cone.app
uses the .po
(portable object) and .pot
(portable object template) extensions as translation files, which use
the GNU gettext format.
For managing translations, lingua is used to create translations for different languages, extracting translation strings from source code, and to compile message catalogs.
When working with YAFOWIL forms in YAML
format, you also need to install
yafowil.lingua
additionally to lingua
in order to get translations
extracted properly from the .yaml
files.
Install lingua
either globally in your system python or to the virtual
environment the application is installed.
sudo pip install lingua
sudo pip install babel
sudo pip install chameleon
sudo pip install yafowil.lingua
Lingua provides a helper script which can be used for managing translations.
Copy the script to the plugin package directory and adopt the settings parameters in the script.
#!/bin/bash
# Usage:
# Initial catalog creation (lang is the language identifier):
# ./i18n.sh lang
# Updating translation and compile catalog:
# ./i18n.sh
# configuration
DOMAIN="cone.example"
SEARCH_PATH="src/cone/example"
LOCALES_PATH="src/cone/example/locale"
# end configuration
# ...
For adding a new translation language, call i18n.sh
with the desired
language code.
./i18n.sh de
For extracting translations and compiling the message catalog call the
i18n.sh
script without arguments. It will extract translation strings from
code followed from compiling message catalogs for all languages.
./i18n.sh
To tell cone.app
about the translations contained in the plugin, they must
be registered inside the Plugin main hook function.
def example_main_hook(config, global_config, local_config):
# add translation
config.add_translation_dirs('cone.example:locale/')
Defining translation strings in python. A translation string factory must be instanciated with the correct i18n domain which is used for creating translation strings.
from pyramid.i18n import TranslationStringFactory
_ = TranslationStringFactory('cone.example')
translation_string = _(
'example_translation_string',
default='Example Translation String'
)
Defining translation strings in page templates. The i18n
namespace and
the correct i18n:domain
must be defined.
<tal:block xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
i18n:domain="cone.example"
omit-tag="True">
<span i18n:translate="example_translation_string">
Example Translation String
</span>
</tal:block>
Defining translation strings in YAML forms.
factory: form
name: exampleform
widgets:
- title:
factory: field:label:text
value: expr:context.model.attrs['title']
props:
label: i18n:title_label:Title
In order to make translations work in YAML forms, the correct translation string factory must be provided on the form tile.
from cone.app.browser.form import Form
from cone.app.browser.form import YAMLForm
from plumber import plumbing
from pyramid.i18n import TranslationStringFactory
_ = TranslationStringFactory('cone.example')
@plumbing(YAMLForm)
class ExampleForm(Form):
form_name = 'exampleform'
form_template = 'cone.example.browser:forms/example.yaml'
@property
def message_factory(self):
return _
Defining translation strings in ZCML files actually works the same way as for XML files and page templates. However, lingua ships with a ZCML extractor which works slightly different to what one would expect, and this extractor is set as default extractor for .zcml file endings.
So when working with ZCML files containing translation strings it’s recommended
to use the XML extractor instead of the default extractor. Therefor we create
a lingua.cfg
file next to the i18n.sh
script.
[extensions]
.zcml = xml
In the i18n.sh
script we need to change the pot-create
command to use this
config file.
pot-create "$SEARCH_PATH" -c lingua.cfg -o "$LOCALES_PATH"/$DOMAIN.pot