Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: How to add Chinese support to the application

I am trying to add a Chinese language to my application written in Django and I have a really hard time with that. I have spent half a day trying different approaches, no success.

My application supports few languages, this is part of settings.py file:

TIME_ZONE = 'Europe/Dublin'
LANGUAGE_CODE = 'en'

LOCALES = (
    #English
    ('en', u'English'),

    #Norwegian
    ('no', u'Norsk'),

    #Finish
    ('fi', u'Suomi'),

    #Simplified Chinese
    ('zh-CN', u'简体中文'),

    #Traditional Chinese
    ('zh-TW', u'繁體中文'),

    #Japanese
    ('ja', u'日本語'),
)

At the moment all (but Chinese) languages work perfectly. This is a content of locale directory:

$ ls locale/
en
fi
ja
no
zh_CN
zh_TW

In every directory I have LC_MESSAGES directory with *.mo and *.po files. *.po files are created by script written in Python, which converts *.ODS to a text file. *.mo files are created by python manage.py compilemessages command.

Language can be selected by user from the proper form in "Preferences" section in my application.

Django does not load Chinese translation. That is the problem. Both simplified and traditional does not work. I have tried different variations of language and locale codes in settings.py and in locale directory: zh-CN, zh-cn, zh_CN, zh_cn. No success.

Perhaps I made a simple mistake? I have added Polish language just for test and everything went fine. Basically I did the same. I have added ('pl', u'Polish') tuple to the settings.py and "locale/pl" with *.po and *.mo and LC_MESSAGES directory...

Do you know what might be wrong?

like image 932
Pavulon Avatar asked Oct 11 '11 15:10

Pavulon


People also ask

Can Django be used with other languages?

In fact, Django is translated into more than 100 languages. This tutorial looks at how to add multiple language support to your Django project.

What is internationalization in Django?

The goal of internationalization and localization is to allow a single web application to offer its content in languages and formats tailored to the audience. Django has full support for translation of text, formatting of dates, times and numbers, and time zones.

What is Django translate?

Django then provides utilities to extract the translation strings into a message file. This file is a convenient way for translators to provide the equivalent of the translation strings in the target language. Once the translators have filled in the message file, it must be compiled.


2 Answers

You will need to use lower case for your locale language codes for it to work properly. i.e. use

LANGUAGES = (
    ('zh-cn', u'简体中文'), # instead of 'zh-CN'
    ('zh-tw', u'繁體中文'), # instead of 'zh-TW'
)

See the language codes specified in https://code.djangoproject.com/browser/django/trunk/django/conf/global_settings.py. You will see that it uses zh-tw instead of zh-TW.

Finally, the language directories storing the *.po and *.mo files in your locales folder needs to be named zh_CN and zh_TW respectively for the translations to work properly.

like image 170
Derek Kwok Avatar answered Oct 12 '22 15:10

Derek Kwok


For Django 1.7 and up, you'll need to do the following:

zh-hans in your config, and make sure that your directory is named zh_Hans.

And for traditional Chinese:

zh-hant in your config, and your directory should be named zh_Hant.

Here is an example of how the auth contributor package lays out its translations in the locale directory: https://github.com/django/django/tree/master/django/contrib/auth/locale

Basically, for our Chinese language codes, the - is replaced with a _, and the first letter of the second work is capitalized.

Source code for this logic is here: https://github.com/django/django/blob/7a42cfcfdc94c1e7cd653f3140b9eb30492bae4f/django/utils/translation/init.py#L272-L285

and just to be thorough, here is the method:

def to_locale(language, to_lower=False):
    """
    Turns a language name (en-us) into a locale name (en_US). If 'to_lower' is
    True, the last component is lower-cased (en_us).
    """
    p = language.find('-')
    if p >= 0:
        if to_lower:
            return language[:p].lower() + '_' + language[p + 1:].lower()
        else:
            # Get correct locale for sr-latn
            if len(language[p + 1:]) > 2:
                return language[:p].lower() + '_' + language[p + 1].upper() + language[p + 2:].lower()
            return language[:p].lower() + '_' + language[p + 1:].upper()
    else:
return language.lower()

Note that en-us is turned into en_US, based on the source code above, because us is 2 characters or less.

like image 35
modulitos Avatar answered Oct 12 '22 16:10

modulitos