Next generation

multilingual story

Ramon Navarro Bosch

  • CTO at
  • Developing Plone sites since 2003
  • Part time musician

- Ramon's blog / @bloodbare

Víctor Fernández de Alba

  • Lead web developer at Universitat Politècnica de Catalunya - Barcelona Tech
  • Author of Plone 3 Intranets (2010, Packt)
  • Developing Plone sites since 2004

- Víctor's Blog / @sneridagh


  • Project started at Girona (Catalonia) sprint in 2005
  • Gathered some of the Plone Rock Stars
  • Design decisions, base infrastructure
  • Only for AT, DX doesn’t even exist yet


  • Great product created by Jarn
  • “De facto” standard multilingual story for Plone
  • Only supports AT
  • Now in “legacy” status
  • Used (literally) in every Plone site (I've) deployed
  • Lots of experience embedded

LinguaPlone design facts

  • Stores translation relations into objects
  • Uses catalog patches to hide content depending on current language
  • Relies in class inheritance to extend standard AT functionalities
  • Not compatible with dexterity content types

Enter PAM

  • Uses ZCA technologies
  • AT and DX compatible
  • Manage translations via unified UI


  • (UI)
  • plone.multilingual (core)

  • plone.multilingualbehavior (DX support)
  • archetypes.multilingual (AT support)

Rules of design

  1. There is no canonical content object
  2. Strict language root folders
  3. Neutral support outside LRF


Language root folders

  • Created on PAM setup
 (Language control panel)
  • Plone folders implementing INavigationRoot
  • Subscribers in place...
  • ... to guarantee integrity
  • ... so each language is “jailed” inside its own LRF

Babel view

  • Unified edit form either for AT and DX
  • Not forced every time you edit a content
  • LP like, but with vitamins
  • Instant access (ajaxified) to other available translations in the left panel

Language independent fields

  • No canonical implies changes in LIFs behavior
  • Users can change the content inside a LIF and it gets replicated to other translation objects

Marking LIFs in AT

Same way as in LP


Marking LIFs in DX

Grok directive

In content type declaration class

        from plone.multilingualbehavior import directives

Marking LIFs in DX


In your content type XML file declaration

                <field name="myField"
                    <description />

Marking LIFs in DX


In your code

from plone.multilingualbehavior.interfaces import ILanguageIndependentField
alsoProvides(ISchema['myField'], ILanguageIndependentField)

Marking LIFs in DX

Through the web

Via the content type definition in the Dexterity Content Types control panel.

Language selector policy

  • There are two policies in place in case the translation of a specific language does not exist (yet):
  • LP way, the selector shows the nearest translated container
  • Shows the user an informative view that shows the current available translations for the current content

Neutral root folder support

  • As a necessity due to LRFs
  • There are use cases where “neutral” content is a must
  • Assets, resources, media, documents...

Translation map

  • Aid for mental sanity of site editors
  • Graphical way to show content and its related translations
  • List of untranslated content (for mirror-translated sites)

Google Translation service

  • Integration with GTS (paid service)
  • Icon in Babel view
  • Setup API key in Language control panel

LinguaPlone migration

  • Migration tab in Languages control panel
  • Non-destructive
  • Lookup your code for LP dependencies before migrating
  • Still rough edges, should be addressed in sprint


Translatable marker interface



  • ITranslationManager
  • ITranslationLocator
  • ITranslationCloner
  • It’s easy to create “policies” with more specific adapters (translation locator, selector, etc.)


Language integrity checkers

  • Add to container
  • Copy/paste
  • Modify



  • Modify translation without waking objects
  • Direct translation map
  • Easier to work on all translations (import/export)
  • Too much catalog!!

Unified get/set language

Unified adapter for AT and DX

        from plone.multilingual.interfaces import ILanguage
        language = ILanguage(context).get_language()
        language = ILanguage(context).set_language('ca')



  • XLIFF export/import
  • Removing catalog patch
  • Iterate support
  • LinguaPlus/Linguatools set of useful tools
  • Locator translation policy
  • Outdated translations alerts and translation workflows support


  • support
  • Add support for Deco layouts and tiles


  • LinguaPlone Migration improvements
  • UI Rough edges
  • More Testing and use cases
  • Locator translation policy

Join us on PC Sprint!

Special thanks to...

  • Anne Walter
  • Jonathan Lewis
  • Martijn Pieters
  • Martin Aspeli
  • David Glick
  • Patrick Gerken
  • Thomas Masmann
  • Jean Carel Brand
  • Mikel Larreategui

Thank you!


Ramon Navarro Bosch (@bloodbare)

Víctor Fernández de Alba (@sneridagh)