Linus Ekström
OMVPPaaS CMS Developer Certification
Dec 5, 2013
visibility 12115
star star star star star
(2 votes)

New standardized format for content type localizations

In EPiServer 7.5, there is a new standarized way how to add localized texts for content types. In previous versions of EPiServer there was separate section for each content type, for instance:

<language id="en" name="English">
    <pagetypes>
        <pagetype name="PageListBlock">
            <name>Page List</name>
            <description>Displays a list of pages, for example to display recent news</description>
        </pagetype>
    </pagetypes>
</language>

 

Since the amount of “base” content types has grown significally in EPiServer 7.5, specifically when taking EPiServer Commerce into consideration, we decided to normalize how content localizations are handled. All content types are now added under the top level section named “contenttypes”. The format has also changed a bit as seen below:

 
<language id="en" name="English">
  <contenttypes>
    <standarpage>
      <name>Standard Page</name>
      <description>A plain vanilla page.</description>
    </standarpage>
    <teaserblockcontrol>
      <name>Teaser</name>
      <description>Used to insert a content teaser</description>
    </teaserblockcontrol>
  </contenttypes>
</language>

 

Adding localized texts for properties can be done either to a specific content type:

<language name="en">
  <contenttypes>
    <startpage>
      <name>Start page</name>
      <description>A description of the page type</description>
      <properties>
        <searchresultpagelink>
          <caption>Search Result Page Link</caption>
          <help>Link to search result page.</help>
        </searchresultpagelink>
      </properties>
    </startpage>
  </contenttypes>
</language>

 

Reusing localization for properties between content types

It is also possible to add common translations to an inherited type, for instance pagedata or icontentdata:

<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 you have your own base classes that are not registered as content types and you want to add the translations to these classes you need to create a UIDescriptor for the base class.

Localizing headers

Headers (tabs for instance) can be localized in the top level section “groups”:

 
<language name="en">
  <groups>
    <advanced>Advanced</advanced>
    <categories>Categories</categories>
  </groups>
</language>

 

Upgrading existing language files

When using Deployment Center to upgrade a site, the upgrade process will try to convert any xml files in the “lang” and “Resources\LanguageFiles” folders given that that process can write to these files (they cannot be read only for instance). If you have existing files in other locations or want to do the conversion manually for some reason (check in to source control for instance) there is a small program that can be used to convert existing files. Just select the folder where the files you want to convert are located and press “Convert Content Type Sections” and the files should be updated to use the new format. You can download the program here.

Dec 05, 2013

Comments

Per Nergård (MVP)
Per Nergård (MVP) Dec 22, 2013 10:42 PM

When I try to use PageData instead of icontentdata for reuse between contenttypes it doesn't seem to work.

Linus Ekström
Linus Ekström Jan 7, 2014 11:44 AM

@Per: I tried using PageData instead of IContentData. It seems that this will work for some places (for instance when editing in the all properties view), but not for other places, like side by side editing and when hovering over a properties in the on page edit view. The reason why pagedata is not working but icontentdata is, is that the server only implements a hard coded fallback to icontentdata (when using PropertyDefinition.TranslateDisplayName). To use the full fallback chain we have to call a specific client side API which we are apparantly are not doing in all places at the moment. I'll report a bug for this.

Per Nergård (MVP)
Per Nergård (MVP) Jan 14, 2014 03:19 PM

Thanks for the answer.

Johan Book
Johan Book Aug 29, 2014 02:19 PM

Was there ever a separate blog post to describe how to make it work when inheriting own base classes? I can't seem to get EPI to pick up our translations no matter what I do. There seems to be a translation stored in the database that takes precedence but I can't find where it is...

Linus Ekström
Linus Ekström Aug 29, 2014 03:37 PM

I think that you need to create an UIDescriptor to indicate to the client that your base class should be taken into consideration. Just create and registering it should be enough:

[UIDescriptorRegistration]
public class YourBaseClassUIDescriptor : UIDescriptor
{
}

Linus Ekström
Linus Ekström Aug 29, 2014 03:38 PM

I can mention that I tried adding automatic registering for base classes. Unfortunately, this had some negative side effects so we had to back on this. We are trying other approaches to solve this so that you don't have to do this yourself.

Linus Ekström
Linus Ekström Nov 12, 2014 09:30 AM

I can add that the default convention is to use the classname made lower case as the key for the language files. This can be changed though, for instance including the full namespace, if you have classes with the same name in different namespaces. To do this, just set the LanguageKey property in the UIDescriptor for a type:

[UIDescriptorRegistration]
public class YourClassUIDescriptor : UIDescriptor
{
LanguageKey = typeof(YourClass).FullName.ToLowerInvariant();
}

Anders Murel
Anders Murel Jan 13, 2016 08:41 AM

@Linus: Ref your comment about filing a bug report 07 January 2014 11:44. Was this resolved? It seems this is still a problem i CMS 9.5. Localized (overridden) text is not shown on fly-out box, but in all properties view.

Piotr Krajewski
Piotr Krajewski Feb 15, 2016 11:51 AM

Hi, can you tell me how I can translate a name of my schedule job that extends ScheduledJobBase? Where should I put it in my xml file? What is the path?

error Please login to comment.
Latest blogs
Surviving a Dirty Feed. Part 3: Error Handling and Event Batching

Committing a 250,000-row Optimizely catalog import row by row, returning a per-row failure report, and coalescing catalog events into one per batch.

Stanisław Szołkowski | Oct 16, 2026 |

Building UI Extensions for Optimizely SaaS CMS

Introduction Developers have been extending the functionality of Optimizely PaaS CMS for years using addons built in C# and deployed as NuGet...

Mark Stott | Oct 15, 2026

Cheapskate AI Translator: Because Translation Should Not Require a Second Mortgage

There is a particular kind of software project that begins with a detailed architecture document, a product roadmap, and a carefully assembled...

Linh Doan Cuu | Oct 15, 2026

Computed Fields in CMS 13 Content Contracts with Optimizely Graph

Content Contracts in Optimizely CMS 13 allow different content types to share a common structure when querying Optimizely Graph. But what if the...

Mardy | Oct 14, 2026