Django and internationalization (i18n)

Turning on i18n for your Django project is straightforward. If you build your project with support for internationalization from the beginning, you can save a lot of time and effort chasing down strings that need to be marked for translation.

The first step is to ensure that USE_I18N is set to True. You can find USE_I18N in your settings file, the .py file specified by DJANGO_SETTINGS_MODULE. This variable is set to true by default.

USE_I18N = True

I’ll describe the rest of the process using French as our target translated language. I’m going to set LANGUAGE_CODE to French in my settings file now.

LANGUAGE_CODE = 'fr'

After this is done, I’ll use a terminal to navigate to the project’s root, the directory in which manage.py resides. A directory named conf/locale needs to exist here.

> mkdir conf
> mkdir conf/locale

Django comes with a few built-in command line tools for processing language strings. I’ll use them now to initialize the project for i18n.

> django-admin.py makemessages -a -l fr -v3
examining files with the extensions: .html and .txt
processing language fr
ignoring directory .git
ignoring file .gitignore in .
processing file README.txt in .
processing file manage.py in .
processing file tutorial.db in .
processing file __init__.py in ./tutorial
processing file urls.py in ./tutorial
processing file views.py in ./tutorial
processing file wsgi.py in ./tutorial
...

> django-admin compilemessages
processing file django.po in /Users/jon/dev/web/django/tutorial/conf/locale/fr/LC_MESSAGES

Those commands created a directory structure and files under conf/locale, as you can see in the last output message. The first command – makemessages – combs through all of the available files, searching for either strings marked for translation in Django template files:

{% trans 'A string to be translated' %}

or strings marked for translation in source code itself. This is done using the ugettext function, which is commonly imported as _ to save time and typing.

from django.utils.translation import ugettext as _

def i18n(request):
    context = RequestContext(request)
    activate('de')
    
    text1 = _('ENGLISH - Translate This 1')
    text2 = _('ENGLISH - Translate This 2')
   
    return render_to_response('i18n.html', {'text1' : text1, 'text2' : text2})

A file named conf/locale/fr/LC_MESSAGES/django.po is created, containing pairs of strings like this:

#: example/views.py:16
msgid "ENGLISH - Translate This 1"
msgstr ""

#: example/views.py:17
msgid "ENGLISH - Translate This 2"
msgstr ""

These strings refer to strings marked for translation found in the example/views.py in my example project. I need to manually provide translations for these strings.

#: example/views.py:16
msgid "ENGLISH - Translate This 1"
msgstr "FRENCH - Translated 1"

#: example/views.py:17
msgid "ENGLISH - Translate This 2"
msgstr "FRENCH - Translated 2"

Run compilemessages:

> django-admin compilemessages
processing file django.po in /Users/jon/dev/web/django/tutorial/conf/locale/fr/LC_MESSAGES

When I reload the i18n view outlined above, I’ll see that the strings are mapped to their “French” translations automatically.

Note: it might be necessary to set the LOCALE_PATHS variable in your settings. Mine is set to:

LOCALE_PATHS = (
    '/Users/jon/dev/web/django/tutorial/conf/locale/',
)
Tagged with: , , , , ,