Multilingual URL Sitecore

Sitecore supports different language versions. It will be very easy to have a hindi, chinese, french or dutch version of an item in Sitecore. But how exciting to have a url to be multilingual.!!

We can have it with a very simple configuration modification…

In a linkManager section of a web.config file change the value useDisplayName to true in  sitecore providers setting. Keep the other settings as it is. Your code may look like following:

<linkManager defaultProvider=”sitecore”>
<providers>
<clear />
<add name=”sitecore” type=”Sitecore.Links.LinkProvider, Sitecore.Kernel” addAspxExtension=”true” alwaysIncludeServerUrl=”false” encodeNames=”true” languageEmbedding=”always” languageLocation=”filePath” shortenUrls=”true” useDisplayName=”true” />
</providers>
</linkManager>

This will show the displayname of an item in its url. Each item has display name property in its Standard fields. You must have item’s name/title in its DisplayName field for every language version to display url as multi-lingual.

—————————————————————————————————————————

To avoid manual update of DispalyName you can write handler on item:save event in web.config file:

<event name="item:saved">
   .
   .
   .
   .
   <handler type="My.Logic.UpdateDisplayName, My.Logic" method="UpdateItemDisplayName"></handler>
   </event>

Now, we need to define a class UpdateDisplayName having UpdateItemDisplayName method. Your class and this methods will look like following:


public class UpdateDisplayName
{
/// <summary>
/// Change the display name of an item as per its Page Heading
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
public void UpdateItemDisplayName(object sender, EventArgs args)
{
Assert.ArgumentNotNull(sender, "sender");
Assert.ArgumentNotNull(args, "args");
Item item = Event.ExtractParameter(args, 0) as Item;
if (item != null)
{
Database database = Factory.GetDatabase(new ItemUri(item).DatabaseName);
this.ChangeDisplayName(database, item, item.Language);

}
}

protected void ChangeDisplayName(Database database, Item item, Sitecore.Globalization.Language lang)
{
Item langitem = database.GetItem(item.ID, lang);
if (langitem != null)
{
if (langitem.Fields[“Title”] != null)
{
String pageHeading = langitem.Fields[“Title”].Value;
if (!String.IsNullOrEmpty(pageHeading))
{
using (new Sitecore.SecurityModel.SecurityDisabler())
{
try
{
langitem.Editing.BeginEdit();
string nm = pageHeading.Trim().Replace(” “, “-“);
langitem.Appearance.DisplayName = nm.Replace(“&”, “-and-“).Replace(” “, “-“).Replace(“–“, “-“).Replace(“–“, “-“).Replace(“?”, “”).Replace(“,”, “”).Replace(“/”, “”).Replace(“\\”, “”).Replace(“‘”, “”).Replace(“(“, “-“).Replace(“)”, “-“).Replace(“!”, “”).Replace(“;”, “”).Replace(“+”, “”).Replace(“~”, “-“).Replace(“@”, “-“).Replace(“$”, “-“).Replace(“:”, “-“).Replace(“%”, “-“).Replace(“\””, “”).Replace(“‘”, “”).Replace(““”, “”).Replace(“””, “”);
}
catch (Exception ex)
{
Log.Error(ex.Message, ex);
}
finally
{
langitem.Editing.EndEdit();
}
}
}
}
}
}
}

So whenever you will save the item, the text of its Title field (which needs to be created manually) will be copied it to the DisplayName field…

But what about already created items? Do we need to write manually?

The answer is “No”. Following is a code, which you need to execute one time to have a text in DisplayName field of an item. Here, we have a list of templates id on which we will update the display name of its items. You can create a button and write following code on its button click.


protected void btn_submit_onClick(object sender, EventArgs e)
{
String includedtemplates = "{templateid1},{templateid2},{templateid3}" ;

Item Home = Helper.GetHomeItem();
foreach(Item itm in Home.Axes.GetDescendants())
{
if (includedtemplates.Contains(itm.TemplateID.ToString()))
{
foreach (Sitecore.Globalization.Language lng in itm.Languages)
{
ChangeDisplayName(itm, lng);
//one label lblLog, which lists the items whose DisplayName is changed.
lblLog.Text += itm.Name + “:” + lng.Name + “:” + itm.DisplayName + “:Done <br/>”;
}
ChangeDisplayName(itm, LanguageManager.DefaultLanguage);
}
}
}

public void ChangeDisplayName(Item itm,Sitecore.Globalization.Language lng)
{
Item langitem = Sitecore.Context.Database.GetItem(itm.ID, lng);
String pageHeading = langitem.Fields[“Title”].Value;
if (!String.IsNullOrEmpty(pageHeading))
{
using (new Sitecore.SecurityModel.SecurityDisabler())
{
try
{
langitem.Editing.BeginEdit();
string nm = pageHeading.Trim();
if (nm.Contains(““”))
{
if (nm.Contains(“\””))
{
nm.Replace(“\””, “”);
}
}
langitem.Appearance.DisplayName = nm.Replace(” & “, “-and-“).Replace(“&”, “-and-“).Replace(” “, “-“).Replace(“–“, “-“).Replace(“–“, “-“).Replace(“?”, “”).Replace(“,”, “”).Replace(“/”, “”).Replace(“\\”, “”).Replace(“‘”, “”).Replace(“(“, “-“).Replace(“)”, “-“).Replace(“!”, “”).Replace(“;”, “”).Replace(“+”, “”).Replace(“~”, “-“).Replace(“@”, “-“).Replace(“$”, “-“).Replace(“:”, “-“).Replace(“%”, “-“).Replace(“‘”, “”).Replace(“\””, “”).Replace(““”, “”).Replace(“””, “”);
}
catch (Exception ex)
{
}
finally
{
langitem.Editing.EndEdit();
}
}
}
}

That’s it. Check your existing items. It will have a text of their Title field in its DisplayName field.

—————————————————————

Yes.. Finally, we have a chinese url for a china version, french url for a french version of an item of a Sitecore website.

Happy Coding 🙂