Software localization
A Quick Guide to Django i18n
Translating your web application to different languages and adding proper localization is something we all should do! This tutorial will give you a short introduction on how to get started with the Django localization process. Part of this can be easily applied to general Python localization and we also show you how you can speed up your i18n workflow even more by using Phrase.
We assume, that you have a working Django application and that you have installed gettext (for example via pip install gettext
). If you havn’t used Django before, you maybe want to take a look at the official tutorial first and come back later.
Basic setup
So let’s suppose you have a Django project called mysite
and an application called polls
. The structure of your project should be looking something like
/ manage.py mysite/ __init__.py settings.py urls.py wsgi.py polls/ migrations/ __init__.py admin.py models.py tests.py views.py
The first step is to make sure that you have activated internationalization in your configuration. To do this, you have to make the following changes to mysite/settings.py
:
# mysite/settings.py LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True
Internationalize templates
Then you have to mark all strings which have to be translated. Suppose you have the following template file polls/templates/polls/index.html
<!-- polls/templates/polls/index.html --> <h1>Welcome to our site!</h1> <p>Here you find polls.</p>
This file needs to be adapted to look like this
<!-- polls/templates/polls/index.html --> {% load i18n %} <h1>{% trans 'WelcomeHeading' %}</h1> <p>{% trans 'WelcomeMessage' %}</p>
so we import the localization package and replace all texts with trans 'SomeTranslationKeyName'
. Alternatively, you can use the default translation text as the translation key. This way, you will always have a good default text, if there is no translation available for the peticular key.
🗒 Note » There are actually two different Django templates you might run into here. Learn about the difference between _() and {% trans %} in Django templates.
Internationalize inside Python code
When you want to localize strings within your python code (for example inside polls/views.py
), you need to import the ugettext
function. It is normal to alias it to _
. So a simple localized view function would look like this
# polls/views.py from django.http import HttpResponse from django.utils.translation import ugettext as _ def index(request): output = _('StatusMsg') return HttpResponse(output)
Create translation files
Now we have to create the translation files for every locale, we want to support. To do this create the directory polls/locale
and inside the directory polls
run
$ django-admin makemessage -l de
where you can replace de
with the locale code of the language you like to add. In our example, this command will create the gettext file polls/locale/de/LC_MESSAGES/django.po
with the content
# polls/locale/de/LC_MESSAGES/django.po ... #: templates/polls/index.html:3 msgid "WelcomeHeading" msgstr "" #: templates/polls/index.html:4 msgid "WelcomeMessage" msgstr ""
and you can fill in the translations:
# polls/locale/de/LC_MESSAGES/django.po ... #: templates/polls/index.html:3 msgid "WelcomeHeading" msgstr "Willkommen auf unserer Seite!" #: templates/polls/index.html:4 msgid "WelcomeMessage" msgstr "Hier findet Ihr Umfragen."
When you have finished translating, you have to compile everything by running
$ django-admin compilemessages
again inside the directory polls
.
To quickly check that your translations work, you have to change the language code inside mysite/settings.py
like so
# mysite/settings.py LANGUAGE_CODE = 'de'
When you open the polls application inside the browser, it should now be translated to German.
Speed up your process using Phrase
If you are using Phrase to manage your translations, you actually don’t need to manually create and edit the *.po
files! You just have to create and translate the keys WelcomeHeading
and WelcomeMessage
within Phrase and use the export function to download your *.po
files.
If you have installed our command line tool, the Phrase client, your workflow is even simpler. Just create a configuration file .phraseapp.yml
within your project’s root directory with the following content:
# .phraseapp.yml phraseapp: access_token: <your access token> project_id: <your project's id on PhraseApp> file_format: po pull: targets: file: "polls/locale/<locale_code>/LC_MESSAGES/django.po
Then running
$ phraseapp pull && django-admin compilemessages
in the root directory of your project will update all translations in your project.
By the way, using Phrase's in-context editor within your Django application is also really simple! You only need to install django-phrase
with pip
:
$ pip install django-phrase
Then just change all templates you like to use the in-context-editor on, in the following way
<!-- polls/templates/polls/index.html --> {% load i18n %} {% load phrase_i18n %} {% phrase_javascript %} <h1>{% trans 'WelcomeHeading' %}</h1> <p>{% trans 'WelcomeMessage' %}</p>
🗒 Note » It is important to load phrase_i18n
after i18n
.
Finally add the following lines to your configuration and you are ready to go!
# mysite/settings.py PHRASE_ENABLED = True PHRASE_PROJECT_ID = 'YOUR_PROJECT_ID' PHRASE_PREFIX = '{{__' PHRASE_SUFFIX = '__}}'
Select locales
One usually wants to select the locale according to the user’s browser settings. In order to do this you have to change the mysite/settings.py
file to the following
# mysite/settings.py from django.utils.translation import ugettext_lazy as _ ... MIDDLEWARE_CLASSES = ( ..., 'django.middleware.locale.LocaleMiddleware', ..., ) ... LANGUAGE_CODE = 'en-us' LANGUAGES = ( ('en-us', _('English')), ('de', _('German')), )
This way, if the user has German as their locale, they will see the de
translations. Otherwise, the default locale will be en-us
. You can check that this is working properly with curl:
$ curl http://localhost:8000/polls -H "Accept-Language: de"
which should return something like this
<h1>Willkommen auf unserer Seite!</h1> <p>Hier findet Ihr Umfragen.</p>
Keep exploring
If you want to learn more about internationalization in Django, the official documentation is always a good place to start. We also warmly recommend the following Django translation tutorial.
If you're curious about how you can set up the Phrase in-context editor within your Django application, take a look at the Phrase documentation. You can also find the full sources of the demo application we used in this tutorial on GitHub.
Want to learn more about localization and internationalization in other web frameworks for Python? Check out the following tutorials: