🌐 Website Implementation
Globalization Code
📖 Docs

Globalization in Code - Optimizely CMS 12

Exam Area: Content Area 3 – Website Implementation & Delivery (25%)
Reference: https://docs.developers.optimizely.com/content-management-system/docs/globalization


1. Language Resources (XML)

<!-- Resources/LanguageFiles/en.xml -->
<?xml version="1.0" encoding="utf-8"?>
<languages>
  <language name="English" id="en">
    <mysite>
      <header>
        <navigation>Navigation</navigation>
        <search>Search</search>
      </header>
      <contenttypes>
        <articlepage>
          <name>Article Page</name>
          <description>A page for articles</description>
          <properties>
            <heading>
              <caption>Heading</caption>
              <help>Enter the heading for this article</help>
            </heading>
            <mainbody>
              <caption>Main Body</caption>
            </mainbody>
          </properties>
        </articlepage>
      </contenttypes>
    </mysite>
  </language>
</languages>
<!-- Resources/LanguageFiles/vi.xml -->
<?xml version="1.0" encoding="utf-8"?>
<languages>
  <language name="Vietnamese" id="vi">
    <mysite>
      <header>
        <navigation>Điều hướng</navigation>
        <search>Tìm kiếm</search>
      </header>
    </mysite>
  </language>
</languages>

2. Localization Service

using EPiServer.Framework.Localization;

public class NavigationService
{
    private readonly LocalizationService _localizationService;

    public NavigationService(LocalizationService localizationService)
    {
        _localizationService = localizationService;
    }

    public string GetNavigationLabel()
    {
        // Key path follows the XML structure
        return _localizationService.GetString("/mysite/header/navigation");
    }

    // With fallback
    public string GetString(string key, string fallback = "")
    {
        return _localizationService.GetString(key, fallback);
    }
}

3. Razor View Localization

@inject EPiServer.Framework.Localization.LocalizationService LocalizationService

<nav>
    <span>@LocalizationService.GetString("/mysite/header/navigation")</span>
</nav>

@* Or use the TranslateTag helper *@
@Html.Translate("/mysite/header/search")

4. Language Settings

LanguageSelector:

// Get content in a specific language
var languageSelector = new LanguageSelector("vi");
var content = _contentLoader.Get<ArticlePage>(contentRef, languageSelector);

// Get in the master language
var masterContent = _contentLoader.Get<ArticlePage>(contentRef, 
    LanguageSelector.MasterLanguage());

// Auto-detect from the request
var autoContent = _contentLoader.Get<ArticlePage>(contentRef, 
    LanguageSelector.AutoDetect());

5. Determining the Current Language

using System.Globalization;
using EPiServer.Globalization;

// Current CMS language
CultureInfo currentCulture = ContentLanguage.PreferredCulture;
string languageId = currentCulture.Name; // "en", "vi", ...

// Thread culture
CultureInfo threadCulture = CultureInfo.CurrentCulture;

// Request culture
CultureInfo requestCulture = CultureInfo.CurrentUICulture;

6. ILanguageBranchRepository

public class LanguageService
{
    private readonly ILanguageBranchRepository _languageBranchRepo;

    public LanguageService(ILanguageBranchRepository languageBranchRepo)
    {
        _languageBranchRepo = languageBranchRepo;
    }

    // Get all enabled languages
    public IEnumerable<LanguageBranch> GetEnabledLanguages()
    {
        return _languageBranchRepo.ListEnabled();
    }

    // Get master language
    public LanguageBranch GetMasterLanguage()
    {
        return _languageBranchRepo.LoadFirstEnabledMasterLanguage();
    }
}

7. Language Fallback in Code

// Configure fallback
[InitializableModule]
public class LanguageFallbackInit : IInitializableModule
{
    public void Initialize(InitializationEngine context)
    {
        // Content fallback
        var languageResolver = context.Locate.Advanced
            .GetInstance<ILanguageSelector>();
    }
}

8. Adding a Custom Language

// Via Admin → Website Languages → Add Language
// Or in code:
public class AddLanguageService
{
    private readonly ILanguageBranchRepository _repo;

    public void AddVietnamese()
    {
        var viBranch = new LanguageBranch(new CultureInfo("vi"));
        viBranch.Enabled = true;
        _repo.Save(viBranch);
    }
}

9. Working with Globalization in Code

// Get all language versions of a content item
var allVersions = _contentRepository.GetLanguageBranches<ArticlePage>(contentRef);

foreach (var version in allVersions)
{
    Console.WriteLine($"Language: {version.Language.Name}, Name: {version.Name}");
}

// Create a new translation
var masterContent = _contentLoader.Get<ArticlePage>(contentRef, LanguageSelector.MasterLanguage());
var newTranslation = _contentRepository.CreateLanguageBranch<ArticlePage>(contentRef, 
    new LanguageSelector("vi"));

var writableTranslation = newTranslation.CreateWritableClone() as ArticlePage;
writableTranslation.Heading = "Tiêu đề bằng tiếng Việt";
_contentRepository.Save(writableTranslation, SaveAction.Publish);

Review Questions

  1. In which folder should XML language files be placed? (Resources/LanguageFiles/ or lang/)
  2. Which service is used to read localized strings? (LocalizationService)
  3. What does LanguageSelector.MasterLanguage() return? (A language selector for the master language)
  4. How do you create a new translation for a page? (_contentRepository.CreateLanguageBranch<T>())
  5. What does ContentLanguage.PreferredCulture indicate? (The current language of the CMS context)