all things Sitecore related

Using wildcards and displaynames in urls

By on May 8, 2012 in Sitecore, Tips and Tricks with 8 Comments

In Sitecore we know wildcards, which will give you the possibility to create dynamic urls. Basically we can use wildcards to pass variables by using the URL instead of querystring parameters. If you would like to know more on how wildcards work and what they can do for you I recommend this blogpost from Alistair Deneys.

Using wildcards and displaynames in urls Wildcard node

So let’s assume we have the following case. We have a multilingual website with the Dutch and English language. On this website we have a catalog section which shows all our products. All the products are stored outside the section and are being loaded with wildcards. Based upon the name of the page that’s requested we will retrieve the correct item from the product repository and use it in the wildcard item. This is basically how wildcards work, nothing new here.

But since we have an multilingual site we would like to use the displayname in the url, so we can create urls which could be in Dutch or English. Because we use the Sitecore LinkManager we can easily configure this in the web.config. We can find the linkmanager configuration in the /configuration/sitecore/linkmanager node inside the web.config. The default linkprovider has an option called “useDisplayName”. When we set this option on true we can create urls which use the displayname, and with that are multilingual.

Using wildcards and displaynames in urls Linkmanager 300x115

With our example site we can now have two urls pointing to the same content item.

Using wildcards and displaynames in urls Link displaynames to content item

So far so good. We can browse the site using the displayname setting in the linkmanager. But what happens when we are going to request a wildcard item. If we are requesting the wildcard item in the default language (in this case English) everything goes well. But when we are going to request the item in another language (Dutch) we are getting the “Item Not Found” page.

This is happening because the ItemResolver processor cannot get the parent item by using the displayname. In the processor there is a method called GetSubItem. This method will try to get the requested item by using the request path.


private Item GetSubItem(string path, Item root)
{
	Item child = root;
	foreach (string str in path.Split(new char[] { '/' }))
	{
		if (str.Length != 0)
		{
			child = this.GetChild(child, str);
			if (child == null)
			{
				return null;
			}
		}
	}
	return child;
}

But the path used is the path which has been constructed by the parsing the request. Which means that we have a path (/sitecore/content/Home/Catalogus/test) which cannot be resolved, because of the use of the displayname. So we need to add some code to the GetSubItems method. We will get the item by combining the parent’s path and the item name. We can retrieve it from the context database and return it.


private Item GetSubItem(string path, Item root)
{
    Item childItem = root;
    Item parentItem = childItem;

    foreach (string itemName in path.Split(new char[] { '/' }))
    {
        if (itemName.Length != 0)
        {
            childItem = this.GetChild(childItem, itemName);
            if (childItem == null)
            {
                string itemPath = string.Format("{0}/{1}", parentItem.Paths.FullPath, itemName);
                using (new SecurityDisabler())
                {
                    childItem = Context.Database.Items[itemPath];
                }
                return childItem;
            }
        }
    }
    return null;
}

Of course you would like to add some safety checking to see if the user has the appropriate access rights. You could do that by calling the AuthorizationManager.


if (AuthorizationManager.IsAllowed(item, AccessRight.ItemRead, Context.User))
{
    return item;
}

Tags: , ,

About the Author

About the Author: Mark van Aalst is a Solution Architect for Sitecore Netherlands. Prior to working for Sitecore he has worked with the Sitecore CMS for more than 6 years and was a Sitecore MVP. Mark is also the initiator of the populair Sitecore Shared Source WeBlog module which he develops together with Nick Wesselman and Alistair Deneys. You can follow Mark on Twitter @markvanaalst or Google+ .

Subscribe

If you enjoyed this article, subscribe now to receive more just like it.

There Are 8 Brilliant Comments

Trackback URL | Comments RSS Feed

  1. Mark, Can you please provide me the steps to implement this feature? We are also facing the same problem. nehem00@gmail.com

  2. Mat Light says:

    Hey Mark,

    thanx for the article, its a beauty ;-)
    A little adaption and the resolver is running!

    Greetz
    Mat

    private Item GetSubItem(string path, Item root)
    {
    Item childItem = root;
    Item parentItem = childItem;

    foreach (string itemName in path.Split(new char[] { ‘/’ }))
    {
    if (itemName.Length == 0) continue;
    childItem = this.GetChild(childItem, itemName);
    if (childItem == null)
    {
    string itemPath = string.Format(“{0}/{1}”, parentItem.Paths.FullPath, itemName);
    using (new SecurityDisabler())
    {
    childItem = Context.Database.Items[itemPath];
    }
    return childItem;
    }
    parentItem = childItem;
    }
    return childItem;
    }

Post a Comment

Your email address will not be published. Required fields are marked *

Top