Richard Seal recently wrote a blog post about how to secure data source items and folders under content pages within the content tree. The TL;DR of his post is that any folders and data source items in the content hierarchy under the home page would technically resolve to item URLs, however because they don’t have any presentation set they will generate a Layout Not Found page. The proposed solution was to use a pipeline processor to catch any items that are not pages based on a Resolve to Url checkbox. First, I want to explain an old solution I used to use for this that may now be better solved via the pipeline processor (a great idea!), and secondly I want to propose an improvement to the processor to avoid a checkbox for determining if an item is a page or not.
The Redirect to Parent Page Component
Prior to reading Richard’s blog post I had always solved similar issues with a unique UI component called Redirect to Parent Page. The items in question to use it on would be data source folder items like the “Assets” folder in Richard’s post, item bucket folder items generated by Sitecore, or even manually generated folders under pages (e.g. year, month, and day folders with News Mover before item buckets came out). For any of the above items’ standard values I would add a layout and apply the Redirect to Parent Page component to any placeholder. The Redirect to Parent Page component would check to see if the current item is a page and if not, loop up the hierarchy until it finds a page. E.g.
[csharp]
Item item = Sitecore.Context.Item;
// add additional checks so there’s no infinite loop – e.g. look for the root item
while(String.IsNullOrEmpty(item.Fields[Sitecore.FieldIDs.LayoutField].Value)
{
item = item.Parent;
}
Response.Redirect(LinkManager.GetItemUrl(item));
[/csharp]
So if I have a page such as http://www.mysite.com/news/2015/12/01/some-page and I trim back the URL to http://www.mysite.com/news/2015/12/01/ the site would redirect to the closest parent page which may be the news landing page (http://www.mysite.com/news/).
Not only does this work for folders in the page hierarchy, but it can also be applied to data source content items in a folder under a page like in the Assets folder mentioned in Richard’s post.
Improving the None Page Pipeline Processor
Now taking the processor approach to this, it solves the problem of needing to assign a layout and the UI component to the standard values of any non-page items. That definitely saves time. But the next challenge is that pesky little Resolve to Url checkbox. Rather than rely on a checkbox to determine this and using standard values to set it, why not just see if the item is a page? Using the same code I have above, its possible to update the processor to check if the item has any presentation set and if not, redirect to the closest parent page. That said, the best idea is not to actually redirect, because in the end redirecting is telling the browser and search engines that this was a page and is temporarily or permanently being redirected. Instead, the best solution is to send a 404 status code to the browser. This can be achieved via the following simple code split across two processors:
[csharp]
// in the same processor in Richard’s post add a custom 404 flag to the current request
HttpContext.Current.Items["404"] = true;
[/csharp]
Then in the httpRequestProcessed
pipeline, patch in the following code to respond to the request and set the 404 status code if need be:
[csharp]
var status = HttpContext.Current.Items["404"];
if (status == null || !(bool)status)
return;
HttpContext.Current.Response.StatusCode = 404;
HttpContext.Current.Response.TrySkipIisCustomErrors = true;
[/csharp]
Hi Mark,
Apologies for an off-topic comment but I’m looking for a reverse solution to the above (I think). I’m new to Sitecore as a user, am not a developer and am looking for a way to structure public pages in Content Editor so they are logically grouped in a parent/children hierarchy that is reflected in the URLs. This largely for ease of management by content editors. e.g.
Section 1 intro page
– Content page 1
– Content page 2
Section 2 intro page
– etc…
My old-school, non-Sitecore brain tells me I should be able to just add a new folder and a default document but Sitecore folders, while being included in the URL, result in a 404 if the user were to edit the URL back from the content page URL.
Is there any way to nest pages in this fashion? Hope you can help.
Regards
James