Edgewall Software

Version 84 (modified by Christian Boos, 10 years ago) ( diff )

alphabetical sorting of translation coordination tickets

Localization (L10N) of Trac

Trac uses Babel for localization. Trac trunk now contains the i18n framework and L10N files.

The Preferences ' Language panel can be used to select the language from the list of available translations, otherwise the web browsers' language preferences will be honored, if possible.

If you're only interested in using a localized version of Trac, then refer to the simpler 0.12/TracInstall instructions. The more complete installation instructions below are aimed at developers and translators.


Getting the Tool Chain

Python tools

  1. Install Babel version [Babel:wiki:Download#LatestRelease:0.9.4 0.9.4]
    Read the detailed installation instructions for Babel if you want to build it from source, but you should also be able to install it with a simple easy_install or by using one of the packages in the Download page linked above.
  2. Likewise, install Genshi, from the Genshi:source:trunk (at least revision [G1072]).
  3. Get a svn checkout from the Trac trunk, e.g. svn checkout http://svn.edgewall.org/repos/trac/trunk trac-0.12dev

Translation Workflow

Using Python tools

  1. Run python setup.py extract_messages.
    This will generate the catalog template file: source:trunk/trac/locale/messages.pot
    You should never have to edit that file manually.
    Note: this step is for committers only. If you're not a Trac svn committer, you have to use the available messages.pot, or bug us to update that file (though we do it on a regular basis).
  2. Run python setup.py update_catalog.
    This will regenerate the various string catalogs (trac/locale/*_*/LC_MESSAGES/messages.po), preserving the previously translated strings and merging the new translations found in the messages.pot file. Translations that are no longer needed are commented out (#~) and moved at the bottom of the .po file.
    Usually, you will be interested in working on one locale only, so you can pass the -l option to specify which catalog should be updated. For example:
    python setup.py update_catalog -l nl_NL.
  3. Now, open your favorite editor and add or modify translations for the extracted strings in the messages.po file for your language.
  4. Once you're done, you should test your translations:
    • Run python setup.py update_catalog -l again, for normalizing the manual edits. For example:
      python setup.py update_catalog -l nl_NL.
      This step is also quite useful for spotting the possible mistakes, like accidental changes of msgid strings. Look for lines beginning with #~, they are indicative of such errors. Note that the comments corresponding to translations which are no longer present in the messages.pot file (as discussed in step 2. above) have been discarded by this second update_catalog run.
    • Run python setup.py compile_catalog -f.
      This will generate one compiled catalog (message.mo file) for each (or each specified) messages.po file. You don't need to do anything with those files, they'll get installed automatically.
      You will most probably need to use the force option (-f) in order to compile catalogs marked "fuzzy". It is fine to have fuzzy translations but try to never contribute a translation still containing those markers, as they mean that a given translation has not been reviewed by a human but were machine generated. Fuzzy translations should be either cleared when they are wrong, or validated when they are correct, by removing the fuzzy tag or even the whole line iff fuzzy was the only keyword on that line
      You can also use the -l option here to specify the locale for which the messages.po has to be compiled.
    • Run python setup.py install for installing Trac and locale data. Alternatively you can use python setup.py develop once for all, if you want to be able to run Trac from your working copy.

Note that you could stop at step 3, but then you risk to submit incomplete or, worse, buggy messages.po files. Going through the 4th step will ensure a better quality standard. Finally, seeing your translations "live" in Trac is not only a great way to realize if the translation still makes sense once put in context, but also quite gratifying when you see that you picked the correct wording ;-)


The various catalog files (messages.po) can be found in the repository under source:trunk/trac/locale. The messages.pot is the template file from which the various locale-specific files get created.

Adding translations for a new language

If you need to create a catalog for a new locale (e.g. et_EE), do:

$ ./setup.py init_catalog -l et_EE

Then proceed through the steps listed above starting at step 2.


See our translation statistics, on Transifex.

Editing Guidelines

There are tons of good guidelines on the web about how to write good translations. See for example: PO_Odyssey and step-by-step, and other resources from http://l10n.kde.org.

In short, a translation unit is typically something like:

#: trac/ticket/templates/milestone_delete.html:41
#: trac/ticket/templates/milestone_view.html:105
msgid "Delete milestone"
msgstr "Supprimer le jalon"
  • the "#:" lines are comments indicating the locations of the message in the source.
  • msgid "..." is the message itself, this should never be changed
  • msgstr is your translation; you should keep there the same structure, as in the msgid. In particular the presence of "\n" at the beginning or the end of the msgid should be mirrored in msgstr
  • right after an automatic catalog update you'll see lots of:
    • # fuzzy comments: this identifies translations that are only approximated (the msgid has changed)
    • msgstr "" translations: those are newly added translations

There are a few more complex situations.

Here's a message containing parameters:

#: trac/ticket/templates/milestone_view.html:26
#, python-format
msgid ""
"Completed %(duration)s ago\n"
"              (%(date)s)"
msgstr ""
"Atteint il y a %(duration)s\n"
"                (%(date)s)"

Note that you need to have to keep the parameters names from msgid in msgstr, although you can reorder them as needed.

Another example, here's how a structured message looks like:

#: trac/ticket/templates/milestone_delete.html:45
msgid ""
"[1:Note:] See\n"
"      [2:TracRoadmap] for help on using\n"
"      the roadmap."
msgstr ""
"[1:Note :] consultez [2:TracRoadmap] pour obtenir de l'aide sur "
"l'utilisation de la feuille de route."

The [1: ...] groups are used when the message contains markup (this is Genshi specific). It is important to keep the same semantic structure. As with message parameters, the groups can be reordered but you should have the same groups in msgid and msgstr.

Of course, you can have messages that combine markup groups and parameters names:

#: trac/ticket/templates/milestone_view.html:32
#, python-format
msgid ""
"[1:%(duration)s late]\n"
"              (%(date)s)"
msgstr ""
"[1:%(duration)s en retard]\n"
"                (%(date)s)"

Finally, there's the translation of sentences which have a singular and a plural form:

#: trac/ticket/templates/query.html:29
#: trac/ticket/templates/query_results.html:30
#: trac/ticket/templates/report_view.html:94
#, python-format
msgid "%(num)s match"
msgid_plural "%(num)s matches"
msgstr[0] "%(num)s résultat"
msgstr[1] "%(num)s résultats"
  • when such a message is newly added, you'll have
    #, fuzzy, python-format as the first comment. Be careful to remove only the fuzzy, part, but not the python-format keyword.
  • some languages (zh, ko) don't have plural forms (plural == 1), so you only have to put a msgstr[0] line.
  • some other languages have more than 2 plural forms, so you need as many msgstr[] as needed.

Note: there are some problems with Genshi and Babel when all the msgstr[] need to have the same content. Also, Babel seems to handle well different parameters for msgid and msgid_plural, whereas msgfmt complains about those.

Terms (Definitions)

Consistent and careful translation of terms like timeline, ticket, report is very important. These terms are used everywhere and must be easy to remember and comfortable to use.

The way to make up good translations of important terms is to discuss them before using everywhere. The easiest way to accomplish it is to set up wiki pages for different languages.

Look also at the various term definition pages: Am, Cy, Cz, De, El, Es, Fa, Fi, Fr, Gl, He, Hu, It, Ja, Ko, Lv, Nl, Pl, Pt, PtBr, Ru, Sv, Tr, ZhCn, ZhTw and TracTermTr (to be renamed once we have #1106).

Translation coordination

For the various languages there are already various tickets logged in which the work on them is tracked: No results

This is a way by which translators for the same language can coordinate their work.

Open issues

  • i18n infrastructure for Trac plugins (#7497)
  • translation of wiki pages (#1513) and help pages (TracDev/Proposals/NewHelp)
  • translation of text within Javascript source code
  • failure to start Trac (raw NullTranslations instance has no attribute 'add' error) when no .mo file is available No results

See also:

Note: See TracWiki for help on using the wiki.