Internationalization

The Camelot translation system is a very small wrapper around the Qt translation system. Internally, it uses the QCoreApplication.translate() method to do the actual translation.

On top of that, it adds the possibility for end users to change translations theirselves. Those translations are stored in the database. This mechanism can be used to adapt the vocabulary of an application to that of a specific company.

How to Specify Translation Strings

Translation strings specify “This text should be translated.”. It’s your responsibility to mark translatable strings; the system can only translate strings it knows about.

from camelot.core.utils import ugettext as _

message = _("Hello brave new world")

The above example translates the given string immediately. This is not always desired, since the message catalog might not yet be loaded at the time of execution. Therefore translation strings can be specified as lazy. They will only get translated when they are used in the GUI.

from camelot.core.utils import ugettext_lazy as _

message = _("This translation is delayed")

Translation strings in model definitions should always be specified as lazy translation strings. Only lazy translation strings can be translated by the end user in various forms.

Translating Camelot itself

To extract translation files from the Camelot source code, Babel needs to be installed.

In the root folder of the Camelot source directory.

First update the translation template:

python setup.py extract_messages

If your language directory does not yet exists in ‘camelot/art/translations’:

python setup.py init_catalog --locale nl

If it allready exists, update it from the translation template:

python setup.py update_catalog

In the language subdirectory of ‘camelot/art/translations’, there is a subdirectory ‘LC_MESSAGES’ which contains the .po translation file. This translation file can then be translated with linguist

linguist camelot.po

And edit it :

../_images/camelot_qt_linguist.png

Make sure to save them back as GNU gettext .po files.

Then the .po file should be converted to a .qm file to make it loadable at run time:

lrelease camelot.po

Don’t forget to post your new .po file on the mailing list, so it can be included in the next release.

For more background information, please have a look at the Babel Documentation

Where to put Translations

Translations can be put in 2 places :

  • in po files which have to be loaded at application startup
  • in the Translation table : this table is editable by the users via the Configuration menu. This is the place to put translations that should be editable by the users. At application startup, all records in this table related to the current language will be put in memory.

Loading translations

Translations are loaded when the application starts. To enforce the loading of the correct translation file, one should overwrite the camelot.admin.application_admin.ApplicationAdmin.get_translator() method. This method should return the proper QtCore.QTranslator object.

End user translations

Often it is convenient to let the end user create or update the translations of an application, this allows the end user to put a lot of domain knowledge into the application.

Therefore, all lazy translation strings can be translated by the end user. When the user right-clicks on a label in a form, he can select Change translation from the menu and update the current translation (for the current language). This effectively updates the content of the Translation table.

After some time the developer can take a copy of this table and decide to put these translations in po files.