HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunitySubmit a ticketLog In
GitHubNuGetDev CommunitySubmit a ticket

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 all 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 element, see the EPiServer.Framework.Configuration.LocalizationElement class.

The following example configuration demonstrates this option. The addDefaultProviders attribute is set to false, which means that the _lang_folder is ignored when the site is initialized. Therefore, 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 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 section of web.config. The virtual path registered there is used as virtual path in the example. Also, this module is dependent on the Optimizely CMS InitializationModule, which is required to use a VPP, since VPPs are initialized during CMS start up.

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) { }
        }
    }