Sunday, April 28, 2013

Custom Link Provider for Items outside startItem in Sitecore

In a recent website development using Sitecore, we had to keep pages outside startItem to implement the required the information architecture of the site. Below is an image depicting the page hierarchy.

Sitecore page item outside contentStartItem

The user friendly URL generated for page "Our-Range" was /sitecore/Content/site_name/Website/our-range instead of /our-range.

On troubleshooting it was found that as "Our-Range" item is out side contentStartItem (in this case, "home" item), Sitecore's default linkProvider returned full path for the item. Displaying full item path as URL is not a good practice from SEO and security point of views.

To fix this, Sitecore's out of box LinkProvider (Sitecore.Links.LinkProvider) was extended and the GetItemUrl method was overridden.

namespace Sitecore.Custom.Providers
/// <summary>
/// Class to generate URL for Sitecore items.
/// </summary>
public class LinkProvider : Sitecore.Links.LinkProvider
/// <summary>
/// Returns user friendly URL for given Sitecore item.
/// </summary>
/// <param name="item">The Sitecore item for which URL is needed.</param>
/// <param name="options">The options to be considered when generating URL</param>
/// <returns>User friendly URL for Sitecore item.</returns>
public override string GetItemUrl(Sitecore.Data.Items.Item item, Sitecore.Links.UrlOptions options)
// Get URL from Sitecore out of box link provider.
string originalURL = base.GetItemUrl(item, options);

// Get contentStartItem path for context site.
string contentStartItem = Sitecore.Context.Site.RootPath.ToLower();

// Replace contentStartItem path in originalURL with empty string and return the resultant string.
return originalURL.ToLower().Replace(contentStartItem, String.Empty);

In above code, GetItemUrl method is overridden to adjust the friendly URL for Sitecore items. First, friendly URL for required item is retrieved using default link provider. Then the contentStartItem path is replaced with empty string. Finally the resultant URL is returned.

After the code is build and deployed, below configuration changes have to be make in web.config file of Sitecore instance:

<add patch:instead="*[@name='sitecore' and @type='Sitecore.Links.LinkProvider, Sitecore.Kernel']" name="sitecore" type="Sitecore.Custom.Providers.LinkProvider, Sitecore.Custom" addAspxExtension="false" alwaysIncludeServerUrl="false" encodeNames="true" languageEmbedding="asNeeded" languageLocation="filePath" shortenUrls="true" useDisplayName="true"></add>

After deploying these changes, URLs for items outside startItem did not have full item path.

Full source code for above custom link provider can be found at GitHub.