In a current project we have developed a solution with pages that are compiled from several different Sitecore items. This might not seem like a strange thing since allmost all pages served by any CMS is a compilation of items one way or another.
The thing here is that we want all pages to be as modular as possible, giving the editors an easy way to add various functionality over the different pages. Instead of creating a big set of different templates serving every need we instead use a structure with one item that represents the actual page and subitems that add modular content to that page. Content can be shown as one single scrollable page or separated in tabs using JQuery. I hope to be able to elaborate on this in a future post.
Anyway, no matter if the content should be shown in one page, in tabs or in any other way we had to be able to link to the different subitems directly. As I prefer standard HTML using anchors seemed the way to go, anchors works fine in a plain scrollable page but it could also be used in JQuery tabs.
Standard Sitecore behaviour for links would be that if I would link to a subitem of a page the URL for that link would read “http://hostname/page/subitemfolder/subitem”, since the subitem has no layout Sitecore would return an error page. The link should instead read “http://hostname/page#subitem”, Since we are talking Sitecore, this if fairly easy to accomplish.
We override the linkManager section in web.config (preferably by using an include file).
<!--<add name="sitecore" type="Sitecore.Links.LinkProvider, Sitecore.Kernel" addAspxExtension="true" alwaysIncludeServerUrl="false" encodeNames="true" languageEmbedding="asNeeded" languageLocation="filePath" shortenUrls="true" useDisplayName="false"/>-->
<add name="sitecore" type="Sitecore64.LinkProvider, Sitecore64" addAspxExtension="true" alwaysIncludeServerUrl="false" encodeNames="true" languageEmbedding="asNeeded" languageLocation="filePath" shortenUrls="true" useDisplayName="false"/>
Then we override the LinkProvider as below.
public class LinkProvider : Sitecore.Links.LinkProvider
public override string GetItemUrl(Sitecore.Data.Items.Item item, Sitecore.Links.UrlOptions options)
Template template = TemplateManager.GetTemplate(item);
string url = base.GetItemUrl(item.Parent.Parent, options) + "#" + item.DisplayName;
return base.GetItemUrl(item, options);
One thing to note here is that all subitems use a common base template to define that they are actual subitems and should be addressed using a hashtag and pointing to a grandparent.
Off course you would need to add logic to verify that parent elements exists and are based on the correct template and so on.