Django Internationalization Translation in templates


To enable translation in templates you must load the i18n library.

{% load i18n %}

Basic translation is made with the trans template tag.

{% trans "Some translatable text" %}
{# equivalent to python `ugettext("Some translatable text")` #}

The trans template tag supports context:

{% trans "May" context "month" %}
{# equivalent to python `pgettext("May", "month")` #}

To include placeholders in your translation string, as in:

_("My name is {first_name} {last_name}").format(first_name="John", last_name="Doe")

You will have to use the blocktrans template tag:

{% blocktrans with first_name="John" last_name="Doe" %}
  My name is {{ first_name }} {{ last_name }}
{% endblocktrans %}

Of course instead of "John" and "Doe" you can have variables and filters:

{% blocktrans with first_name=user.first_name last_name=user.last_name|title %}
  My name is {{ first_name }} {{ last_name }}
{% endblocktrans %}

If first_name and last_name are already in your context, you can even omit the with clause:

{% blocktrans %}My name is {{ first_name }} {{ last_name }}{% endblocktrans %}

However, only "top-level" context variables can be use. This will NOT work:

{% blocktrans %}
    My name is {{ user.first_name }} {{ user.last_name }}
{% endblocktrans %}

This is mainly because the variable name is used as placeholder in translation files.

The blocktrans template tag also accepts pluralization.

{% blocktrans count nb=users|length }}
    There is {{ nb }} user.
{% plural %}
    There are {{ nb }} users.
{% endblocktrans %}

Finally, regardless of the i18n library, you can pass translatable strings to template tags using the _("") syntax.

{{ site_name|default:_("It works!") }}
{% firstof var1 var2 _("translatable fallback") %}

This is some magic built-in django template system to mimic a function call syntax but this ain't a function call. _("It works!") passed to the default template tag as a string '_("It works!")' which is then parsed a translatable string, just as name would be parsed as a variable and "name" would be parsed as a string.