HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideLegal TermsGitHubNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

Configure a custom localization provider

Describes how to configure the initialization of localization providers used by the default LocalizationService in Optimizely Content Management System (CMS).

You have two choices for configuring localization providers.

  • Configure localization in the <episerver.framework> section of your web.config. Here, you can control the behavior of providers registered on your site and disable built-in providers.
  • Register a provider in the localization service through code during website initialization. This choice lets you place language documents in a location other than the default lang folder.
    The following sections show how to achieve this. You might be required to grant access to the folder to the IIS application pool.

📘

Note

A large number of providers increases the time needed to find strings. So, for best performance, support only a few providers.

Use the configuration option

When you add a provider that reads XML language documents through configuration, you specify a path to a physical folder. Optimizely Content Management System (CMS) does not support specifying a path to a virtual path provider (VPP). For details about the attributes available with the <localization> element, see the EPiServer.Framework.Configuration.LocalizationElement class.

The following example configuration demonstrates this option. Set the addDefaultProviders attribute to false to ignore the lang folder when initializing the site. No language documents are included.

<episerver.framework>
  ...
  <localization fallbackBehavior="FallbackCulture, MissingMessage, Echo" fallbackCulture="en">
    <providers>
      <add physicalPath="c:\temp\resourceFolder"
           name="customResources"
           type="EPiServer.Framework.Localization.XmlResources.FileXmlLocalizationProvider" />
    </providers>
  </localization>
  ...
</episerver.framework>

Use the code-only option

Register localization providers during site initialization. The preferred way to do this is to implement the IInitializableModule interface and handle the registration in the Initialize method. 

The following example (using a physical path) shows one way to create an IInitializableModule that registers a similar provider as in the configuration option above but this time through code.

using System;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.Framework.Localization;
using EPiServer.Framework.Localization.XmlResources;

namespace CodeSamples {
  [InitializableModule]
  [ModuleDependency(typeof (FrameworkInitialization))]
  public class CustomLanguageProviderInitializationWithPhysicalPath: IInitializableModule {
    private
    const string ProviderName = "customResources";
    public void Initialize(InitializationEngine context) {
      //Casts the current LocalizationService to a ProviderBasedLocalizationService to get access to the current list of providers
      ProviderBasedLocalizationService localizationService = context.Locate.Advanced.GetInstance<LocalizationService>() as ProviderBasedLocalizationService;
      if (localizationService != null) {
        string langFolder = @ "c:\temp\resourceFolder";
        if (Directory.Exists(langFolder)) {
          NameValueCollection configValues = new NameValueCollection();
          //This config value tells the provider where to find XML language documents.
          configValues.Add(FileXmlLocalizationProvider.PhysicalPathKey, langFolder);
          FileXmlLocalizationProvider localizationProvider = new FileXmlLocalizationProvider();
          //Instanciates the provider
          localizationProvider.Initialize(ProviderName, configValues);
          //Adds it at the end of the list of providers.
          localizationService.Providers.Add(localizationProvider);
        }
      }
    }

    public void Uninitialize(InitializationEngine context) {
      //Casts the current LocalizationService to a ProviderBasedLocalizationService to get access to the current list of providers
      ProviderBasedLocalizationService localizationService = context.Locate.Advanced.GetInstance<LocalizationService>() as ProviderBasedLocalizationService;
      if (localizationService != null) {
        //Gets any provider that has the same name as the one initialized.
        LocalizationProvider localizationProvider = localizationService.Providers.FirstOrDefault(p => p.Name.Equals(ProviderName, StringComparison.Ordinal));
        if (localizationProvider != null) {
          //If found, remove it.
          localizationService.Providers.Remove(localizationProvider);
        }
      }
    }

    public void Preload(string[] parameters) {}
  }
}

Optimizely provides two convenience classes, VirtualPathXmlLocalizationProviderInitializer and EmbeddedXmlLocalizationProviderInitializer, located in the EPiServer.Framework.Localization.XmlResources namespace. Use them when you register localization providers.

The following example (using virtual path) demonstrates using a convenience class to read XML language documents from a specified virtual path. A prerequisite for this sample is that you configure a VPP under the <episerver> section of web.config. The example uses the virtual path registered there virtual path. Also, this module is dependent on the Optimizely CMS InitializationModule, which requires a VPP because CMS start-up initializes VPPs.

using System;
using System.Linq;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.Framework.Localization;
using EPiServer.Framework.Localization.XmlResources;
using EPiServer.Web.Hosting;

namespace CodeSamples {
  [InitializableModule]
  //A dependency to Optimizely CMS initialization is needed to be able to use a VPP
  [ModuleDependency(typeof (EPiServer.Web.InitializationModule))]
  public class CustomLanguageProviderInitializationWithVirtualPath: IInitializableModule {
    private
    const string ProviderName = "CustomProviderName";

    public void Initialize(InitializationEngine context) {
      //Casts the current LocalizationService to a ProviderBasedLocalizationService to get access to the current list of providers
      ProviderBasedLocalizationService localizationService = context.Locate.Advanced.GetInstance<LocalizationService>() as ProviderBasedLocalizationService;
      if (localizationService != null) {
        VirtualPathXmlLocalizationProviderInitializer localizationProviderInitializer =
          new VirtualPathXmlLocalizationProviderInitializer(GenericHostingEnvironment.VirtualPathProvider);
        //a VPP with the path below must be registered in the sites configuration.
        string virtualPath = "~/MyCustomLanguageVPP/";
        FileXmlLocalizationProvider localizationProvider = localizationProviderInitializer.GetInitializedProvider(virtualPath, ProviderName);
        //Inserts the provider first in the provider list so that it is prioritized over default providers.
        localizationService.Providers.Insert(0, localizationProvider);
      }
    }

    public void Uninitialize(InitializationEngine context) {
      //Casts the current LocalizationService to a ProviderBasedLocalizationService to get access to the current list of providers
      ProviderBasedLocalizationService localizationService = context.Locate.Advanced.GetInstance<LocalizationService>() as ProviderBasedLocalizationService;
      if (localizationService != null) {
        //Gets any provider that has the same name as the one initialized.
        LocalizationProvider localizationProvider = localizationService.Providers.FirstOrDefault(p => p.Name.Equals(ProviderName, StringComparison.Ordinal));
        if (localizationProvider != null) {
          //If found, remove it.
          localizationService.Providers.Remove(localizationProvider);
        }
      }
    }

    public void Preload(string[] parameters) {}
  }
}