When developing a website in Sitecore version 9.x, we developed multilingual websites and configured four websites like en-us, en-GB,en-au and en. We wanted the item URL made like us,gb,au and en but when we got the item URL from the link provider, we got the URL with the full language code.
So, we tried to overcome this issue by overriding the link provider and updating the GetItemUrl method. Below you can find the code snippet which we used for overriding to get the item URL in a two letter language code.
When you check Sitecore config using URL (https://demosc.dev.local/sitecore/admin/showconfig.aspx) you will get information for linkprovider that use Sitecore default provider. Please refer below image for reference:
For our above issue we updated the below settings and created custom link provider.
We have created PipelineLinkProvider class which we inherited from LinkProvider and overrode GetItemUrl Method. Please refer below code snippet for your reference
public class PipelineLinkProvider : Sitecore.Links.LinkProvider
{
public override String GetItemUrl(Item item, UrlOptions options)
{
if (IsLanguageEmbeddedUrl)
options.LanguageEmbedding = LanguageEmbedding.Always;
ResolveItemUrlPipelineArgs args = new ResolveItemUrlPipelineArgs(item, options);
CorePipeline.Run("resolveItemUrl", args);
if (args.IsResolved && !String.IsNullOrEmpty(args.Url))
return ChangeLanguageUrlIfNeeded(args.Url);
return ChangeLanguageUrlIfNeeded(base.GetItemUrl(item, options));
}
//for multi site, allow per site on/off of sitecore language in url. Default is false
public static bool IsLanguageEmbeddedUrl
{
get
{
if (Sitecore.Context.Site == null)
return false;
if (!string.IsNullOrEmpty(Sitecore.Context.Site.SiteInfo.Properties["languageEmbeddingUrl"]))
return bool.Parse(Sitecore.Context.Site.SiteInfo.Properties["languageEmbeddingUrl"]);
return false; //default
}
}
public string ChangeLanguageUrlIfNeeded(string url)
{
if (IsLanguageEmbeddedUrl && Sitecore.Context.Site.Name.Equals("corporate") && !string.IsNullOrEmpty(url))
{
var trimmedUrl = url.TrimStart('/').ToLower();
foreach (var entry in CorpCustomToScLanguageMapping)
{
if (trimmedUrl.StartsWith(entry.Value + "/", StringComparison.InvariantCultureIgnoreCase) ||
trimmedUrl.Equals(entry.Value, StringComparison.InvariantCultureIgnoreCase))
{
url = url.ReplaceFirst(entry.Value, entry.Key, StringComparison.InvariantCultureIgnoreCase);
break;
}
}
}
return url;
}
private static Dictionary _corpCustomToScLanguageMapping;
public static Dictionary CorpCustomToScLanguageMapping
{
get
{
if (_corpCustomToScLanguageMapping == null)
{
_corpCustomToScLanguageMapping = new Dictionary()
{
{ "au", "en-au"},
{ "uk", "en-gb"},
{ "us", "en-us"},
{ "en", "en"}
};
}
return _corpCustomToScLanguageMapping;
}
}
private static Dictionary _corpScToCustomLanguageMapping;
public static Dictionary CorpScToCustomLanguageMapping
{
get
{
if (_corpScToCustomLanguageMapping == null)
{
_corpScToCustomLanguageMapping = CorpCustomToScLanguageMapping.ToDictionary(x => x.Value, x => x.Key);
}
return _corpScToCustomLanguageMapping;
}
}
}
The above is an example of overriding the link provider. We can also implement multi-site logic to get URL based on your specific requirement.