Optimizely CMS 12 have been out for a while now, but still some elements haven't been properly translated resulting in a GUI defaulting to english. While that may be fine with many of us I still do have some customers who refuse to see the benefits of learning a bit of english. Anyways, it is good practice to implement translations of elements in all web sites which would include the Optimizely CMS GUI.
Setting up and configuring translation in CMS 12
The official documentation (Localize the user interface (optimizely.com)) doesn't really cover this and as usual my approach is how to obtain a result with as little configuration and overhead as possible, leaving us with the following steps
- Adding a folder structure
- Adding the appropriate XML-language files configuring these for output
- Simple configuration in Startup.cs
- Figuring out which properties to manipulate in the CMS UI
- Add the elements to the custom language XML-file
- Done
Adding a folder structure
Modify this according to your needs, this will work in any setup and even in Docker. I do recommend having the XML-files stored locally because I love IOPS. I use the following structure in the root of the project:
/Resources/LanguageFiles
Adding language files
In the LanguageFiles folder create the files you may need. It is common practise to split them in one file per language but this isn't necessary.
When added remember to enable copy always for (all) the language files, in Visual Studio this can be done in the properties window (see image) or modify your csproj file accordingly
The csproj file
<ItemGroup> <None Update="Resources\LanguageFiles\Episerver_SV.xml"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </None> </ItemGroup>
The base XML-file, Episerver_SV.xml in my case
<?xml version="1.0" encoding="utf-8" ?> <languages> <language name="Svenska" id="sv"> </language> </languages>
Configuring Startup.cs
For this usage we only need to tell the CMS which localization provider to use and where it can find the files.
services.AddLocalizationProvider<FileXmlLocalizationProvider, NameValueCollection>(p => { p[FileXmlLocalizationProvider.PhysicalPathKey] = $"{_webHostingEnvironment.ContentRootPath}/Resources/LanguageFiles/"; });
Which properties to set in the CMS UI
This can be a bit tricky to find out, there is no guidance in exploring the DOM in CMS so we need to utilize a decompiler to see which paths Optimizely is setting in their default implementations. As far as I can tell resources can be found in the following binaries
- EPiServer.Cms.Shell.UI.dll
- EPiServer.Cms.TinyMce.dll
- EPiServer.Cms.UI.Admin.dll (Image editor)
- EPiServer.Cms.UI.VisitorGroups.dll
- EPiServer.Cms.Shell.UI.dll
- EPiServer.Shell.dll
- EPiServer.Shell.UI.dll
- EPiServer.UI.dll
I use JetBrains dotPeek to decompile and extract the default language files. However typically you are looking for the files in EPiServer.Cms.Shell.UI and EPiServer.UI, these would be named
- EPiServer.Cms.Shell.EmbeddedLangFiles.OnlineCenter_EN.xml
- EPiServer.EmbeddedLangFiles.language_EN.xml
To figure out the properties search the files (the english ones) for any word you need to translate, in this example the "Select Image" text needs to be translated as well as "Drop content here or".
These could be found in the file EPiServer.Cms.Shell.EmbeddedLangFiles.OnlineCenter_EN.xml with the paths episerver > cms > widget > contentselector > button > selectimage and episerver > cms > widget > contentselectorplugandplay > text.
Adding the elements to our custom language XML-file
<?xml version="1.0" encoding="utf-8" ?> <languages> <language name="Svenska" id="sv"> <episerver> <cms> <widget> <contentselector> <button> <selectimage>Välj bild</selectimage> <selectmedia>Välj media</selectmedia> <selectvideo>Välj video</selectvideo> </button> </contentselector> <contentselectorplugandplay> <text>Släpp innehåll här eller</text> </contentselectorplugandplay> </widget> </cms> </episerver> </language> </languages>
Resulting in
All done!