HomeDev GuideRecipesAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

Localize the user interface

Describes how to localize the user interface in Optimizely Content Management System (CMS).

Localized UI text lets editors and visitors see the interface in their preferred language. The default localization service retrieves translated resource files from a predefined project folder.

The provider looks for XML string resource files in a lang folder under the content root. Add localizations or override system strings by placing files in that folder. Translations in the lang directory override system-defined resources.

By default, the UI language matches the editor's Language Settings > Personal Language selection. For more control, create a custom localization provider. Inherit from LocalizationProvider and register it as described in Configure a custom localization provider.

Register custom localization providers

Register custom localization providers with LocalizationOptions, AddLocalizationProvider, or AddEmbeddedLocalization on IServiceCollection. The following example registers an embedded localization provider for the assembly containing Startup:

services.AddEmbeddedLocalization<Startup>();

After registering the provider, add XML language files such as ContentTypeNames.xml to that location. When using EmbeddedXmlLocalizationProvider, add them as embedded resources instead.

Language files accept any file name and support one or more languages per file. The following structure is required.

One language:

<?xml version="1.0" encoding="utf-8"?>
<languages>
  <language name="English" id="en">
  </language>
</languages>

Two languages:

<?xml version="1.0" encoding="utf-8"?>
<languages>
   <language name="English" id="en">
     ...
   </language>
   <language name="Swedish" id="sv">
      ...
   </language>
</languages>

Add localized text

Localize text shown in the UI for content types by adding translations in a convention-based format. The following code example defines the StandardPage content type with attribute and property texts such as MainContentArea:

[ContentType(Description = "Replace this text with an XML translation")]

public class StandardPage: PageData {
  [Display(
    GroupName = SystemTabNames.Content,
    Name = "Replace this text with an XML translation",
    Description = "Replace this text with an XML translation"
  )]
  public virtual ContentArea MainContentArea {
    get;
    set;
  }
}

For a StandardPage content type with these attributes and properties, the language file structure is as follows:

<language name="en">
  <contenttypes>
    <standardpage>
      <description>A description of the page type</description>
      <properties>
        <maincontentarea>
          <caption>Name text from XML</caption>
          <help>Description text from XML</help>
        </maincontentarea>
      </properties>
    </standardpage>
  </contenttypes>
</language>

Reuse localization for properties between content types

Shared translations reduce duplication across content types that inherit common properties.

Add common translations to an inherited type such as pagedata or icontentdata.

The following content type defines a Name property that inherits from PageData:

public class StandardPage: PageData {
    public virtual string Name {
      get;
      set;
    }
  }

The corresponding language file provides translations for the pagedata base type:

<language id="en" name="English">
  <contenttypes>
    <pagedata>
      <properties>
        <name>
          <caption>Name text from language file</caption>
        </name>
      </properties>
    </pagedata>
  </contenttypes>
</language>

Translations on interface types such as icontentdata apply to all implementing content types:

<language id="en" name="English">
  <contenttypes>
    <icontentdata>
      <properties>
        <disableindexing>
          <caption>Disable indexing</caption>
          <help>Prevents the page from being indexed by search engines</help>
        </disableindexing>
      </properties>
    </icontentdata>
  </contenttypes>
</language>
📘

Note

If base classes are not registered as content types, create a UIDescriptor for the base class to add translations.

Localize headers

Localized group headers let editors see tab labels in their preferred language. The following example localizes tabs used to group properties:

public class StandardPage: PageData {
  [Display(GroupName = SystemTabNames.Content, )]
  public virtual ContentArea MainContentArea {
    get;
    set;
  }
}

public static class SystemTabNames {
  public
  const string Content = "Information";
}

The GroupName on MainContentArea refers to SystemTabNames.Content, which resolves to Information. Add a <groups> element with the group name as the child element:

<language name="en">
  <groups>
    <information>Group name from XML file</information>
  </groups>
</language>