.. doctest docs/dev/i18n.rst 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 :func:`ugettext` function (usually aliased as :func:`_`) 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, :func:`ugettext` just returns the English text: >>> print(_("January")) January In Lino we usually use the :func:`translation.override` context when we want to translate: >>> from django.utils import translation >>> with translation.override('fr'): ... print(_("January")) janvier How does the :func:`ugettext` function know that "January" is "janvier" in French? See :cmd:`inv mm` and :ref:`dev.translate`. Note that :func:`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 :func:`ugettext`, which does the lookup only when it is really needed. >>> 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 :func:`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__ >>> ugettext_lazy("January").__class__ .__proxy__'>