1

I need to implement internationalization in my project, so i want to use i18n for static content while i use the app django-modeltranslation for the models. I support the following languages:

en-us (default) nl-nl de-de fr-fr es-es

While i am dutch, django does not change to language to dutch. I do have a english windows but chrome is set up dutch to test the internationalization. This is not the only problem, only the model translates itself when the default language changes. When i set the default language to dutch, all models will show the dutch translation but the static content stays english.

Note: I did use compilemessages and restarted the server

Settings.py

USE_I18N = True

LANGUAGE_CODE = 'en-us'

gettext = lambda s: s
LANGUAGES = (
    ('en-us', gettext('English')),
    ('nl-nl', gettext('Dutch')),
    ('fr-fr', gettext('French')),
    ('de-de', gettext('German')),
    ('es-es', gettext('Spain')),
)

LOCALE_PATHS = ('/vagrant/locale', )

/vagrant/locale/en-us/LC_MESSAGES/django.po (shortened file to display error)

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-05-17 23:14+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Language: en-us\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: PyDiving/settings.py:170
msgid "English"
msgstr ""

#: PyDiving/settings.py:171
msgid "Dutch"
msgstr ""

#: PyDiving/settings.py:172
msgid "French"
msgstr ""

#: PyDiving/settings.py:173
msgid "German"
msgstr ""

#: PyDiving/settings.py:174
msgid "Spain"
msgstr ""

#: company/templates/company/company_detail.html:22
msgid "City"
msgstr ""

/vagrant/locale/nl-nl/LC_MESSAGES/django.po (only showing differences to shorten post)

"Language: nl-nl\n"

#: company/templates/company/company_detail.html:28
msgid "Postal Code"
msgstr "Postcode"

#: company/templates/company/company_detail.html:34
msgid "City"
msgstr "Stad"

Template company/templates/company/company_detail.html

{% load i18n %}
{{ company.text }} # this is the model translation, this will change when i change the default language
{% trans "City" %} # this always says "City"

Outcome when default language is en-us

EnglishCity

where 'English is the content of the model'

default language nl-nl

