# How to translate django applications?

Evgeny
11314 50 84 183

What are steps necessary to translate a django program into another language?

What good practices, gotchas, and common issues are there? Please feel free to add.

Here are the detailed instructions at the Django project site.

Note: askbot has user interface for translations - using django-rosetta application and you can test out your translations almost immediately (well, whithin 10 minutes or so - if things go well). Please help us translate!

delete close retag edit

Sort by » oldest newest most voted

Evgeny
11314 50 84 183

# How to prepare the translator's environment

This answer assumes that your application source code has already been prepared for the internationalization (askbot is) and explains how to prepare a file holding the translation messages. Ideally this file is the only thing that translator needs to touch in order to do his work.

There are two ways to get started, in either case you will have to type some stuff into the command line of your OS.

Let's assume you are translating to Russian and your operating system is Unix-like.

# Start from scratch or update an existing translation

By starting from scratch it is meant that you are not using any prepared localization for another language and instead you are just pulling the string keys from the project source files.

This method also works when source files get out of sync with your translation and you want to update it.

1. open the command shell in the directory that contains your settings.py file
2. type python manage.py makemessages -l ru -e html,py,txt

Note: the above command assumes that your translations are in the django site project directory, which is not always the case. For example, in askbot the localization files are inside the directory askbot, so in such cases the command will be:

cd askbot
python ../manage.py jinja2_makemessages -l ru -e html,py,txt


Notice the ../manage.py. Also, in askbot the message extraction command is customized, so it is called jinja2_makemessages instead of the django's makemessages.

The command above will create/update a file ./locale/ru/LC_MESSAGES/django.po - that file will be the main focus of your translation effort. .po files are meant to be edited by the translators. There are some format requirements to follow, but they are easier than those used in the source code and contain no programming logic.

If you are working on Windows, the command will start with python.exe, but will be the same otherwise. ru - is the language code (locale in computer parlance).

# Start from another language translation

This method is perfect if there is a good quality localization that you understand, and is the only sane way if application abbreviates the string keys.

All you need here is just copy the translation directory (say English - ./locale/en) and name it ./locale/ru:

 cd locale
cp -r en ru #copy the directories recursively
cd ..       #get back to the root of your django site


# What's next?

Now you have the ./locale/ru/LC_MESSAGES/django.po file. All that you need to do now is to translate those hundreds of messages into your language :).

Open the file in your favorite text editor and type away, but you will have to pay attention to some very specific issues - pluralization, insertion of variables and be careful with typing html tags into the translation strings.

It would be helpful if catalogue was collected with jinja2_makemessages --no-wrap. Different versions of rosetta break lines differently, which leads to chaos in version control system -- hard to see what really changed and where.

( 2011-12-20 01:30:56 -0500 )edit

SyntaxError: Translation blocks must not include other block tags: - endtrans (f ile skins\default\templates\email\macros.html, line 19) when I used jinja2_makemessages to translate some strings in Askbot.

( 2012-11-30 02:37:34 -0500 )edit

Evgeny
11314 50 84 183

# What is internationalization?

Internationalization includes two things (1) preparing of your software to be translated to other languages and (2) creating the translations themselves. Internationalization is long word and is abbreviated as i18n - because there are 18 characters between first i and last n.

The two step process makes life a lot easier for the programmers, designers of the user interface and the translators, because this way each can focus on his/her work without having to learn tricks of the trade of the others.

Evgeny
11314 50 84 183

# How to translate django.po files

First open file in the text editor (e.g. locale/ru/LC_MESSAGES/django.po)

In the simplest situation you will have lines like these:

#: django_authopenid/forms.py:162
msgid "Welcome to our website!"
msgstr ""


The string keys (translatable strings in the source code) are prefixed with msgid - you should never touch those (even if they look strange)! Your translations should go into strings starting with msgstr. If you do decide to change the key - instead of changing it in the django.po file do it in the source code and use command makemessages to rebuild the django.po file(s).

Strings themselves (both keys and translations) are always enclosed into double quotes. (If you need to use double quote inside the string itself - escape it with a backslash "string with a \" - double quote"). Backslash indicates start of the "escape sequence" - often indicating a special character \n means "new line" or an entry delimiter (double quote in this case).

So in the simple case above the Russian translation will look this way

msgid "Welcome to our website!"
msgstr "Добро пожаловать на наш сайт!"


In the previous example there was a line

#: django_authopenid/forms.py:162


This is a comment (because it starts with #) - do not delete or modify this type of comment as it tells where in the source code this message is coming from. You will use this comment when you decide to modify the translation key. The same string can be actually used in many places throughout the program and the comment will list all of them.

There is one case when you do need to edit comment - when you see line starting with

#, fuzzy


, fuzzy note indicates that the key string has been changed in the source file and the gettext system has guessed the meaning of the string. This comment is actually trying to help you locate strings that need your attention - so check the translation of those and then delete the , fuzzy part.

Make sure to never delete anything that might follow that comment on the same line. For example change:

#, fuzzy, python-format


to

#, python-format


Do not delete the whole line in this case. (However you can delete the whole comment if it contains only , fuzzy note).

# Translating strings with variables

Here is a simple example of a string with a variable (comments with line numbers are omitted):

#, python-format
msgid "see questions tagged '%(tag)s'"
msgstr ""


The key has %(tag)s - that's the most important part. It means that value of a variable named "tag" will be inserted into the string - by the program. Name of the variable is enclosed into parentheses () and preceded by %; s right after the closing parenthesis ) means that variable is of string type. Finally, comment #, python-format instructs the gettext system that this translation is prepared for a program written in python programming language.

Here is how translation might look like:

#, python-format
msgid "see questions tagged '%(tag)s'"
msgstr "вопросы по темам '%(tag)s'"


Variable names are never translated. Also format of the variable entry must be preserved.

Note: even though in this case names of tags will be listed in the end of the string both in English and Russian, the variable in the translation may be moved around and even may be inserted more than once.

Gettext system has a convention that if a key starts with a newline - then translations also must start with the new line.

Some entries will look like

msgid ""
"\n"
"some text"
msgstr ""


In this case key string starts with a new line - how can you tell that is explained below.

First, the key string is split into three: "", "\n" and "some text". \n - means "new line" - that is there is a line break. The first string is empty - therefore \n (newline) is the first character in the whole key.

msgid ""
"\n"
"some text"
msgstr ""
"\n"
"немного текста"


First "" is not really necessary in the translation as long as the the first character in the translation is \n. If you omit the newline character there will be an error message when you try compiling .po files.

Evgeny
11314 50 84 183

# How to compile translations?

If you have finished translating the content of your .po file - all you need to do is to compile the messages into machine-readable binary form. Run:

cd askbot
python ../manage.py compilemessages


If all goes well - your translation is ready for use, otherwise - fix any errors in the .po file and rerun the command.

Finally, if you have not done it yet - adjust the value of LANGUAGE_CODE variable to 'ru' in the case above.

"python ../manage.py compilemessages" returned an error on my system (CentOS). I had to install "gettext". ("apt-get install gettext" or "yum install gettext"). You might want to put that information somewhere.  ( 2011-06-25 01:41:48 -0500 )edit

On mac: "brew install gettext" followed by "brew link gettext"

( 2013-03-20 14:34:16 -0500 )edit

petteri
1 1

What you could try is Get Localization and https://github.com/getlocalization/django-getlocalization">django-getlocalization to sync your Django app's .po files with GL easily.

[hide preview]