2010-02-16 20:12:53 +08:00
|
|
|
.. _using-translations-in-your-own-projects:
|
|
|
|
|
|
|
|
===============================================
|
|
|
|
Using internationalization in your own projects
|
|
|
|
===============================================
|
|
|
|
|
2011-02-08 02:48:40 +08:00
|
|
|
At runtime, Django builds an in-memory unified catalog of literals-translations.
|
|
|
|
To achieve this it looks for translations by following this algorithm regarding
|
|
|
|
the order in which it examines the different file paths to load the compiled
|
|
|
|
:term:`message files <message file>` (``.mo``) and the precedence of multiple
|
|
|
|
translations for the same literal:
|
|
|
|
|
|
|
|
1. The directories listed in :setting:`LOCALE_PATHS` have the highest
|
|
|
|
precedence, with the ones appearing first having higher precedence than
|
|
|
|
the ones appearing later.
|
|
|
|
2. Then, it looks for and uses if it exists a ``locale`` directory in each
|
|
|
|
of the installed apps listed in :setting:`INSTALLED_APPS`. The ones
|
|
|
|
appearing first have higher precedence than the ones appearing later.
|
|
|
|
3. Then, it looks for a ``locale`` directory in the project directory, or
|
|
|
|
more accurately, in the directory containing your settings file.
|
|
|
|
4. Finally, the Django-provided base translation in ``django/conf/locale``
|
|
|
|
is used as a fallback.
|
|
|
|
|
|
|
|
.. deprecated:: 1.3
|
|
|
|
Lookup in the ``locale`` subdirectory of the directory containing your
|
|
|
|
settings file (item 3 above) is deprecated since the 1.3 release and will be
|
|
|
|
removed in Django 1.5. You can use the :setting:`LOCALE_PATHS` setting
|
|
|
|
instead, by listing the absolute filesystem path of such ``locale``
|
|
|
|
directory in the setting value.
|
|
|
|
|
|
|
|
.. seealso::
|
|
|
|
|
|
|
|
The translations for literals included in JavaScript assets are looked up
|
|
|
|
following a similar but not identical algorithm. See the
|
|
|
|
:ref:`javascript_catalog view documentation <javascript_catalog-view>` for
|
|
|
|
more details.
|
2010-02-16 20:12:53 +08:00
|
|
|
|
|
|
|
In all cases the name of the directory containing the translation is expected to
|
|
|
|
be named using :term:`locale name` notation. E.g. ``de``, ``pt_BR``, ``es_AR``,
|
|
|
|
etc.
|
|
|
|
|
|
|
|
This way, you can write applications that include their own translations, and
|
|
|
|
you can override base translations in your project path. Or, you can just build
|
2011-02-08 02:48:40 +08:00
|
|
|
a big project out of several apps and put all translations into one big common
|
|
|
|
message file specific to the project you are composing. The choice is yours.
|
2010-02-16 20:12:53 +08:00
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
|
|
If you're using manually configured settings, as described in
|
|
|
|
:ref:`settings-without-django-settings-module`, the ``locale`` directory in
|
|
|
|
the project directory will not be examined, since Django loses the ability
|
|
|
|
to work out the location of the project directory. (Django normally uses the
|
|
|
|
location of the settings file to determine this, and a settings file doesn't
|
|
|
|
exist if you're manually configuring your settings.)
|
|
|
|
|
|
|
|
All message file repositories are structured the same way. They are:
|
|
|
|
|
2011-05-30 01:41:04 +08:00
|
|
|
* All paths listed in :setting:`LOCALE_PATHS` in your settings file are
|
2011-02-08 02:48:40 +08:00
|
|
|
searched for ``<language>/LC_MESSAGES/django.(po|mo)``
|
|
|
|
* ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)`` --
|
|
|
|
deprecated, see above.
|
|
|
|
* ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
|
2010-02-16 20:12:53 +08:00
|
|
|
* ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
|
|
|
|
|
|
|
|
To create message files, you use the :djadmin:`django-admin.py makemessages <makemessages>`
|
|
|
|
tool. You only need to be in the same directory where the ``locale/`` directory
|
|
|
|
is located. And you use :djadmin:`django-admin.py compilemessages <compilemessages>`
|
|
|
|
to produce the binary ``.mo`` files that are used by ``gettext``. Read the
|
2010-08-20 03:27:44 +08:00
|
|
|
:doc:`/topics/i18n/localization` document for more details.
|
2010-02-16 20:12:53 +08:00
|
|
|
|
|
|
|
You can also run ``django-admin.py compilemessages --settings=path.to.settings``
|
|
|
|
to make the compiler process all the directories in your :setting:`LOCALE_PATHS`
|
|
|
|
setting.
|
|
|
|
|
|
|
|
Finally, you should give some thought to the structure of your translation
|
|
|
|
files. If your applications need to be delivered to other users and will
|
|
|
|
be used in other projects, you might want to use app-specific translations.
|
2011-02-08 02:48:40 +08:00
|
|
|
But using app-specific translations and project-specific translations could
|
|
|
|
produce weird problems with ``makemessages``: It will traverse all directories
|
|
|
|
below the current path and so might put message IDs into a unified, common
|
|
|
|
message file for the current project that are already in application message
|
|
|
|
files.
|
2010-02-16 20:12:53 +08:00
|
|
|
|
|
|
|
The easiest way out is to store applications that are not part of the project
|
|
|
|
(and so carry their own translations) outside the project tree. That way,
|
2011-02-08 02:48:40 +08:00
|
|
|
``django-admin.py makemessages``, when ran on a project level will only extract
|
2010-02-16 20:12:53 +08:00
|
|
|
strings that are connected to your explicit project and not strings that are
|
|
|
|
distributed independently.
|
2010-02-22 07:44:05 +08:00
|
|
|
|
|
|
|
Using translations outside views and templates
|
|
|
|
==============================================
|
|
|
|
|
|
|
|
While Django provides a rich set of i18n tools for use in views and templates,
|
|
|
|
it does not restrict the usage to Django-specific code. The Django translation
|
|
|
|
mechanisms can be used to translate arbitrary texts to any language that is
|
|
|
|
supported by Django (as long as an appropriate translation catalog exists, of
|
|
|
|
course). You can load a translation catalog, activate it and translate text to
|
|
|
|
language of your choice, but remember to switch back to original language, as
|
|
|
|
activating a translation catalog is done on per-thread basis and such change
|
|
|
|
will affect code running in the same thread.
|
|
|
|
|
|
|
|
For example::
|
|
|
|
|
|
|
|
from django.utils import translation
|
|
|
|
def welcome_translated(language):
|
|
|
|
cur_language = translation.get_language()
|
|
|
|
try:
|
|
|
|
translation.activate(language)
|
|
|
|
text = translation.ugettext('welcome')
|
|
|
|
finally:
|
|
|
|
translation.activate(cur_language)
|
|
|
|
return text
|
|
|
|
|
|
|
|
Calling this function with the value 'de' will give you ``"Willkommen"``,
|
|
|
|
regardless of :setting:`LANGUAGE_CODE` and language set by middleware.
|
|
|
|
|
|
|
|
Functions of particular interest are ``django.utils.translation.get_language()``
|
|
|
|
which returns the language used in the current thread,
|
|
|
|
``django.utils.translation.activate()`` which activates a translation catalog
|
|
|
|
for the current thread, and ``django.utils.translation.check_for_language()``
|
|
|
|
which checks if the given language is supported by Django.
|