NederlandsCity
LHolleman
  • 2,486
  • 2
  • 18
  • 19
  • Are you using `django.middleware.locale.LocaleMiddleware`? Can you output `request.LANGUAGE_CODE` in your template to make sure the correct language is set? – Bernhard Vallant May 22 '13 at 22:54
  • For some reason, when i add LocaleMiddleware (which i didn't use because i read it is for setting languages instead of recognizing) it changes the models to display spanish (es-es). It 'succesfully' recognizes a language because i can change the default code, but request.LANGUAGE_CODE still says it's es-es, which is not true. Im in the netherlands with a dutch ip/chrome and an english windows. The language files however, stay english. I checked the spanish language files and it is the same as the english/dutch one. – LHolleman May 23 '13 at 09:06
  • Normally you should need `LocaleMiddleware` in any case... Can you check in Chrome's Web Inspector what you browser sends for `Accept-Language` (in the Network tab... choose your document and look at request headers) – Bernhard Vallant May 23 '13 at 09:37
  • 1
    Also check if you have the needed locales on your machine: `locale -a`. – Bernhard Vallant May 23 '13 at 09:39
  • Probably django doesn't find the mo file. Could you detail the structure of your project on the filesystem ? file paths etc ... – jpic May 23 '13 at 09:57
  • My chrome headers http://pastie.org/7947352. It is unlikely that django can't find my language files, i can compile them without any problem http://pastie.org/7947368. I also got the needed locales on my machine – LHolleman May 23 '13 at 11:31
  • You've read this right https://docs.djangoproject.com/en/dev/topics/i18n/translation/#how-django-discovers-language-preference? – Adrián May 23 '13 at 14:28
  • 1
    Is your `LocaleMiddleware` placed _after_ `SessionMiddleware` and _before_ `CommonMiddleware`? – Hedde van der Heide May 23 '13 at 14:47
  • Yes i did read that, checked everything, it was right. @Hedde, this is included in the post that adrian made – LHolleman May 23 '13 at 14:58

3 Answers3

2

I've found different platforms allow/prefer different language folder names. I was pulling my hair out on my development system (Mac OS X) because '/pt-br/LC_MESSAGES/' wouldn't work, even though makemessages created the folders that way and compile messages worked fine too. It finally sprang to life once I renamed the languages as '/pt_br/LC_MESSAGES/' (notice the underscore). Note my LANGUAGES tuple in settings uses the aa-bb form, just as you're using here.

Migrating the same project to production (Ubuntu), it stopped working again, I tried everything under the Sun thinking the folder names must already be correct since they work on my dev. machine. I finally, out of desperation tried uppercasing the country component like '/pt_BR/LC_MESSAGES/', and, boom, it started working again. I find that using the aa_BB form works universally.

So, the solution I think you're looking for is to change the names of the locale directories inside your locale folder. You should have:

[project]
    locale
        de_DE
        en_US
        es_ES
        fr_FR
        nl_NL
    ...
    settings.py

Inside each you'll have the LC_MESSAGES, etc. as normal of course. Your Django configuration shouldn't change, this is just what gettext accepts on your platform. Again, I think if you use the aa_BB form, you'll be fine on most systems.

If you need your locale folder in some other location for some reason, just make sure that you set the property settings.LOCALE_PATHS accordingly. Also, the Django documentation makes it clear how it finds this folder: https://docs.djangoproject.com/en/dev/topics/i18n/translation/#how-django-discovers-translations.

mkoistinen
  • 7,724
  • 3
  • 41
  • 56
1

I know it's been more than a year since this question has been answered, but i've ran into a similar problem and after many hours trying to figure out, i've finally come to a deterministic anwser.

Disclaimer: i'm using pt-br because is my mother language, but you can derive this to any language you want

First, what did i do on my django application (assuming you already have created project and app[s] and the current directory is the project dir):

  • created locale dir: mkdir locale
  • created a pt_BR locale: django-admin.py makemessages -l pt_BR
  • changed the text inside the created file
  • compiled all messages: django-admin.py compilemessages
  • added LOCALE_PATHS variable to django settings: LOCALE_PATHS =('/path/to/locale_foder',)

After this, my Django app was never being translated. No matter what i did...

According to django documentation (https://docs.djangoproject.com/en/dev/topics/i18n/translation/#how-django-discovers-language-preference) django has a predefined way to find language preferences, and this is how it works:

  1. django search for the language prefix in the url, for this to work you must be using i18n_patterns in django url.
  2. if the above fails, search for a variable in user session
  3. if the above fails, search for a cookie
  4. if the above fails, use the Accept-Language HTTP header
  5. if the above fails, use the language specified in homonymous variable in django settings.

I've highlighted number 4 because, in my case, that's the one i'm using. This means my application is dependent on HTTP browser data.

Now, since we are dependent on HTTP data, let's check how the browser behaves. I mainly use chrome and firefox. My chrome has the following language settings on my notebook:

  • pt
  • en-us
  • en

And that is the problem, my Accept-Language HTTP header is sending pt, but i do not have pt locale, i only have a pt-br locale. If it was the other way around, this would work. My conclusion is that one should always have the iso 639-1 codes, and from there use specialisation. For example: i'm now using pt as default for pt-br, and pt-pt for Portugal specific translations.

0

I came across this post: Django internationalization language codes. Apparently, django only supports iso 639-1 language codes, which is not to be found in the documentation, even worse, it says you have to use codes like en-us. As soon as i changed the languages to en-us > en, nl-nl > nl etc. it worked immediately.

Anyway, thanks for the attention.

Community
  • 1
  • 1
LHolleman
  • 2,486
  • 2
  • 18
  • 19
  • 1
    It's explained [here](https://docs.djangoproject.com/en/dev/topics/i18n/#term-locale-name) and it does say that it supports contry specific transltations :/ – Adrián May 24 '13 at 15:50
  • I see that the pages are linked now, read it wrong, my bad. Post it and i will accept it. – LHolleman May 24 '13 at 17:41
  • I would post it, but it doesn't really answer the question. I still don't know why it didn't work and now, after changing 'en-us' to just 'en', it does. According to the docs, 'en-us' is valid. – Adrián May 24 '13 at 17:51
  • Hmm, that is true. Now that i checked it, nl-nl is a valid code also. – LHolleman May 24 '13 at 17:58
  • 'en-us' it's even the given example for the [LANGUAGE_CODE](https://docs.djangoproject.com/en/dev/ref/settings/#language-code) setting. – Adrián May 24 '13 at 17:59
  • Yes, according to the documentation and my Accept-Language header it should display english while the LANGUAGE_CODE is something else. – LHolleman May 24 '13 at 18:05
  • See here, [this](https://github.com/django/django/blob/master/django/conf/global_settings.py) is the list of languages in which django itself is translated. – Adrián May 24 '13 at 18:06
  • And if you specified for example, 'en-gb' and it wasn't one of the list. It is supposed to fallback to general english 'en', I think. – Adrián May 24 '13 at 18:09
  • Umm, it worked for you only because you lopped-off the regional parts of the languages. To fix the problem that you stated in your original question, leave the language codes as Django expects them, and change the language FOLDERS under /locale/ as gettext expects them, as I posted in my answer. – mkoistinen May 29 '13 at 01:45