Wichert Akkerman

Software design? Strange hacks? All of the above please!

Lingua 2 released

Lingua is a Python package that helps you find translateable texts in your code, and generate POT-file for them. It is the recommended tool for this Pyramid, but can be used for all Python code. There are good reasons why you should use the new Lingua instead of other tools like Gettext's xgettext or Babel's extract_messages:

  • Lingua can detect both c-format and python-format string expansion styles. Babel can only detect C-style formatting but incorrectly claims it is python-format.
  • Lingua will not wrongly classify a strftime string as c-format.
  • Lingua can process Python code in templates.
  • Lingua supports the message-notation used in Zope Page Templates
  • Lingua supports message strings as used by translationstring (used in Pyramid) and zope.i18nmessageid.
  • Lingua fully suports plural forms.

Previous versions of Lingua were implemented as an extraction plugin for Babel. This was no longer feasible: Babel was effectively unmaintained for a long time and is still only seeing little work, and its internal API for message extraction did not support everything Lingua needed. Therefore I made the decision to remove the Babel dependency completely (using polib to handle the POT-format) and add an extraction command to Lingua itself: the new pot-create command. This command is designed to be a drop-in replacement for `xgettext:

$ pot-create src/mypackage > messages.pot

All standard xgettext options such as reading the list of files to process from an input file (--files-from=POTFILES.in) and specifying which keywords to use (--keyword=mygettext) are supported. See the Lingua documentation for details.

Lingua itself includes parsers for Python, Zope Page Templates, ZCML files, and any template format that uses ${...} to include Python expressions. For backwards compatibility Lingua is able to use existing plugins for Babel, although their functionality may be limited.

Unlike Babel, lingua deliberately does not include commands to create, update or compile PO-files. Gettext is already installed on most systems and includes the msginit, msgmerge and msgfmt tools for these tasks. There is no way Lingua can do better than those, so it does not try. If you are upgrading from Babel with Lingua 1 to Lingua 2 that means you will need to make a few changes to your project. When adding a new language you now need to use msginit:

$ cd src/mypackage/locale
$ mkdir -p nl/LC_MESSAGES
$ msginit -i mydomain.pot -o nl/LC_MESSAGES/mydomain.po -l nl

When you add or modify translateable strings in your package you use pot-create to create a new POT-file, followed by msgmerge to update your PO-files.

$ pot-create src/mypackage > src/mypackages/locale/mydomain.pot
$ for po in src/mypackages/locale/*/LC_MESSAGES/mydomain.po ; do
>   msgmerge $po src/mypackages/locale/mydomain.pot
> done

And finally to compile your PO-files you use the msgfmt command:

$ for po in src/mypackages/locale/*/LC_MESSAGES/*.po ; do
>   msgfmt $po
> done