1

Having trouble getting any of my translation files after compilemessages to take effect.

Digging into the code I came to:

django.utils.translation.trans_real.check_for_language

def check_for_language(lang_code):
    # First, a quick check to make sure lang_code is well-formed (#21458)
    if not language_code_re.search(lang_code):
        return False
    for path in all_locale_paths():
        if gettext_module.find('django', path, [to_locale(lang_code)]) is not None:
            return True
    return False

Which makes use of:

django.utils.translation.trans_real.all_locale_paths

def all_locale_paths():
    from django.conf import settings
    globalpath = os.path.join(
        os.path.dirname(upath(sys.modules[settings.__module__].__file__)), 'locale')
    return [globalpath] + list(settings.LOCALE_PATHS)

Which returns:

[
  u'/data/.venv/mysite/local/lib/python2.7/site-packages/django/conf/locale',
  '/data/www/locale/'
]

This is such core code, tested probably a million times, I'm sure I'm configuring wrong, but I can't really see any way that my LOCALE_PATHS will ever take precedence?

/data/www/locale/ content

/data/www/locale/
|-- en-us
|   `-- LC_MESSAGES
|       |-- django.mo
|       `-- django.po
|-- zh-hans
|   `-- LC_MESSAGES
|       |-- django.mo
|       `-- django.po
`-- zh-hant
    `-- LC_MESSAGES
        |-- django.mo
        `-- django.po

settings.py

LANGUAGES_DICT = {
    'en-us': _('English'),
    'zh-hant': _('Traditional Chinese'),
    'zh-hans': _('Simplified Chinese'),
}
LANGUAGES = LANGUAGES_DICT.items()

BASE_DIR = os.path.dirname(os.path.dirname(__file__))
path = lambda *a: os.path.join(BASE_DIR, *a)
LOCALE_PATHS = (
    path(u'locale'),
)
# Outputs: (u'/data/www/locale',)
DanH
  • 5,498
  • 4
  • 49
  • 72
  • From the looks of `check_for_language()` function however it appears to only look for the first valid path and then returns True? Would this not prevent all subsequent language files from being loaded? I'm not attempting to override Django's default at this time though. – DanH Apr 20 '15 at 16:29
  • @sthzg Ahh right, running out of patience totally misreading everything :) I'll update the question with my current config and structure – DanH Apr 21 '15 at 12:26
  • @sthzg Sure, thanks! Changed to unicode however no change. Updated OP with `LANGUAGES` and `LOCALE_PATHS`. – DanH Apr 21 '15 at 12:57
  • Oops, there I go again, I'm calling `LANGUAGES = LANGUAGES_DICT.items()` afterwards, updated OP – DanH Apr 21 '15 at 13:10
  • @sthzg Ok tried changing the keys in `LANGUAGES_DICT` and now I'm getting `u'Unknown language code zh_hans.'` from `{% get_language_info_list for LANGUAGES as languages %}` as per the language switcher code at https://docs.djangoproject.com/en/1.7/topics/i18n/translation/#the-set-language-redirect-view – DanH Apr 21 '15 at 14:20
  • could you verify that by changing the setting back to use hyphens but renaming the translation directories to be separated by underscores the translations show correctly? – sthzg Apr 21 '15 at 14:21
  • Just did, back to normal no error, but no translations. Maybe worth mentioning, other translation strings that are part of django core are translated, such as "Home" -> "首頁" – DanH Apr 21 '15 at 14:23
  • Hm strange, I tried to set it up exactly as you. When I rename the directory in my locale path to `zh_hans` at least in admin it shows me translated values ([Screenshot](http://snag.gy/Wtf4H.jpg)). Bambazes and Foobar is the same model and results from the translated `verbose_name`. Only thing I had to do is to append the locale dir to the python path, but I assume you did that already because otherwise `makemigrations` would complain. – sthzg Apr 21 '15 at 14:39
  • Were you able to find the problems with the translations? Is yes I'd be interested since I have the feeling that one can't be aware of enough gotchas with the i18n-topics. ;) – sthzg Apr 24 '15 at 18:16

1 Answers1

1

The language directories in /data/www/locale/ should be separated by underscores instead of hyphens. The naming can be compared against Django's official repo.

In case of zh_Hans and zh_Hant it also seems appropriate to uppercase only the first letter of the 4-characters behind the hyphen (that said, testing it it also worked with lower-case names like zh_hans).

/data/www/locale/
|-- en_US
|-- zh_Hans
`-- zh_Hant

Against my previous comment these underscores should only be in the directory names, they need to remain separated by hyphens in settings.py.

To initially create the directories with this name (no need to recreate them if they already exist, renaming should be enough):

$ django-admin.py makemessages -l zh_Hant
$ django-admin.py makemessages -l zh_Hans

After compiling the messages and restarting runserver (it can't detect file changes outside the project root) the translations should show, at least it worked for me while testing it in Django Admin with translating verbose_name_plural of a test model.

One thing I've noticed, the directory /data/www/locale/ needs to be on Python path in order for Django to pick the translations up.

sthzg
  • 5,514
  • 2
  • 29
  • 50
  • Finally came back to this and it all seems to be working now after naming the directories as per the official repo link. Thanks very much – DanH Jun 02 '15 at 13:56
  • Thanks for this. so zh_CN and zh_Hans are the codes. – TankorSmash Oct 01 '15 at 17:29
  • @TankorSmash `zh_CN` is kind of deprecated (see [this ticket for the argument behind](https://code.djangoproject.com/ticket/18419)), so for simplified Chinese `zh_Hans` is recommended. – sthzg Oct 01 '15 at 20:54
  • Thanks, I had just read that. Unfortunately we've got both languages implemented thanks to an engineer's incompetence (mine). – TankorSmash Oct 01 '15 at 21:11
  • frustratingly it seems as though the case sensitivity over the language specific folder names is less of an issue for OSX than it is for Ubuntu, which makes committing the case sensitive folder names to Git a pain. I had to do `git mv zh_hant zh_hant2; git mv zh_hant2 zh_Hant`. – DanH Dec 02 '15 at 10:07