Note: this tutorial assumes that you have some basic understanding of Django terminology and folder/file structure.

I recently started learning the Django Python framework. So far I really like it. Recently I found out how to quickly bootstrap translation for your application to different languages. On of the things that amazed me about the Django platform, that it will automatically load the correct translation file based on the browser language. I’ve quite a lot of experience developing applications using Yii and Laravel and I’ve never seen such a feature before in a framework. Let’s get started with enabling this awesome feature for your project.

Step by step instructions

Step 1: make sure internationalization is turned on

Open the settings.py file of your project and look for the USE_I18N setting. The value of this setting should be like this:

USE_I18N = True

If you can’t find this setting, please create this variable manually.

(I18N is a common abbreviation of the word internationalization)

Step 2: make the translation function available to settings.py

It my come in handy to have translated strings in your settings. For example for error messages or e-mail templates. Add the following to the top of your settings.py :

from django.utils.translation import ugettext_lazy as _

You can now use the _() function in settings.py. This function will translate your strings. For example: DEFAULT_ERROR_MESSAGE = _("An error has occurred") .

Step 3: define a default language

Django uses lowercase ISO 639 codes for languages. For example the English language gets the code en. If you want to differentiate between British or American English, use en-gb and en-us. In settings.py you set a fallback language like this:

LANGUAGE_CODE = 'en'

When a French user visits your application and you only have an English and German translation, the English version will be loaded.

Step 4: define the languages you want to support

If I want my application to be available in Dutch and English, I add the following list to settings.py :

LANGUAGES = (

('en', _('English')),

('nl', _('Dutch')),

)

Because we earlier loaded the _() function, the language labels will also be properly translated.

Step 5: use the translation function in your templates

To be able to use translations in your templates, you need to load the i18n tag in all your views. This will give you the trans function. For example if I want to create a login form that has button with “Login with Facebook”, I would create the following code:

{% extends 'frontend/base.html' %}

{% load i18n %}

{% block content %}

<form>

<button class="button-facebook">{% trans "Login with Facebook" %}</button>

</form>

{% endblock %}

The trans function takes a string and will try to look for a translation. If no translation can be found, the input string will be rendered. Since we haven’t created a translation yet and English is the fallback language, the button will say “Login with Facebook”.

Step 6: create a folder for the language strings

The standard Django convention is to create a folder called locale in the root of your Django project, not your app. Afterwards you need to make this file known to the Django translation functions. You do this by adding the directory to the LOCALE_PATHS setting:

LOCALE_PATHS = (

os.path.join(BASE_DIR, 'locale'),

)

Step 7: let Django generate all the needed files and folders

Django uses the GNU gettext format for storing translations. Gettext stores all the strings in a file and compiles this file to a binary. Gettext is also used by Wordpress. You can edit the gettext po files with any editor, but I prefer a program called Poedit.

To generate the po files for your project, you can use the django-admin command. For example I’m Dutch and would like to start translating my project, so I execute the following command:

django-admin.py makemessages -a

This will take all the languages defined in the LANGUAGES setting from step 4 and generates a django.po file for each language in the locale folder.

Step 8: open the django.po file with an editor

When you open the django.po file for your locale, you see something like this:

#: sample/settings.py:128

msgid "English"

msgstr ""



#: sample/settings.py:129

msgid "Dutch"

msgstr ""



#: templates/frontend/main/index.html:11 templates/frontend/main/login.html:5

msgid "Login with Facebook"

msgstr ""

This is the earlier mentioned gettext format. Django will automatically look for all usages of the _ or trans function in your project and them in this file. In the field msgstr you can set a translation for the particular string. Like I said earlier, I prefer to use Poedit for a graphic interface:

Poedit provides a nice interface for handeling .po files and also syncs all translations users make to a huge database. This means you can get autocomplete options for common strings

After editing the django.po file, save it.

Step 9: compile the po files

To able to use a PO file in an application, it needs to be compiled to the binary MO file format. Poedit has a built-in option for this, but you can also use the django-admin toolbox. Run this command to compile all your po files at once:

django-admin compilemessages

Step 10: check the result

Spin up a local dev server and open your browser. If you have done everything correctly, your strings should display in your native language.

From now own you should follow this steps to add new translation strings:

make sure the i18n tag is loaded in your view use the trans function and write a (preferabele English)sentence in your view. use the makemessages command to update your po files. Edit and translate the po files. Compile the po into mo files

Conclusion

I hope that after reading this article, you have a basic understanding of translating a Django app. Django also provides a way to set the language with url paramaters as noted in the official documentation. For another good implementation example, check out this Github repository.

If you like this content, please share it with other people :) For more content or I want to say something, please contact me on Twitter: