Internationalization

An introduction to translatable strings.

>>> from lino import startup
>>> startup('lino_book.projects.docs.settings.demo')
>>> from lino.api.shell import *

Django uses the gettext system for providing internationalization.

In your application code, you import Django's ugettext() function (usually aliased as _()) and call it on any string that you want the user to see in their language.

>>> from django.utils.translation import ugettext as _

If no language is activated, ugettext() just returns the English text:

>>> print(_("January"))
January

In Lino we usually use the translation.override() context when we want to translate:

>>> from django.utils import translation
>>> with translation.override('fr'):
...     print(_("January"))
janvier

How does the ugettext() function know that "January" is "janvier" in French? See inv mm.

Note that ugettext() will do the lookup in-place. The following code prints English and not German:

>>> s = _("January")
>>> with translation.override('de'):
...     print(s)
January

But Django has a lazy version of ugettext()

>>> from django.utils.translation import ugettext_lazy as _
>>> s = _("January")
>>> with translation.override('de'):
...     print(str(s))
Januar

This is also the version you get when you say:

from lino.api import _

A lazy translation returned by ugettext_lazy() is actually not a string, it is rather an object that will be translated when needed.

>>> from django.utils.translation import ugettext_lazy
>>> from django.utils.translation import ugettext
>>> ugettext("January").__class__
<class 'str'>
>>> ugettext_lazy("January").__class__
<class 'django.utils.functional.lazy.<locals>.__proxy__'>