================================== 20130323 (Saturday, 23 March 2013) ================================== Extract messages using Babel instead of Django ---------------------------------------------- Cool! Today I replaced the sophisticated and intransparent system for handling internationalization (which used only Django's builtin possibilities and needed :srcref:`/Makefile`) by a transparent and easy-to-use system using Babel_ (and Jinja's `Babel Integration `__). .. _Babel: http://babel.edgewall.org/wiki/Documentation/setup.html The configuration is in :srcref:`/lino/setup_info.py`:: SETUP_INFO.update(message_extractors = { 'lino': [ ('**/sandbox/**', 'ignore', None), ('**/cache/**', 'ignore', None), ('**.py', 'python', None), ('**.js', 'javascript', None), ('**/templates_jinja/**.html', 'jinja2', None), ], }) The raw commands to issue (supposing locale "de" ) are:: setup.py extract_messages -o lino/locale/django.pot setup.py init_catalog --domain django -d lino/locale -l de -i lino/locale/django.pot setup.py update_catalog --domain django -d lino/locale -l de -i lino/locale/django.pot setup.py compile_catalog --domain django -d lino/locale -l de A first nice surprise is the following message: SyntaxError: python refuses to compile code with both a UTF8 byte-order-mark and a magic encoding comment There were indeed a few files with this problem (which had never occured on my machine, though, and I'm not going to research why). One fundamental difference is: until now I had a lot of `locale` directories (one for each app), but I'm going to have now a single one in :srcref:`/lino/locale`. Because that simplifies everything a lot! Except that I'll need to find out how to recover the existing translations. Here is the Windows shell command used to get a list of the German ones:: T:\hgwork\lino>dir /s django.po /b | grep de\\ Another little difference: Django's makemessages command automatically removed the .pot files, I am going to leave the :srcref:`/lino/locale/django.pot` file hanging around. The above commands are now fully implemented in :mod:`djangosite.utils.fablib` as:: fab em fab im fab um fab cm While converting lino_welfare to the new system I noticed that I can now finally also put the central things like the settings.py file, demo fixtures and django-admin commands to where they belong (to the top-level directory) I used the occasion to split the central parts of :mod:`lino_welfare.modlib.pcsw.models` into a new module :mod:`lino_welfare.models`. :class:`north.north_site.Site` now does the same for `LOCALE_PATHS` as for `FIXTURE_DIRS`: it extends Django's automatic discovery system by searching also for "locale" subdirectories relative to any Python module that defines a subclass of :class:`north.north_site.Site` (usually a :file:`settings.py` file) and which are *not* part of an app (in which case a locale directory should not be mentioned there because Django already searches them, as explained in `How Django discovers translations `_). One "detail" causes still headache: Babel_ doesn't seem to support message contexts, at least it doesn't extract them using `pgettext` instead of `gettext`. A ticket `278 `_ mentioned this, but it has been closed as duplicate of `277 `_ which afaics doesn't speak at all about pgettext. An example of where this causes problem is the German male salutation "Herr" or "Herrn": both salutations are "Mr" in English, but in German there are two cases. Lino provides some utility functions for this, see :ref:`lino.tutorial.human`. This is done using pgettext (see source code at :srcref:`/lino/mixins/human.py`), but Babel seems to simply ignore these. It does read the file:: ... extracting messages from lino\mixins\human.py ... UPDATE: What a funny coincidence! The last post in Babel's mailinglist was exactly about this problem, and it told me that Babel *can* do pgettext, but they just didn't yet release it officially! Tried with a checkout of the latest trunk version (which is not completely trivial but `there are clear instructions `_): yes, that works. Only remaining problem is that I'd prefer to use a released version on my customer's site. To trust or not to trust? ------------------------- Before releasing yesterdays new "textfield templates are now parsed using Jinja" feature to :ref:`lf`, I'd rather add the new attribute :attr:`lino.ui.Site.trusted_templates` which is False by default. So sorry, you cannot see this feature in our live demos.