plone.app.multilingual

Next generation

multilingual story

http://pam.iskra.cat

Ramon Navarro Bosch

  • CTO at Iskra.cat
  • 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

History

  • 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

LinguaPlone

  • 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

Components

  • plone.app.multilingual (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

Features

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


                        atapi.StringField(
                            'myField',
                            widget=atapi.StringWidget(
                            ....
                            ),
                            languageIndependent=True
                        ),
                    

Marking LIFs in DX

Grok directive

In content type declaration class


        from plone.multilingualbehavior import directives
        directives.languageindependent('field')
                    

Marking LIFs in DX

Supermodel

In your content type XML file declaration


                <field name="myField"
                          type="zope.schema.TextLine"
                          lingua:independent="true">
                    <description />
                    <title>myField</title>
                </field>
                    

Marking LIFs in DX

Native

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

Internals

Translatable marker interface


            plone.multilingual.interfaces.ITranslatable
                    

Adapters

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

Subscribers

Language integrity checkers

  • Add to container
  • Copy/paste
  • Modify

Storage

Why?

  • 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')
                    

DEMO!

Roadmap

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

Future

  • plone.app.toolbar support
  • Add support for Deco layouts and tiles

Sprint!

  • 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!

Questions?

Ramon Navarro Bosch (@bloodbare)

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

http://github.com/plone/plone.app.multilingual

http://pypi.org/plone.app.multilingual

http://pam.iskra.cat