Many sites need to support content and templates in multiple languages. Luckily, Zotonic is completely multilingual, out of the box. mod_translation does all the work for you.
Zotonic will try to serve the page in the language of the user (based on the browser’s HTTP Accept header) or the selected language from the URL. If this fails, Zotonic falls back to the default language as configured on the Translation admin page.
In Zotonic, two kinds of information are being translated.
Before you can use multiple languages, you first need to enable mod_translation.
Next, you need to tell Zotonic which languages you are going to use. You can do this in the /admin, following the Translation menu item in the Structure submenu.
On this page you can add and remove languages, enable/disable languages and more. Note that a language is always identified by its two letter ISO639-1 language code.
The fixed texts in a Zotonic website are translated using the GNU gettext <http://www.gnu.org/software/gettext/> .po file format and its related tools.
In Zotonic, static translations are organized in each Zotonic module. It is the module’s responsibility to provide translations for all the texts that it uses in its templates. All files related to static translations live inside the translations/ subdirectory of a module (remember: a Zotonic site is just a module!).
In the translations/ directory of the modules you can find the .po files containing the translations. They are marked with the their two letter language code. (Optionally you can name your file like: nl.foobar.po as Zotonic will only look at the part till the first ‘.’ for the language code):
translations/ ├── nl.po ├── template │ └── mod_foo.pot └── tr.po
Here you see that this module, mod_foo, has been translated into Dutch (nl) and Turkish (tr).
The translations/ directory contains a subdirectory which contains mod_foo.pot, which is the translation template, on which new translations will be based.
The basis for these files (the translation template), is the .pot file which is located in the template/ subdirectory of the translations directory. This .pot file is regenerated when you click on the generate .pot files button on the Translation page in the admin.
After clicking generate .pot files, Zotonic will parse all your templates and Erlang modules for translatable strings. These strings are then added to the .pot file.
First, add a language in the admin with the 2-letter code for that language.
Say, we’re adding Polish, pl. Now copy the .pot template file to the 2-letter code .po file:
$ cd modules/mod_foo $ cp translations/template/mod_foo.pot translations/pl.po
Now, open pl.po in your favorite editor and start translating the strings. A good po file editor can be found at: http://www.poedit.net/
When templates change, often the translatable strings change: more strings are added, strings are changed, or removed. When this happens, the translation files need to be kept in sync.
The Translation status page in the admin gives an overview, per module / language combination, of the amount of strings that are translated for each language.
After pressing the Generate .pot files button in the translation admin the .pot files are updated, but the existing .po files are not.
GNU gettext comes with a tool, msgmerge, which looks at the changed strings in a .pot file and changes the translated strings in a language’s .po file accordingly:
$ cd modules/mod_foo/translations $ msgmerge -U nl.po templates/mod_foo.pot
This will merge the new strings into the existing nl.po file. After doing this, you’ll need to edit the nl.po file again to check if there are new strings which need translation, edit existing strings, etc.
When you have enabled languages on the Translation page of the admin you will see a Translations item on the right of the edit page.
Each language has a checkbox next to it: When you click a checkbox, the language will become visible as a tab on your content items.
Resources in Zotonic are translated on a per-page basis. This allows you to start translating your site by translating the most important pages first.