Welcome | Get started | Dive into Lino | Contribute | Reference

Internationalization

An introduction to translatable strings.

>>> from lino import startup
>>> startup('lino_book.projects.min9.settings')
>>> 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 gettext 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 and How to contribute translations.

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(), which does the lookup only when it is really needed.

>>> from django.utils.translation import gettext_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 gettext_lazy
>>> from django.utils.translation import gettext
>>> gettext("January").__class__
<class 'str'>
>>> gettext_lazy("January").__class__
<class 'django.utils.functional.lazy.<locals>.__proxy__'>