Identifying a global Facebook page from API - facebook-graph-api

Facebook recently launched Global pages for brands:
http://www.facebook-studio.com/news/item/announcing-a-new-pages-structure-for-global-brands
These pages have regional aliases. For example, http://www.facebook.com/asos.france points to the ASOS global page, but only shows French content.
My questions is: is it possible to identify via Facebook's API, whether a given page URL is
A regional version of a global page, or
A standard page

Querying this with the Graph API will get you there:
/PAGE_NAME_OR_ID?fields=global_brand_children.username,global_brand_parent_page
Three examples to replace PAGE_NAME_OR_ID with in the above query:
asos.france returns a JSON object with global_brand_parent_page populated. It is a regional alias. The top-level global page is given.
asos returns a JSON object with an array of global_brand_children. It is the top level global page. The children show all the regional aliases.
cocacola returns only an id. This is a stand-alone page.

As the Facebook Graph API documentation states
You need to be the admin of root page for child pages in order to read the global_brand_children edge for a page.
However, I think there is another way to answer this question, if you don't have that level of access. If you use this query:
GET /v2.5/{id}?fields=global_brand_root_id,parent_page
If either of those fields are present/non-empty then you can safely deduce that the page in question has a parent, either a Global Page Root or a Locations Parent.
Now, understanding the distinctions between Global Pages and Locations (aka Parent-Child) is worthy of further investigation but from what I understand–so far–they are mutually exclusive. Either a page is part of Global Pages or Locations, but not both.
From what I have read, a Global Page is reserved for large brands which need country/region/language-specific pages, like Coca-cola (mentioned above), while Locations would be for more local properties like hotels, retail stores, etc. Clickz had a pretty good blog post on this, if you need to understand the distinction in more detail.

Related

Hiding new pages from being created in Wagtail

I have tried searching the official documentation and related message boards for this however I have been unable to find anything related.
Some of the templates for pages in my website are only to be used once - e.g. homepage.
Is there a way in Wagtail to hide or disallow users from selecting that template/Page model when creating a new page?
You can limit the places it is possible to create a page type, by editing YourPageModel.parent_page_types, see http://docs.wagtail.io/en/v1.10.1/reference/pages/model_reference.html#wagtail.wagtailcore.models.Page.parent_page_types. Similarly there is a subpage_types setting, so for instance you can enforce that NewsIndexPage can only be created as a direct child of HomePage, and can only contain NewsItemPage instances. Combining this with user permissions should be enough for home pages or page types at a high enough place in the tree.
If you absolutely must enforce that only one of a certain page type exists, it is possible to override the classmethod clean_parent_page_models, to return [] if an instance of this class already exists. This approach is a hack, however, and may be broken by future versions of Wagtail.
Update, January 2021:
The hack above isn't exactly broken, but it certainly wasn't ideal, and since version 2.4 Wagtail has had the max_count Page attribute (and max_count_per_parent in 2.5).
Documentation: https://docs.wagtail.io/en/stable/reference/pages/model_reference.html#wagtail.core.models.Page.max_count
#JaredOzzy's answer is correct, and has more details on these methods.
Anybody coming here looking for something similar, Wagtail has now added 2 nifty properties that we can use to limit pages from being created more than a specific amount of times.
http://docs.wagtail.io/en/v2.5.1/reference/pages/model_reference.html#wagtail.core.models.Page.max_count
max_count
Controls the maximum number of pages of this type that can be created through the Wagtail administration interface. This is useful when needing “allow at most 3 of these pages to exist”, or for singleton pages.
and
max_count_per_parent.
Controls the maximum number of pages of this type that can be created under any one parent page.

Master/Detail Dilema: Wildcard items vs Sitecore Pipeline for Virtual Items or any better idea?

