The Content Editor I18n Support module is now available with Magnolia CMS, in version 2.1 of the Content Editor module.

Refer to Stories App, and more specifically to its Content internationalization (i18n) section in the main product documentation for up-to-date information. This page is no longer maintained. 

This is a simple workaround to provide basic content translation capability to content-editor based apps such as the Stories app.

The translation UX provided in this solution is different from the standard Magnolia translation UX in the page editor and in standard content apps. This workaround will eventually be replaced with a standard translation mechanism in the core product.


Maven is the easiest way to install the module. Add the following dependency to your bundle:



2.1.1Magnolia 6.2
2.0.5Magnolia 6.1
2.0.2Magnolia 5.7
2.0.2Magnolia 5.6


This module provides a new 'Translate' Action which can be added to the actionbar of a content-editor based app.

The action opens a dialog where the editor can select the language to translate to - then it creates a copy of the item as a sibling node.

The new item has two special properties, a 'master' property which stores a link to the original item, and a language property. The user can then perform the actual translation on this new item.

Translate action

A new Translate action is available on the composition nodes. The action:

  • Opens a light dialog where the user can pick one of the locales configured on the site, and pick whether the existing story content is copied (by default it is not copied.).
  • Creates a new composition node at the same level as the original story. Optionally copying the content of the original node.
  • Appends the locale to the node name: lost-and-found-in-the-swiss-alps_de
  • Sets the locale property to the locale.
  • Sets the master property is to the UUID of the "master" node.

The locale property is displayed read-only in the outline.

The master property is not displayed in the outline.


The module provides, and registers, a small new templating function library, storyfn.

The library has one method, storyfn.localizedStory(content) which is used to get the content from the proper node based on the currently active language.

Use storyfn in your templates to get the translated content. A simple example:

[#assign story = cmsfn.contentByPath("/stories-demo/" + selector, "stories") /]
[#assign storyTranslated = storyfn.localizedStory(story)!/]

When displaying a list of stories, you will probably want to display just the "master" stories, so that you do not display the originals and the translations all in one list. A simple example:

[#assign stories = cmsfn.children(rootContent, "mgnl:composition")]
[#list stories as story]
  [#if !story.master?has_content]
    [#assign storyTranslated = storyfn.localizedStory(story)!/]

Technical details

Each translation is stored in its own sibling node, at the same level as the original

While this structure could theoretically support translatable node names, that is not covered in this workaround. In fact, for simplicity we use the original node name and append the locale.

A translation composition node will contain two additional properties:

  • locale
    • Stores the locale of the translation
  • master
    • Stores the UUID of the master node, typically the content in the default locale.

These properties will allow the templates to retrieve the proper content for the desired locale.

  - lost-and-found-in-the-swiss-alps        mgnl:composition
	- author
    - title
    - 01                              	    mgnl:block
    - 02
  - lost-and-found-in-the-swiss-alps_de     mgnl:composition
    - author
    - title
    - locale = de
    - master = <UUID of original story>
    - 01                                    mgnl:block
    - 02
  - lost-and-found-in-the-swiss-alps_fr     mgnl:composition
    - author
    - locale = fr
    - master = <UUID of original story>


  • This module is at INCUBATOR level.
  • The translated item is linked to the original story, but content is not synchronized. When you change the original you must remember to update the translation yourself.
  • We don't plan to provide migration for your story translations once the translation feature is officially released. We don't know yet exactly how story translations will be stored. If possible we will try and provide a Groovy script.


  • No data.