kotti_multilingual is a package still in an early stage of development that adds to the Kotti CMS (http://kotti.pylonsproject.org/) multilingual capabilities. It is neither feature complete nor can be considered API stable: so things will change!

You can find various fixes on this fork (a PR is still in the review phase):

How it works

First of all you should add a LanguageRoot folder in your root site. It is like the standard folderish Document, but with an editable Language attribute where you set the language code (eg: en, it, etc).

Once you have created two or more language folders (with >2 languages there is a problem with the translation link actions at this time of writing) you can add your contents and translate them.

The translate menu prompts a translate into italian action from  /en/welcome
If you click on the translate into action, it will create a translated instance in /it/welcome (you can rename it later in /it/benvenuto or whatever you like) and you'll be redirected to a regular edit form prefilled with the english fields values.

Once saved, you can switch to the existing translation and navigate among languages as shown in the following picture:

You can switch to the existing English translation
kotti_multilingual supports the quite advanced concept of language independent fields: a field whose values should be inherited by translations, only editable on the root translation.

You can see for example a select widget in edit mode on the root translation:
And the same field in readonly mode on the translated object:

See the kotti_multilingual.widget.i10n_widget_factory code for more info.

Code examples

And now code examples.


You can define language independent fields in your type_info attribute on your resource.
class YourResource(...):


    type_info = Document.type_info.copy(
        language_independent_fields= ['course_sku',],


The edit form does not require changes, you just need to apply the i10n_widget_factory on your language independent fields (in some particular cases you need a bit more complex setup when you have to deal with not null column, required fields, etc). In these particular cases you'll have to play with get_source (kotti_multilingual.api.source) and put the widget in readonly mode. If you experience problems cloning select widgets you might have to migrate to deferred widgets (that creates a new widget instance each time) and set the widget mode in readonly when needed.

from kotti_multilingual.widget import i10n_widget_factory
from kotti_multilingual.api import get_source 
def deferred_widget(node, kw):
    request = kw['request']
    context = request.context


    widget = SelectWidget(values=available_tags, multiple=True)
    if get_source(context) is not None:
        widget.readonly = True
    return widget

class YourResourceSchema(colander.Schema):

    course_sku = colander.SchemaNode(
        title=_(u"Course SKU"),

class YourResourceAddForm(ImageAddForm):
    schema_factory = YourResourceSchema

    def get_bind_data(self):
        bind_data = super(YourResourceAddForm, self).get_bind_data()
        # we tell to the i10n_widget_factory that this is an addform,
        # so our widgets will be shown as usual in edit mode
        bind_data['addform'] = True
        return bind_data

Final thoughts

Yes, it is a very very young package but very promising!
It is not complete and probably it never will be complete because SQLAlchemy is huge and I think it is not possible to cover all the possible SQLAlchemy combinations.

For example this fork includes support for the SQLAlchemy's association_proxy feature and language independent fields (in this case the copy_properties_blacklist attribute on your resource is your friend).

This is open source, dude: if you need something that is not yet covered, just fork kotti_multilingual, implement the missing parts and share with others!

Update 20150427

Merged and released new version of kotti_multilingual on PyPI https://pypi.python.org/pypi/kotti_multilingual/0.2a3.
Development happens on https://github.com/Kotti/kotti_multilingual now.

All Kotti posts published by @davidemoro:

No comments:

Post a Comment