{% trans "string" %} not working on templates but {% trans variable %} does

I ran into a similar problem and was able to resolve it by setting LOCALE_PATHS in my settings file. LOCALE_PATHS is a tuple of directory paths where django looks for .mo and .po files. Here's an example:

# settings.py
LOCALE_PATHS = (
    '/path/to/your/project/locale',
)

Read django's official documentation on LOCALE_PATHS for more information.


Have you manually translated the string in the .po ?

makemessages just adds "carro" to the .po, generating something like this in the .po file

#: idioma.html:45
msgid "carro"
msgstr ""

and then you have to edit the .po manually adding the translation for that string, in this way:

#: idioma.html:45
msgid "carro"
msgstr "car"

Then, when you are done translating all the .po strings, you can run compilemessages: it will compile your translations.

Note: always remember to look for ,fuzzy translations. If you have something like this in your .po

#: idioma.html:45
#, fuzzy
msgid "carro"
msgstr "car"

That means that django, for some reason, tried to translate the string by itself (it usually happens when you already used that string in a piece of code that you aren't using anymore).

You have to review the translation and delete the #, fuzzy line: any translation tagged with #, fuzzy won't be translated in your pages.


In some cases {% trans "your string " %} doesn't work.

I recommend you to use blocktrans instead of trans for strings.

How to use blocktrans:

{% blocktrans %} your string {% endblocktrans %}

I tracked the code whole night and found some clues. Mainly in trans_real.py and gettext.py. You can put a breakpoint in "translation" function.

  1. The translation code are executed only once when app starts. So you need to reload the uwsgi to load the new version.
  2. Po file is never used. gettext.py use "mo" file only.(in my laptop). So you have to compile messages after changing.
  3. The "-" in the language code will be converted to "_" in locale path. For example "zh-CN" will be converted to "zh_CN". That's why the translation file cannot be found. I think it will be better if just using two characters as the language code. And the case sensitive should be considered in Linux system.