Add a Custom Language Definition to Sitecore

By default, Sitecore and Windows come pre-loaded with a standard set of cultures (culture being the combination of ISO region and language). For example, some standard cultures include "en" (global English), "fr-FR" (French, France), "en-GB" (English, Great Britain), "es-ES" (Spanish, Spain), etc.

But what if you have a business requirement to add a new custom culture, such as "en-AR" (English, Argentina), that is NOT included by default? In that case you'll need to add a new custom culture to Sitecore and your Windows servers. This post will guide you through the process.

STEP 1 - Construct the custom culture code

The custom culture code is made up of two parts, the two-letter ISO 639-1 language code and the two-letter ISO Alpha 2 country code, in the following format: <language code>-<country code>.

You can look up language codes here: https://www.loc.gov/standards/iso639-2/php/code_list.php

You can look up country codes here: http://www.nationsonline.org/oneworld/country_code_list.htm

So for example, for our English Argentina example we will end up with a custom code "en-AR".

STEP 2 - Determine if you need a custom culture

Different out-of-the-box cultures are included in Windows depending on the o/s version and .NET Framework version. So the first thing you should do is verify the cultures available on your Windows servers. To do this, you can use a simple tool like this one.

1. Create a new admin page named "InstalledCultures.aspx" in your Sitecore solution in the following location: "<website>\sitecore\admin".

Here is the markup:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="InstalledCultures.aspx.cs" Inherits="Integryx.InstalledCultures" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Literal ID="lit1" runat="server"></asp:Literal>
    </div>
    </form>
</body>
</html>

Here is the code behind:

using Sitecore.sitecore.admin;
using System;
using System.Globalization;
using System.Text;

namespace Integryx
{
    public partial class InstalledCultures : AdminPage
    {
        protected override void OnInit(EventArgs e)
        {
            CheckSecurity(true);
            base.OnInit(e);
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            var sb = new StringBuilder();
            sb.Append("<table><tr><td>CULTURE</td><td>ISO 2</td><td>ISO 3</td><td>WIN</td><td>DISPLAY NAME</td><td>ENGLISH NAME</td></tr>");
            foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))
            {
                sb.Append("<tr>");
                sb.Append("<td>" + ci.Name + "</td>");
                sb.Append("<td>" + ci.TwoLetterISOLanguageName + "</td>");
                sb.Append("<td>" + ci.ThreeLetterISOLanguageName + "</td>");
                sb.Append("<td>" + ci.ThreeLetterWindowsLanguageName + "</td>");
                sb.Append("<td>" + ci.DisplayName + "</td>");
                sb.Append("<td>" + ci.EnglishName + "</td>");
                sb.Append("</tr>");
            }
            sb.Append("</table>");

            lit1.Text = sb.ToString();
        }
    }
}

2. Publish this page to your Sitecore CM and CD servers, and navigate a browser to the page.

3. Log in using admin credentials.

4. You will be presented with a list of the installed cultures on the Windows server.

5. Search the list to see if your new culture code already exists. If it exists, you can skip the next step. If it doesn't, you'll need to install it using the next step.

STEP 3 - Register the custom culture in .NET Framework

1. Create a new console application, and add the following code:

using System;
using System.Collections.Generic;
using System.Globalization;

namespace Integryx.RegisterCultures
{
    class Program
    {

        static void Main(string[] args)
        {
            List<CustomCulture> cultures = new List<CustomCulture>();
            // Add your new culture definitions here.
            cultures.Add(new CustomCulture("en-US", "US", "en-AR", "en-AR", "English (Argentina)", "English (Argentina)", "Argentina", "Argentina"));
            cultures.Add(new CustomCulture("en-US", "US", "en-BM", "en-BM", "English (Bermuda)", "English (Bermuda)", "Bermuda", "Bermuda"));
            cultures.Add(new CustomCulture("en-US", "US", "en-CL", "en-CL", "English (Chile)", "English (Chile)", "Chile", "Chile"));
            // ...etc.

            foreach (var culture in cultures)
            {
                CultureAndRegionInfoBuilder cib = null;
                try
                {
                    cib = new CultureAndRegionInfoBuilder(culture.CultureName, CultureAndRegionModifiers.None);
                    cib.LoadDataFromCultureInfo(new CultureInfo(culture.BaseFrom));
                    cib.LoadDataFromRegionInfo(new RegionInfo(culture.BaseFromReg));
                    cib.CultureEnglishName = culture.EnglishName;
                    cib.CultureNativeName = culture.NativeName;
                    cib.IetfLanguageTag = culture.CultureLangTag;
                    cib.RegionEnglishName = culture.RegEnglishName;
                    cib.RegionNativeName = culture.RegNativeName;
                    cib.Register();
                    System.Console.WriteLine(cib.CultureName + " => created");
                }
                catch (Exception e)
                {
                    System.Console.WriteLine(e.Message);
                }
            }

            System.Console.WriteLine("Press any key to exit");
            System.Console.ReadKey();
        }

        class CustomCulture
        {
            public string BaseFrom { get; set; }
            public string BaseFromReg { get; set; }
            public string CultureName { get; set; }
            public string CultureLangTag { get; set; }
            public string EnglishName { get; set; }
            public string NativeName { get; set; }
            public string RegEnglishName { get; set; }
            public string RegNativeName { get; set; }

            public CustomCulture(string baseFrom, string baseFromReg, string cultureName, string cultureLangTag, string englishName, string nativeName, string regEnglishName, string regNativeName)
            {
                this.BaseFrom = baseFrom;
                this.BaseFromReg = baseFromReg;
                this.CultureName = cultureName;
                this.CultureLangTag = cultureLangTag;
                this.EnglishName = englishName;
                this.NativeName = nativeName;
                this.RegEnglishName = regEnglishName;
                this.RegNativeName = regNativeName;
            }

        }

    }
}

2. Modify lines 14-16 as needed with the information for your new custom culture. For example, to add the en-AR culture you could add this line:

cultures.Add(new CustomCulture("en-US", "US", "en-AR", "en-AR", "English (Argentina)", "English (Argentina)", "Argentina", "Argentina"));

3. Compile the tool. Grab the resulting exe file, and run it on each CM and CD server in your Sitecore topology.

4. Congratulations! You have registered your new culture in Windows.

STEP 4 - Register the custom culture in Sitecore

1. Sitecore comes with flag icons for most countries, but if you need a new one go ahead and add it to Sitecore.

2. Edit the App_Config/Include/LanguageDefinitions.config file to add a new language definition. For our "en-AR" example we would add this line to the file:

<language id="en" region="AR" codepage="65001" encoding="utf-8" charset="iso-8859-1" icon="flags/16x16/flag_Argentina.PNG" />

3. Open Sitecore control panel, navigate to Globalization -> Add New language. A dialog will pop up.

4. Find your newly-created culture in the drop-down list, and select it. Sitecore will populate the required fields as needed.

 

5. Click "Next" through the wizard to complete it.

6. Congrats - you are now ready to use your new custom culture! It will appear in the Language drop-downs in Content Editor and Experience Editor, and you may start creating new content in that culture.

I hope this is useful to developers out there in Sitecore land. Please let me know of any improvements that could be made to this blog post, or the code examples.

~David

Comments (2) -

  • Is there a way to do this in Azure PaaS?
  • Great post by the way will try it.

Add comment

Loading