I used to implement listing/detail scenarios using wildcard items, meaning that, for the sake of URL, I create a regular item to display the list and then under that node, I create a wildcard item to represent all possible detail pages, like:
/news/*
(i generate a friendly name by code to replace wildcard and produce the full URL such as: mywebsite.com/news/the-meeting-press-release)
Then I create a folder or a bucket of content items somewhere else as my repository. Then I assign same datasource to listing node and wildcard node to give them same repository of content items.
Main reason I want to do this is to use datasources and make navigational nodes (which generate actual pages and URLs) to be separate from Content folder structure. In other words, separation of concerns: navigational items as presentation nodes and content items as my data repository.
This is an easy way to work around master/detail requirements but I always feel guilty about this, it feels like this technique breaks integrity (sitecore links table on database) and design pattern in Sitecore back-end.
For example when I look at Analytics, I get * as name of items, clearly the it feels like aliens to back-end system.
I know this is not a new topic. I have seen threads like this or ideas like Sitecore Pipeline Processor for Virtual Items to implement such requirements.
Is there any best practice about this? Have anyone good example of what is most sitecore-friendly way to implement such pipeline processor? How do you address this issue with wildcards on Analytics?
I'm going to go a different way to Martin here. I have successfully used Wildcards many times for the exact purpose you are suggesting (For an example have a look at http://www.atpworldtour.com/news - all news articles are items in a bucket with a wildcard to resolve the url).
There are 2 options to enabling the page editor.
The news article item becomes the page. In this way, you need a new processor in the httpRequestBegin pipeline that resolves the url to the item and then sets Sitecore.Context.Item to the current item. IIRC you do this by setting one of the pipeline argument properties. This will work fine in the page editor as the context item - the one being edited - is the news article. And then other renderings on the page can just use data sources as needed.
The news article resolves to a Datasource. I have also tried this method. To do this, you need a custom Datasource resolver. I sill used a processor in the httpRequestBegin pipeline so that I didn't have to resolve the Url multiple times for each rendering that needed the datasource. But then in the RenderRendering pipeline I had a processor that detected if I wanted a wildcard Datasource and used the item that had been resolved in the httpRequestBegin processor.
There are pros & cons for each method.
Option 1 is nice and simple. It means that you could use a single wildcard to resolve different "types" of page item as the presentation is on the page item and not the wildcard item, also each item can have its own custom presentation, so Datasources set in the page editor would be unique to an article. That is also a disadvantage in someways. A/B testing becomes more difficult with main article text etc... You are limited to testing article versions.
Option 2 is more flexible in the testing area - you can easily test/personalize parts of the article by changing the Datasource. But you are more limited as the presentation must be set on the wildcard. So renderings that are not part of the main article will have the same content/settings across all news articles.
I was previously in the same boat as you are. The are few issues with wildcard items, like resolving datasources or disability to run a page in Page(Experience) Editor or nested wildcards. Regardless of that, I have used wildcard few times and they do their job.
I've managed to resolve datasources properly, based on URL (see blog post: Automatically resolving correct Datasources for wildcard items based on URL), still did not sort the rest others.
Update: Richard suggests the way of implementing Page Editor below, you may find this helpful
Thus, my answer would be:
I would recommend you to keep classical approach of having a page item for each news item, rather than using wildcards. Content authors would use habitual approach (and page editor) rather that editing datasources somewhere on the content tree in Content Editor. If you configure that properly with templates and standard values - there would minimal hassle to create new news article.
In case if you worry about potential raise of number of news articles - use Buckets along with it (or suggest manual strategy to group them into folders).

Where to create the Articles in Sitecore?

I'm trying to understand the best approach to create article items in my sitecore 7.2 project.
Basically I'm considering 2 options:
1 - Create an article as a page;
2 - Create an article as a Site Data Item.
1 - Create article pages under a given page (i.e. My Articles). This way each article would have a specific URL out of the box, easier to understand in Content Authors' point of view;
2 - Have a specific folder (i.e. Article Folder) under Site Data. This way we don't need to have a page for each article - I was thinking to have a single Article page that would render the article fields. However this would require more work in terms of URLs, navigation, etc.
Is there any other ideas? Am I missing something? I was also having a look at Buckets...
Thank you
I'm going to disagree with Marek and recommend you opt for option 2.
Storing your articles in folder under a Data node allows those items to be datasourced. This is the principle Sitecore was built on. You can then surface those articles in a number of interesting ways via Widgets such as Promo Panels, prompting the user to click through to read about the article without duplicating its data and requiring Content Editors to manage data multiple times.
It even supports multiple sites, so the Articles can be used in other sites you may add to your Sitecore instance in the future.
As you state it will require extra work in terms of Urls and Navigation but it can be achieved via Sitecore's Wild Card Item and you an even use a great open sourced Module from Sitecore's Marketplace to complete 90% of the work for you. See links below for more information.
You can still implement Marek's point of applying Presentation Details once on the Standard Values of the Wild Cart Item you create. If you are using Sitecore 7 and above you can store all your articles in a Bucket so if you have lots of articles they are stored and searchable in a meaningful way.
http://www.sitecore.net/learn/blogs/technical-blogs/getting-to-know-sitecore/posts/2011/09/wildcards-and-data-driven-urls.aspx
https://marketplace.sitecore.net/en/Modules/Wildcard_module.aspx
In a standard one instance setup the easiest implementation is to create articles as pages.
In Sitecore you want to limit the items in a folder to 100 or less which is best practice to keep the content editors experience optimal.
This then leads you needing a folder structure and a couple options:
Manually maintain a folder structure for your articles. For example articles/year/month/day. This gives your editors the most control over the folder structure and allow them to navigate the articles in a more traditional way via a visible folder structure.
Use a bucket which automatically generates the folder structure and hides this complexity from the content editor. This takes the manual folder creation and maintenance away from the content editor and are automatically generated based on the configuration you set out for your bucket. The folders wont be visible to the content editor so they will be forced to search in the bucket for any articles rather then navigate the folders.
Use the shared source News mover module (https://marketplace.sitecore.net/en/Modules/News_mover.aspx). This takes a different approach to the above. It works via a traditional folder structure however it generates folders and moves the item on save based on the date field in the article. So the news mover handles the generation of folders however you will still need to check your not exceeding 100 items per folder again for performance when opening folders with large amounts of items.
With all solutions you must still consider the URLs for your articles as they will include the folder structure by default. This is not always acceptable. I prefer to remove the folder structure from the URL. For this you need to create a custom linkProvider and a custom HttpRequestProcessor. Firstly the linkprovider allows you to ensure the new URL is always created and displayed in your site as you want. Next the HttpRequestProcessor ensures that when navigating to the shortened URL Sitecore recognises it as a valid URL and presents the correct page.
By excluding the folder structure from the URL it also adds the additional benefit that the URL is not dependent on the structure. This means editors can change that folder structure and not need to create redirect items to ensure SEO rankings or users bookmarks are not lost.
The cleaner data model is to use the wildcard approach for the URLs and centralize the storage of articles data in a bucket of datasources. This will give you optimum performance and reuse of the data.
However, this isn't how an author thinks about their website. When they use the system, they tend to navigate to the area where they would view articles and try to create a new one there. Authors tend to think in 'pages', so try to hide whatever data model you are using from them and give them the ability to edit the page with Experience Editor.
Some developers try to optimize too far and forget that the authoring experience is likely the most important piece of the delivered solution. The author doesn't care how efficiently you stored the data, only that they can edit it easily and publish efficiently. Whatever model supports that for your author base is how you should implement it.
My recommendation is a page-based approach where the author creates the URL structure with folders and items, something they understand. Then, if you really need to, you can have the primary article data be a datasource-driven component on the page. The user gets to use all the tools they are familiar with (Experience Editor,preview navigation) but you can still store the raw data in a centralized folder. You could then theoretically swap out the article data using DMS rules, or hide information based on authentication or membership status.
Go with approach 1: article is a page.
Define all your presentation details on Article Page template __Standard Values. All new articles will get them. And you can change some of the presentation details for your chosen articles if you want.
If you know that you'll have lot of articles, think about year/month/day folder structure, e.g. articles/2015/06/12.
Approach 2 doesn't give you anything - you still need to have an item for every article. And as you wrote, it would require additional coding which is not required.

What fields/properties can be queried from Facebook Graph API on a Place object?

I'm doing a query of this form:
https://graph.facebook.com/search?q=Beshoff&fields=likes,checkins,products,name,talking_about_count,description,category&type=place&center=37.327453,-121.813102&distance=400
I am interested in finding out the exhaustive list of fields that can be selected for a Place object.
In particular, on the facebook page for a specific place, there are often multiple categories listed which I have been unable to figure out if it's possible to retrieve using the Graph API.
e.g. On https://www.facebook.com/BeshoffInfiniti, there is an entry "Car Dealership" but the graph api call above returns "Local business".
If you leave out the "fields" attribute in your query you will get all the fields. The number of fields depends on the object type (for example owned pages vs. wiki pages)
Don't just look at the Graph API. Take a look at FQL. There are different fields available in FQL vs. the API. And yes, using the distance function you can look for places in an area.
Graph API != FQL
One thing to try is the Facebook Open Graph schema entry for Page and Place.
You'll find all the additional fields for Pages. You can think of places as a subclass of pages.
If you're curious about the types of page that might be returned, try having a look through the create a page flow.

Is it Possible to Filter Graph Feed using Location?

We have a worldwide brand page that posts brand messages and filtered by country, for example: "This is visible in the US" (visible to United States), and "This is visible to Russia" (only visible to Russia).
Main Question: Is it possible to retrieve posts on the page wall filtered by country or other location parameters? For example: https://graph.facebook.com/[userID]/feed?access_token=[accessToken]&locale=en_US
Side Question: Currently when using the URL above (without &locale...) returns only the posts available worldwide, and all targeted posts are not returned. This could potentially be due to the access token being used as I am able to return info for page feeds (that I own) for all locales using a different access token. Is there a correlation between application tokens and locales that are returned?
Forget about it - it's impossible. They never thought about providing us any interface to this.
What you must do is:
Download the entire graph object (awesome especially on mobile),
Remember to download all pages (since facebook is paging long responses),
Merge and filter them on your side (or in client's browser|phone),
Voilà you're good to go ;) .
PS. I know you asked this looong time ago, but it's still one of the first Google results for related queries, so I'm writing here so others can quickly find out. Cheers!