|Version 94 (modified by 10 years ago) ( diff ),|
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
- Install Babel version [Babel:wiki:Download#LatestRelease:0.9.5 0.9.5]
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_installor by using one of the packages in the Download page linked above.
- Likewise, install Genshi, from the Genshi:source:trunk (at least revision [G1072]).
- Get a svn checkout from the Trac trunk, e.g.
svn checkout http://svn.edgewall.org/repos/trac/trunk trac-0.12dev
Using Python tools
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).
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
-loption to specify which catalog should be updated. For example:
python setup.py update_catalog -l nl_NL.
- Now, open your favorite editor and add or modify translations for the extracted strings in the messages.po file for your language.
- Once you're done, you should test your translations:
python setup.py update_catalog -lagain, 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
msgidstrings. 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
python setup.py compile_catalog -f.
This will generate one compiled catalog (
message.mofile) 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
-loption here to specify the locale for which the messages.po has to be compiled.
python setup.py installfor installing Trac and locale data. Alternatively you can use
python setup.py developonce 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 ;-)
Although Babel is Python specific and is the tool which is advised to use, the traditional msgfmt toolset can also be used. In particular, the following command is quite useful:
$ msgfmt --statistics --check trac/locale/pl/LC_MESSAGES/messages.po 979 translated messages, 85 fuzzy translations, 32 untranslated messages.
All is well, except for some fuzzy and missing translations ;-)
$ msgfmt --statistics --check trac/locale/zh_CN/LC_MESSAGES/messages.po trac/locale/zh_CN/LC_MESSAGES/messages.po:2155: a format specification for argument 'unit', as in 'msgstr', doesn't exist in 'msgid' trac/locale/zh_CN/LC_MESSAGES/messages.po:2162: a format specification for argument 'unit', as in 'msgstr', doesn't exist in 'msgid' trac/locale/zh_CN/LC_MESSAGES/messages.po:2169: a format specification for argument 'unit', as in 'msgstr', doesn't exist in 'msgid' msgfmt: found 3 fatal errors 1058 translated messages.
Some errors were detected with format specifications.
This is a useful additional check, as
python setup.py compile_catalog -l zh_CN wouldn't have detected that issue.
The web-based collaborative site for translations Transifex has a project page for Trac.
From there, it is easy to download an always up to date
and start translating right away.
Your translation can then be uploaded and will for now be sent back to us by mail, but in the future they will be directly committed in a dedicated i18n repository clone of Trac.
It is important however to keep the messages.po files free from
fatal errors as reported by
msgfmt --check, as this might confuse
Transifex and prevent it to report correct statistics or merge the
The easy way using
make and l10n targets
You'll find a Makefile in the toplevel directory of the Trac source.
If you're lucky enough to have the GNU
make tool, you can benefit from some
automation for these translation tasks.
$ make ... ---------------- L10N tasks extraction regenerate the messages.pot template file update update all the messages.po file(s) update-xy update the catalog for the xy locale only compile compile all the messages.po files compile-xy compile the catalog for the xy locale only check verify all the messages.po files check-xy verify the catalog for the xy locale only stats translation statistics for all catalogs stats-pot statistics for the messages.pot template file stats-xy statistics for the xy locale only [locale=...] variable for selecting a set of locales
$ make stats-pot update check compile stats locale='fr de' translation statistics for messages.pot: stats-pot: 0 translated messages, 1096 untranslated messages. python setup.py update_catalog -l fr running update_catalog updating catalog 'trac/locale\\fr\\LC_MESSAGES\\messages.po' based on 'trac/locale/messages.pot' python setup.py update_catalog -l de running update_catalog updating catalog 'trac/locale\\de\\LC_MESSAGES\\messages.po' based on 'trac/locale/messages.pot' checking catalogs for fr de... check-fr: OK check-de: OK All catalogs checked are OK python setup.py compile_catalog -l fr running compile_catalog compiling catalog 'trac/locale\\fr\\LC_MESSAGES\\messages.po' to 'trac/locale\\fr\\LC_MESSAGES\\messages.mo' python setup.py compile_catalog -l de running compile_catalog compiling catalog 'trac/locale\\de\\LC_MESSAGES\\messages.po' to 'trac/locale\\de\\LC_MESSAGES\\messages.mo' translation statistics for fr de... stats-fr: 1096 translated messages. stats-de: 932 translated messages, 164 untranslated messages.
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.
Note that if the statistics for a language suddenly drop to 0%,
this is indicative of the presence of fatal errors
(as reported by
msgfmt --check) in the corresponding
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. (The references also applies to translators using Windows, though the set of translation editors seems to be narrower. However, see Poedit for a multiplatform dedicated PO editor.)
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
msgstris 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:
# fuzzycomments: 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 keep the same set of parameters in
msgstr, both for the name and the keyword (i.e. don't
%(id)s with a
%(id)d), 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."
[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
msgstr (see for example r9553).
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 "%(num)s résultat" msgstr "%(num)s résultats"
- when such a message is newly added, you'll have
#, fuzzy, python-formatas the first comment. Be careful to remove only the
fuzzy,part, but not the
- some languages (zh, ko, ja) don't have plural forms (plural == 1),
so you only have to put a
- some other languages have more than 2 plural forms, so you need as
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).
For the various languages there are already various tickets logged in which the work on them is tracked:
- Multi-language support in the wiki
- Translation of Trac to Arabic/عربى [ar_EG]
- Translation of Trac to Argentinian Spanish/español de Argentina [es_AR]
- Translation of Trac to Armenian [hy_AM]
- Translation of Trac to Catalan/Català [ca]
- Translation of Trac to Chinese/中文 [zh_CN]
- Translation of Trac to Czech/Česky [cs_CZ]
- Translation of Trac to Dutch/Nederlands [nl_NL]
- Translation of Trac to English [en_GB]
- Translation of Trac to Estonian/eesti [et_EE]
- Translation of Trac to Farsi/پارسی [fa_IR]
- Translation of Trac to Finnish/suomi [fi_FI]
- Translation of Trac to French/Français [fr_FR]
- Translation of Trac to Galician/Galego [gl_ES]
- Translation of Trac to German/Deutsch [de_DE]
- Translation of Trac to Greek/Ελληνικά [el_GR]
- Translation of Trac to Hebrew [he_HE]
- Translation of Trac to Hungarian/Magyar [hu_HU]
- Translation of Trac to Italian/Italiano [it_IT]
- Translation of Trac to Japanese/日本語 [ja_JP]
- Translation of Trac to Korean/한국어 [ko_KR]
- Translation of Trac to Norwegian/bokmål [nb_NO]
- Translation of Trac to Polish/Polski [pl_PL]
- Translation of Trac to Portuguese/Português [pt_BR]
- Translation of Trac to Portuguese/Português [pt_PT]
- Translation of Trac to Romanian/Română [ro_RO]
- Translation of Trac to Russian/Русский [ru_RU]
- Translation of Trac to Slovene/Slovensko [sl_SI]
- Translation of Trac to Spanish/Español [es_ES]
- Translation of Trac to Swedish/Svenska [sv]
- Translation of Trac to Traditional Chinese/正體中文 [zh_TW]
- Translation of Trac to Turkish/Türkçe [tr_TR]
- Translation of Trac to Vietnamese/Tiếng Việt [vi_VN]
- Translations to Esperanto [eo]
This is a way by which translators for the same language can coordinate their work.
- help us spot the MissingTranslations!
- i18n infrastructure for Trac plugins (#7497)
- translation of wiki pages (#1513) and help pages (TracDev/Proposals/NewHelp)
- failure to start Trac (raw
NullTranslations instance has no attribute 'add'error) when no .mo file is available
- Multi-language support in the wiki
- Component field sort order doesn't use locale
- Timeline shows incomplete information about status changes for customized workflow
- Workflow actions not translated
- TicketQuery groups without translation
- Created, Modified and Ticket columns are not translated in SQL reports
- Wrong label on wiki diff view between initial version and version 1
- Error message with untranslated text when removing no selected items