Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #17087 -- Re-organized the i18n docs to reduce confusion betwee…

…n USE_I18N/USE_L10N and the concepts of internationalization/localisation. Re

moved some duplicate content.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@17026 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 67e6e0fcf35d93f88bfb1a4cbf5c6008d99dd923 1 parent 4f00a2d
@aaugustin aaugustin authored
View
121 docs/howto/i18n.txt
@@ -1,121 +0,0 @@
-.. _using-translations-in-your-own-projects:
-
-===============================================
-Using internationalization in your own projects
-===============================================
-
-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.
-
-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
-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.
-
-.. 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:
-
-* All paths listed in :setting:`LOCALE_PATHS` in your settings file are
- 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)``
-* ``$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
-:doc:`/topics/i18n/localization` document for more details.
-
-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.
-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.
-
-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,
-``django-admin.py makemessages``, when ran on a project level will only extract
-strings that are connected to your explicit project and not strings that are
-distributed independently.
-
-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.
View
1  docs/howto/index.txt
@@ -18,7 +18,6 @@ you quickly accomplish common tasks.
deployment/index
error-reporting
initial-data
- i18n
jython
legacy-databases
outputting-csv
View
2  docs/internals/contributing/index.txt
@@ -56,7 +56,7 @@ Browse the following sections to find out how:
triaging-tickets
writing-code/index
writing-documentation
- translations
+ localizing
committing-code
.. _django-users: http://groups.google.com/group/django-users
View
22 docs/internals/contributing/translations.txt → docs/internals/contributing/localizing.txt
@@ -1,15 +1,15 @@
-=======================================
-Submitting and maintaining translations
-=======================================
+=================
+Localizing Django
+=================
Various parts of Django, such as the admin site and validation error messages,
-are internationalized. This means they display different text depending on each
-user's language setting. For this, Django uses the same internationalization and
-localization infrastructure available to Django applications, described in the
-:doc:`i18n documentation</topics/i18n/index>`.
+are internationalized. This means they display differently depending on each
+user's language or country. For this, Django uses the same internationalization
+and localization infrastructure available to Django applications, described in
+the :doc:`i18n documentation </topics/i18n/index>`.
-Internationalization
---------------------
+Translations
+------------
Translations are contributed by Django users worldwide. The translation work is
coordinated at `Transifex`_.
@@ -45,8 +45,8 @@ do:
For more information about how to use Transifex, read the
`Transifex User Guide`_.
-Localization
-------------
+Formats
+-------
You can also review ``conf/locale/<locale>/formats.py``. This file describes
the date, time and numbers formatting particularities of your locale. See
View
2  docs/ref/contrib/localflavor.txt
@@ -146,7 +146,7 @@ Django's general catalog in ``django/conf/locale``. If you want localflavor's
texts to be translated, like form fields error messages, you must include
:mod:`django.contrib.localflavor` in the :setting:`INSTALLED_APPS` setting, so
the internationalization system can find the catalog, as explained in
-:ref:`using-translations-in-your-own-projects`.
+:ref:`how-django-discovers-translations`.
Adding flavors
==============
View
16 docs/ref/settings.txt
@@ -1243,7 +1243,7 @@ LOCALE_PATHS
Default: ``()`` (Empty tuple)
A tuple of directories where Django looks for translation files.
-See :ref:`using-translations-in-your-own-projects`.
+See :ref:`how-django-discovers-translations`.
Example::
@@ -2038,10 +2038,10 @@ USE_I18N
Default: ``True``
-A boolean that specifies whether Django's internationalization system should be
-enabled. This provides an easy way to turn it off, for performance. If this is
-set to ``False``, Django will make some optimizations so as not to load the
-internationalization machinery.
+A boolean that specifies whether Django's translation system should be enabled.
+This provides an easy way to turn it off, for performance. If this is set to
+``False``, Django will make some optimizations so as not to load the
+translation machinery.
See also :setting:`USE_L10N`
@@ -2054,9 +2054,9 @@ USE_L10N
Default: ``False``
-A boolean that specifies if data will be localized by default or not. If this
-is set to ``True``, e.g. Django will display numbers and dates using the
-format of the current locale.
+A boolean that specifies if localized formatting of data will be enabled by
+default or not. If this is set to ``True``, e.g. Django will display numbers and
+dates using the format of the current locale.
See also :setting:`USE_I18N` and :setting:`LANGUAGE_CODE`
View
2  docs/ref/utils.txt
@@ -455,7 +455,7 @@ appropriate entities.
:synopsis: Internationalization support.
For a complete discussion on the usage of the following see the
-:doc:`Internationalization documentation </topics/i18n/internationalization>`.
+:doc:`translation documentation </topics/i18n/translation>`.
.. function:: gettext(message)
View
9 docs/topics/cache.txt
@@ -494,12 +494,9 @@ more on these decorators.
.. versionadded:: 1.2
If :setting:`USE_I18N` is set to ``True`` then the generated cache key will
-include the name of the active :term:`language<language code>`.
-This allows you to easily cache multilingual sites without having to create
-the cache key yourself.
-
-See :doc:`/topics/i18n/deployment` for more on how Django discovers the active
-language.
+include the name of the active :term:`language<language code>` -- see also
+:ref:`how-django-discovers-language-preference`). This allows you to easily
+cache multilingual sites without having to create the cache key yourself.
__ `Controlling cache: Using other headers`_
View
217 docs/topics/i18n/deployment.txt
@@ -1,217 +0,0 @@
-==========================
-Deployment of translations
-==========================
-
-If you don't need internationalization
-======================================
-
-Django's internationalization hooks are on by default, and that means there's a
-bit of i18n-related overhead in certain places of the framework. If you don't
-use internationalization, you should take the two seconds to set
-:setting:`USE_I18N = False <USE_I18N>` in your settings file. If
-:setting:`USE_I18N` is set to ``False``, then Django will make some
-optimizations so as not to load the internationalization machinery.
-
-You'll probably also want to remove ``'django.core.context_processors.i18n'``
-from your :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting.
-
-.. note::
-
- There is also an independent but related :setting:`USE_L10N` setting that
- controls if Django should implement format localization.
-
- If :setting:`USE_L10N` is set to ``True``, Django will handle numbers times,
- and dates in the format of the current locale. That includes representation
- of these field types on templates and allowed input formats for dates,
- times on model forms.
-
- See :ref:`format-localization` for more details.
-
-If you do need internationalization
-===================================
-
-.. _how-django-discovers-language-preference:
-
-How Django discovers language preference
-----------------------------------------
-
-Once you've prepared your translations -- or, if you just want to use the
-translations that come with Django -- you'll just need to activate translation
-for your app.
-
-Behind the scenes, Django has a very flexible model of deciding which language
-should be used -- installation-wide, for a particular user, or both.
-
-To set an installation-wide language preference, set :setting:`LANGUAGE_CODE`.
-Django uses this language as the default translation -- the final attempt if no
-other translator finds a translation.
-
-If all you want to do is run Django with your native language, and a language
-file is available for it, all you need to do is set :setting:`LANGUAGE_CODE`.
-
-If you want to let each individual user specify which language he or she
-prefers, use ``LocaleMiddleware``. ``LocaleMiddleware`` enables language
-selection based on data from the request. It customizes content for each user.
-
-To use ``LocaleMiddleware``, add ``'django.middleware.locale.LocaleMiddleware'``
-to your :setting:`MIDDLEWARE_CLASSES` setting. Because middleware order
-matters, you should follow these guidelines:
-
-* Make sure it's one of the first middlewares installed.
-* It should come after ``SessionMiddleware``, because ``LocaleMiddleware``
- makes use of session data. And it should come before ``CommonMiddleware``
- because ``CommonMiddleware`` needs an activated language in order
- to resolve the requested URL.
-* If you use ``CacheMiddleware``, put ``LocaleMiddleware`` after it.
-
-For example, your :setting:`MIDDLEWARE_CLASSES` might look like this::
-
- MIDDLEWARE_CLASSES = (
- 'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.middleware.locale.LocaleMiddleware',
- 'django.middleware.common.CommonMiddleware',
- )
-
-(For more on middleware, see the :doc:`middleware documentation
-</topics/http/middleware>`.)
-
-``LocaleMiddleware`` tries to determine the user's language preference by
-following this algorithm:
-
-.. versionchanged:: 1.4
-
-* First, it looks for the language prefix in the requested URL. This is
- only performed when you are using the ``i18n_patterns`` function in your
- root URLconf. See :ref:`url-internationalization` for more information
- about the language prefix and how to internationalize URL patterns.
-
-* Failing that, it looks for a ``django_language`` key in the current
- user's session.
-
-* Failing that, it looks for a cookie.
-
- The name of the cookie used is set by the :setting:`LANGUAGE_COOKIE_NAME`
- setting. (The default name is ``django_language``.)
-
-* Failing that, it looks at the ``Accept-Language`` HTTP header. This
- header is sent by your browser and tells the server which language(s) you
- prefer, in order by priority. Django tries each language in the header
- until it finds one with available translations.
-
-* Failing that, it uses the global :setting:`LANGUAGE_CODE` setting.
-
-.. _locale-middleware-notes:
-
-Notes:
-
-* In each of these places, the language preference is expected to be in the
- standard :term:`language format<language code>`, as a string. For example,
- Brazilian Portuguese is ``pt-br``.
-
-* If a base language is available but the sublanguage specified is not,
- Django uses the base language. For example, if a user specifies ``de-at``
- (Austrian German) but Django only has ``de`` available, Django uses
- ``de``.
-
-* Only languages listed in the :setting:`LANGUAGES` setting can be selected.
- If you want to restrict the language selection to a subset of provided
- languages (because your application doesn't provide all those languages),
- set :setting:`LANGUAGES` to a list of languages. For example::
-
- LANGUAGES = (
- ('de', _('German')),
- ('en', _('English')),
- )
-
- This example restricts languages that are available for automatic
- selection to German and English (and any sublanguage, like de-ch or
- en-us).
-
-* If you define a custom :setting:`LANGUAGES` setting, as explained in the
- previous bullet, it's OK to mark the languages as translation strings
- -- but use a "dummy" ``ugettext()`` function, not the one in
- ``django.utils.translation``. You should *never* import
- ``django.utils.translation`` from within your settings file, because that
- module in itself depends on the settings, and that would cause a circular
- import.
-
- The solution is to use a "dummy" ``ugettext()`` function. Here's a sample
- settings file::
-
- ugettext = lambda s: s
-
- LANGUAGES = (
- ('de', ugettext('German')),
- ('en', ugettext('English')),
- )
-
- With this arrangement, ``django-admin.py makemessages`` will still find
- and mark these strings for translation, but the translation won't happen
- at runtime -- so you'll have to remember to wrap the languages in the
- *real* ``ugettext()`` in any code that uses :setting:`LANGUAGES` at
- runtime.
-
-* The ``LocaleMiddleware`` can only select languages for which there is a
- Django-provided base translation. If you want to provide translations
- for your application that aren't already in the set of translations
- in Django's source tree, you'll want to provide at least a basic
- one as described in the :ref:`Locale restrictions<locale-restrictions>`
- note.
-
-Once ``LocaleMiddleware`` determines the user's preference, it makes this
-preference available as ``request.LANGUAGE_CODE`` for each
-:class:`~django.http.HttpRequest`. Feel free to read this value in your view
-code. Here's a simple example::
-
- def hello_world(request, count):
- if request.LANGUAGE_CODE == 'de-at':
- return HttpResponse("You prefer to read Austrian German.")
- else:
- return HttpResponse("You prefer to read another language.")
-
-Note that, with static (middleware-less) translation, the language is in
-``settings.LANGUAGE_CODE``, while with dynamic (middleware) translation, it's
-in ``request.LANGUAGE_CODE``.
-
-.. _settings file: ../settings/
-.. _middleware documentation: ../middleware/
-.. _session: ../sessions/
-.. _request object: ../request_response/#httprequest-objects
-
-How Django discovers translations
----------------------------------
-
-As described in :ref:`using-translations-in-your-own-projects`, Django 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.
-
-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.
View
182 docs/topics/i18n/formatting.txt
@@ -0,0 +1,182 @@
+===================
+Format localization
+===================
+
+.. _format-localization:
+
+.. versionadded:: 1.2
+
+Overview
+========
+
+Django's formatting system is capable to display dates, times and numbers in templates using the format specified for the current :term:`locale <locale
+name>`. It also handles localized input in forms.
+
+When it's enabled, two users accessing the same content may see dates, times and
+numbers formatted in different ways, depending on the formats for their current
+locale.
+
+The formatting system is disabled by default. To enable it, it's
+necessary to set :setting:`USE_L10N = True <USE_L10N>` in your settings file.
+
+.. note::
+
+ The default :file:`settings.py` file created by :djadmin:`django-admin.py
+ startproject <startproject>` includes :setting:`USE_L10N = True <USE_L10N>`
+ for convenience.
+
+.. note::
+
+ There is also an independent but related :setting:`USE_I18N` setting that
+ controls if Django should activate translation. See
+ :doc:`/topics/i18n/translation` for more details.
+
+Locale aware input in forms
+===========================
+
+When formatting is enabled, Django can use localized formats when parsing dates,
+times and numbers in forms. That means it tries different formats for different
+locales when guessing the format used by the user when inputting data on forms.
+
+.. note::
+ Django uses different formats for displaying data to those it uses for
+ parsing data. Most notably, the formats for parsing dates can't use the
+ ``%a`` (abbreviated weekday name), ``%A`` (full weekday name),
+ ``%b`` (abbreviated month name), ``%B`` (full month name),
+ or ``%p`` (AM/PM).
+
+To enable a form field to localize input and output data simply use its
+``localize`` argument::
+
+ class CashRegisterForm(forms.Form):
+ product = forms.CharField()
+ revenue = forms.DecimalField(max_digits=4, decimal_places=2, localize=True)
+
+.. _topic-l10n-templates:
+
+Controlling localization in templates
+=====================================
+
+When you have enabled formatting with :setting:`USE_L10N`, Django
+will try to use a locale specific format whenever it outputs a value
+in a template.
+
+However, it may not always be appropriate to use localized values --
+for example, if you're outputting Javascript or XML that is designed
+to be machine-readable, you will always want unlocalized values. You
+may also want to use localization in selected templates, rather than
+using localization everywhere.
+
+To allow for fine control over the use of localization, Django
+provides the ``l10n`` template library that contains the following
+tags and filters.
+
+Template tags
+-------------
+
+.. templatetag:: localize
+
+localize
+~~~~~~~~
+
+.. versionadded:: 1.3
+
+Enables or disables localization of template variables in the
+contained block.
+
+This tag allows a more fine grained control of localization than
+:setting:`USE_L10N`.
+
+To activate or deactivate localization for a template block, use::
+
+ {% load l10n %}
+
+ {% localize on %}
+ {{ value }}
+ {% endlocalize %}
+
+ {% localize off %}
+ {{ value }}
+ {% endlocalize %}
+
+.. note::
+
+ The value of :setting:`USE_L10N` isn't respected inside of a
+ ``{% localize %}`` block.
+
+See :tfilter:`localize` and :tfilter:`unlocalize` for template filters that will
+do the same job on a per-variable basis.
+
+Template filters
+----------------
+
+.. templatefilter:: localize
+
+localize
+~~~~~~~~
+
+.. versionadded:: 1.3
+
+Forces localization of a single value.
+
+For example::
+
+ {% load l10n %}
+
+ {{ value|localize }}
+
+To disable localization on a single value, use :tfilter:`unlocalize`. To control
+localization over a large section of a template, use the :ttag:`localize` template
+tag.
+
+
+.. templatefilter:: unlocalize
+
+unlocalize
+~~~~~~~~~~
+
+.. versionadded:: 1.3
+
+Forces a single value to be printed without localization.
+
+For example::
+
+ {% load l10n %}
+
+ {{ value|unlocalize }}
+
+To force localization of a single value, use :tfilter:`localize`. To
+control localization over a large section of a template, use the
+:ttag:`localize` template tag.
+
+Creating custom format files
+============================
+
+Django provides format definitions for many locales, but sometimes you might
+want to create your own, because a format files doesn't exist for your locale,
+or because you want to overwrite some of the values.
+
+To use custom formats, specify the path where you'll place format files first.
+To do that, just set your :setting:`FORMAT_MODULE_PATH` setting to the package
+where format files will exist, for instance::
+
+ FORMAT_MODULE_PATH = 'mysite.formats'
+
+Files are not placed directly in this directory, but in a directory named as
+the locale, and must be named ``formats.py``.
+
+To customize the English formats, a structure like this would be needed::
+
+ mysite/
+ formats/
+ __init__.py
+ en/
+ __init__.py
+ formats.py
+
+where :file:`formats.py` contains custom format definitions. For example::
+
+ THOUSAND_SEPARATOR = ' '
+
+to use a space as a thousand separator, instead of the default for English,
+a comma.
View
96 docs/topics/i18n/index.txt
@@ -2,64 +2,77 @@
Internationalization and localization
=====================================
+.. toctree::
+ :hidden:
+ :maxdepth: 1
+
+ translation
+ formatting
+
Overview
========
-Django has full support for internationalization of text in code and
-templates, and format localization of dates and numbers. Here's how it works.
+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 :doc:`translation of text
+</topics/i18n/translation>` and :doc:`formatting of dates, times and numbers
+</topics/i18n/formatting>`.
Essentially, Django does two things:
-* It allows developers and template authors to specify which parts of
- their apps should be translatable.
-* It uses these hooks to translate Web apps for particular users according
- to their language preferences.
+* It allows developers and template authors to specify which parts of their apps
+ should be translated or formatted for local languages and cultures.
+* It uses these hooks to localize Web apps for particular users according to
+ their preferences.
-The complete process can be seen as divided in three stages. It is also possible
-to identify an identical number of roles with very well defined responsibilities
-associated with each of these tasks (although it's perfectly normal if you
-find yourself performing more than one of these roles):
+Obviously, translation depends on the target language. Formatting usually
+depends on the target country.
-* For application authors wishing to make sure their Django apps can be
- used in different locales: :doc:`/topics/i18n/internationalization`.
-* For translators wanting to translate Django apps: :doc:`/topics/i18n/localization`.
-* For system administrators/final users setting up internationalized apps or
- developers integrating third party apps: :doc:`/topics/i18n/deployment`.
+Definitions
+===========
-.. toctree::
- :hidden:
- :maxdepth: 1
+The words "internationalization" and "localization" often cause confusion;
+here's a simplified definition:
+
+.. glossary::
- internationalization
- localization
- deployment
+ internationalization
+ Preparing the software for localization. Usually done by developers.
-.. _ seealso::
+ localization
+ Writing the translations and local formats. Usually done by translators.
-For more general information about the topic, see the `GNU gettext documentation`_
-and the `Wikipedia article`_.
+More details can be found in the `W3C Web Internationalization FAQ`_, the `Wikipedia article`_ or the `GNU gettext documentation`_.
+.. _W3C Web Internationalization FAQ: http://www.w3.org/International/questions/qa-i18n
.. _GNU gettext documentation: http://www.gnu.org/software/gettext/manual/gettext.html#Concepts
.. _Wikipedia article: http://en.wikipedia.org/wiki/Internationalization_and_localization
-Glossary
-========
+.. warning::
-First lets define some terms that will help us to handle a common language:
+ Translation and formatting are controlled by :setting:`USE_I18N` and
+ :setting:`USE_L10N` settings respectively. However, both features involve
+ internationalization and localization. The names of the settings are an
+ unfortunate result of Django's history.
+
+Here are some other terms that will help us to handle a common language:
.. glossary::
locale name
A locale name, either a language specification of the form ``ll`` or a
combined language and country specification of the form ``ll_CC``.
- Examples: ``it``, ``de_AT``, ``es``, ``pt_BR``. Note the underscore in
- some of them and the case of the part located to its right.
+ Examples: ``it``, ``de_AT``, ``es``, ``pt_BR``. The language part is
+ always is lower case and the country part in upper case. The separator
+ is an underscore.
language code
Represents the name of a language. Browsers send the names of the
languages they accept in the ``Accept-Language`` HTTP header using this
- format. Examples: ``it``, ``de-at``, ``es``, ``pt-br``. Note the ``-``
- separator.
+ format. Examples: ``it``, ``de-at``, ``es``, ``pt-br``. Both the language
+ and the country parts are in lower case. The separator is a dash.
message file
A message file is a plain-text file, representing a single language,
@@ -70,21 +83,6 @@ First lets define some terms that will help us to handle a common language:
translation string
A literal that can be translated.
-.. _specialties-of-django-i18n:
-
-Specialties of Django translation
-=================================
-
-Django's translation machinery uses the standard ``gettext`` module that comes
-with Python. If you know ``gettext``, you might note these specialties in the
-way Django does translation:
-
-* The string domain is ``django`` or ``djangojs``. This string domain is
- used to differentiate between different programs that store their data
- in a common message-file library (usually ``/usr/share/locale/``). The
- ``django`` domain is used for python and template translation strings
- and is loaded into the global translation catalogs. The ``djangojs``
- domain is only used for JavaScript translation catalogs to make sure
- that those are as small as possible.
-* Django doesn't use ``xgettext`` alone. It uses Python wrappers around
- ``xgettext`` and ``msgfmt``. This is mostly for convenience.
+ format file
+ A format file is a Python module that defines the data formats for a given
+ locale.
View
409 docs/topics/i18n/localization.txt
@@ -1,409 +0,0 @@
-============
-Localization
-============
-
-This document covers three localization-related topics: `Creating language
-files`_ , `locale aware date, time and numbers input/output in forms`_,
-and `controlling localization in templates`_.
-
-.. _`Creating language files`: how-to-create-language-files_
-.. _`locale aware date, time and numbers input/output in forms`: format-localization_
-.. _`controlling localization in templates`: topic-l10n-templates_
-
-.. seealso::
-
- The :doc:`/howto/i18n` document included with the Django HOW-TO documents collection.
-
-.. _how-to-create-language-files:
-
-How to create language files
-============================
-
-Once the string literals of an application have been tagged for later
-translation, the translation themselves need to be written (or obtained). Here's
-how that works.
-
-.. _locale-restrictions:
-
-.. admonition:: Locale restrictions
-
- Django does not support localizing your application into a locale for which
- Django itself has not been translated. In this case, it will ignore your
- translation files. If you were to try this and Django supported it, you
- would inevitably see a mixture of translated strings (from your application)
- and English strings (from Django itself). If you want to support a locale
- for your application that is not already part of Django, you'll need to make
- at least a minimal translation of the Django core.
-
- A good starting point is to copy the Django English ``.po`` file and to
- translate at least some :term:`translation strings <translation string>`.
-
-Message files
--------------
-
-The first step is to create a :term:`message file` for a new language. A message
-file is a plain-text file, representing a single language, that contains all
-available translation strings and how they should be represented in the given
-language. Message files have a ``.po`` file extension.
-
-Django comes with a tool, ``django-admin.py makemessages``, that automates the
-creation and upkeep of these files.
-
-.. admonition:: Gettext utilities
-
- The ``makemessages`` command (and ``compilemessages`` discussed later) use
- commands from the GNU gettext toolset: ``xgettext``, ``msgfmt``,
- ``msgmerge`` and ``msguniq``.
-
- .. versionchanged:: 1.2
-
- The minimum version of the ``gettext`` utilities supported is 0.15.
-
-To create or update a message file, run this command::
-
- django-admin.py makemessages -l de
-
-...where ``de`` is the language code for the message file you want to create.
-The language code, in this case, is in :term:`locale format<locale name>`. For
-example, it's ``pt_BR`` for Brazilian Portuguese and ``de_AT`` for Austrian
-German.
-
-The script should be run from one of two places:
-
-* The root directory of your Django project.
-* The root directory of your Django app.
-
-The script runs over your project source tree or your application source tree
-and pulls out all strings marked for translation. It creates (or updates) a
-message file in the directory ``locale/LANG/LC_MESSAGES``. In the ``de``
-example, the file will be ``locale/de/LC_MESSAGES/django.po``.
-
-By default ``django-admin.py makemessages`` examines every file that has the
-``.html`` or ``.txt`` file extension. In case you want to override that
-default, use the ``--extension`` or ``-e`` option to specify the file
-extensions to examine::
-
- django-admin.py makemessages -l de -e txt
-
-Separate multiple extensions with commas and/or use ``-e`` or ``--extension``
-multiple times::
-
- django-admin.py makemessages -l de -e html,txt -e xml
-
-When :ref:`creating message files from JavaScript source code
-<creating-message-files-from-js-code>` you need to use the special 'djangojs'
-domain, **not** ``-e js``.
-
-.. admonition:: No gettext?
-
- If you don't have the ``gettext`` utilities installed, ``django-admin.py
- makemessages`` will create empty files. If that's the case, either install
- the ``gettext`` utilities or just copy the English message file
- (``locale/en/LC_MESSAGES/django.po``) if available and use it as a starting
- point; it's just an empty translation file.
-
-.. admonition:: Working on Windows?
-
- If you're using Windows and need to install the GNU gettext utilities so
- ``django-admin makemessages`` works see :ref:`gettext_on_windows` for more
- information.
-
-The format of ``.po`` files is straightforward. Each ``.po`` file contains a
-small bit of metadata, such as the translation maintainer's contact
-information, but the bulk of the file is a list of **messages** -- simple
-mappings between translation strings and the actual translated text for the
-particular language.
-
-For example, if your Django app contained a translation string for the text
-``"Welcome to my site."``, like so::
-
- _("Welcome to my site.")
-
-...then ``django-admin.py makemessages`` will have created a ``.po`` file
-containing the following snippet -- a message::
-
- #: path/to/python/module.py:23
- msgid "Welcome to my site."
- msgstr ""
-
-A quick explanation:
-
-* ``msgid`` is the translation string, which appears in the source. Don't
- change it.
-* ``msgstr`` is where you put the language-specific translation. It starts
- out empty, so it's your responsibility to change it. Make sure you keep
- the quotes around your translation.
-* As a convenience, each message includes, in the form of a comment line
- prefixed with ``#`` and located above the ``msgid`` line, the filename and
- line number from which the translation string was gleaned.
-
-Long messages are a special case. There, the first string directly after the
-``msgstr`` (or ``msgid``) is an empty string. Then the content itself will be
-written over the next few lines as one string per line. Those strings are
-directly concatenated. Don't forget trailing spaces within the strings;
-otherwise, they'll be tacked together without whitespace!
-
-.. admonition:: Mind your charset
-
- When creating a PO file with your favorite text editor, first edit
- the charset line (search for ``"CHARSET"``) and set it to the charset
- you'll be using to edit the content. Due to the way the ``gettext`` tools
- work internally and because we want to allow non-ASCII source strings in
- Django's core and your applications, you **must** use UTF-8 as the encoding
- for your PO file. This means that everybody will be using the same
- encoding, which is important when Django processes the PO files.
-
-To reexamine all source code and templates for new translation strings and
-update all message files for **all** languages, run this::
-
- django-admin.py makemessages -a
-
-Compiling message files
------------------------
-
-After you create your message file -- and each time you make changes to it --
-you'll need to compile it into a more efficient form, for use by ``gettext``.
-Do this with the ``django-admin.py compilemessages`` utility.
-
-This tool runs over all available ``.po`` files and creates ``.mo`` files, which
-are binary files optimized for use by ``gettext``. In the same directory from
-which you ran ``django-admin.py makemessages``, run ``django-admin.py
-compilemessages`` like this::
-
- django-admin.py compilemessages
-
-That's it. Your translations are ready for use.
-
-.. admonition:: Working on Windows?
-
- If you're using Windows and need to install the GNU gettext utilities so
- ``django-admin compilemessages`` works see :ref:`gettext_on_windows` for more
- information.
-
-.. admonition:: .po files: Encoding and BOM usage.
-
- Django only supports ``.po`` files encoded in UTF-8 and without any BOM
- (Byte Order Mark) so if your text editor adds such marks to the beginning of
- files by default then you will need to reconfigure it.
-
-.. _creating-message-files-from-js-code:
-
-Creating message files from JavaScript source code
-==================================================
-
-You create and update the message files the same way as the other Django
-message files -- with the ``django-admin.py makemessages`` tool. The only
-difference is you need to explicitly specify what in gettext parlance is known
-as a domain in this case the ``djangojs`` domain, by providing a ``-d djangojs``
-parameter, like this::
-
- django-admin.py makemessages -d djangojs -l de
-
-This would create or update the message file for JavaScript for German.
-After updating message files, just run ``django-admin.py compilemessages``
-the same way as you do with normal Django message files.
-
-.. _gettext_on_windows:
-
-``gettext`` on Windows
-======================
-
-This is only needed for people who either want to extract message IDs or compile
-message files (``.po``). Translation work itself just involves editing existing
-files of this type, but if you want to create your own message files, or want to
-test or compile a changed message file, you will need the ``gettext`` utilities:
-
-* Download the following zip files from the GNOME servers
- http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/ or from one
- of its mirrors_
-
- * ``gettext-runtime-X.zip``
- * ``gettext-tools-X.zip``
-
- ``X`` is the version number, we are requiring ``0.15`` or higher.
-
-* Extract the contents of the ``bin\`` directories in both files to the
- same folder on your system (i.e. ``C:\Program Files\gettext-utils``)
-
-* Update the system PATH:
-
- * ``Control Panel > System > Advanced > Environment Variables``.
- * In the ``System variables`` list, click ``Path``, click ``Edit``.
- * Add ``;C:\Program Files\gettext-utils\bin`` at the end of the
- ``Variable value`` field.
-
-.. _mirrors: http://ftp.gnome.org/pub/GNOME/MIRRORS
-
-You may also use ``gettext`` binaries you have obtained elsewhere, so long as
-the ``xgettext --version`` command works properly. Do not attempt to use Django
-translation utilities with a ``gettext`` package if the command ``xgettext
---version`` entered at a Windows command prompt causes a popup window saying
-"xgettext.exe has generated errors and will be closed by Windows".
-
-.. _format-localization:
-
-Format localization
-===================
-
-.. versionadded:: 1.2
-
-Django's formatting system is disabled by default. To enable it, it's
-necessary to set :setting:`USE_L10N = True <USE_L10N>` in your settings file.
-
-.. note::
-
- The default :file:`settings.py` file created by :djadmin:`django-admin.py
- startproject <startproject>` includes :setting:`USE_L10N = True <USE_L10N>`
- for convenience.
-
-When using Django's formatting system, dates and numbers on templates will be
-displayed using the format specified for the current locale. Two users
-accessing the same content, but in different language, will see date and
-number fields formatted in different ways, depending on the format for their
-current locale.
-
-Django will also use localized formats when parsing data in forms. That means
-Django uses different formats for different locales when guessing the format
-used by the user when inputting data on forms.
-
-.. note::
- Django uses different formats for displaying data to those it uses for
- parsing data. Most notably, the formats for parsing dates can't use the
- ``%a`` (abbreviated weekday name), ``%A`` (full weekday name),
- ``%b`` (abbreviated month name), ``%B`` (full month name),
- or ``%p`` (AM/PM).
-
-To enable a form field to localize input and output data simply use its
-``localize`` argument::
-
- class CashRegisterForm(forms.Form):
- product = forms.CharField()
- revenue = forms.DecimalField(max_digits=4, decimal_places=2, localize=True)
-
-Creating custom format files
-----------------------------
-
-Django provides format definitions for many locales, but sometimes you might
-want to create your own, because a format files doesn't exist for your locale,
-or because you want to overwrite some of the values.
-
-To use custom formats, first thing to do, is to specify the path where you'll
-place format files. To do that, just set your :setting:`FORMAT_MODULE_PATH`
-setting to the path (in the format ``'foo.bar.baz``) where format files
-will exists.
-
-Files are not placed directly in this directory, but in a directory named as
-the locale, and must be named ``formats.py``.
-
-To customize the English formats, a structure like this would be needed::
-
- mysite/
- formats/
- __init__.py
- en/
- __init__.py
- formats.py
-
-where :file:`formats.py` contains custom format definitions. For example::
-
- THOUSAND_SEPARATOR = ' '
-
-to use a space as a thousand separator, instead of the default for English,
-a comma.
-
-.. _topic-l10n-templates:
-
-Controlling localization in templates
-=====================================
-
-When you have enabled localization using :setting:`USE_L10N`, Django
-will try to use a locale specific format whenever it outputs a value
-in a template.
-
-However, it may not always be appropriate to use localized values --
-for example, if you're outputting Javascript or XML that is designed
-to be machine-readable, you will always want unlocalized values. You
-may also want to use localization in selected templates, rather than
-using localization everywhere.
-
-To allow for fine control over the use of localization, Django
-provides the ``l10n`` template library that contains the following
-tags and filters.
-
-Template tags
--------------
-
-.. templatetag:: localize
-
-localize
-~~~~~~~~
-
-.. versionadded:: 1.3
-
-Enables or disables localization of template variables in the
-contained block.
-
-This tag allows a more fine grained control of localization than
-:setting:`USE_L10N`.
-
-To activate or deactivate localization for a template block, use::
-
- {% load l10n %}
-
- {% localize on %}
- {{ value }}
- {% endlocalize %}
-
- {% localize off %}
- {{ value }}
- {% endlocalize %}
-
-.. note::
-
- The value of :setting:`USE_L10N` is not respected inside of a
- `{% localize %}` block.
-
-See :tfilter:`localized` and :tfilter:`unlocalized` for a template filter that will
-do the same job on a per-variable basis.
-
-Template filters
-----------------
-
-.. templatefilter:: localize
-
-localize
-~~~~~~~~
-
-.. versionadded:: 1.3
-
-Forces localization of a single value.
-
-For example::
-
- {% load l10n %}
-
- {{ value|localize }}
-
-To disable localization on a single value, use :tfilter:`unlocalize`. To control
-localization over a large section of a template, use the :ttag:`localize` template
-tag.
-
-
-.. templatefilter:: unlocalize
-
-unlocalize
-~~~~~~~~~~
-
-.. versionadded:: 1.3
-
-Forces a single value to be printed without localization.
-
-For example::
-
- {% load l10n %}
-
- {{ value|unlocalize }}
-
-To force localization of a single value, use :tfilter:`localize`. To
-control localization over a large section of a template, use the
-:ttag:`localize` template tag.
View
632 docs/topics/i18n/internationalization.txt → docs/topics/i18n/translation.txt
@@ -1,27 +1,44 @@
-====================
-Internationalization
-====================
+===========
+Translation
+===========
.. module:: django.utils.translation
Overview
========
-The goal of internationalization is to allow a single Web application to offer
-its content and functionality in multiple languages and locales.
+In order to make a Django project translatable, you have to add a minimal amount
+of hooks to your Python code and templates. These hooks are called
+:term:`translation strings <translation string>`. They tell Django: "This text
+should be translated into the end user's language, if a translation for this
+text is available in that language." It's your responsibility to mark
+translatable strings; the system can only translate strings it knows about.
+
+Django then provides utilities to extract the translation strings into a
+:term:`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. This process
+relies on the GNU gettext toolset.
+
+Once this is done, Django takes care of translating Web apps on the fly in each
+available language, according to users' language preferences.
+
+Django's internationalization hooks are on by default, and that means there's a
+bit of i18n-related overhead in certain places of the framework. If you don't
+use internationalization, you should take the two seconds to set
+:setting:`USE_I18N = False <USE_I18N>` in your settings file. Then Django will
+make some optimizations so as not to load the internationalization machinery.
+You'll probably also want to remove ``'django.core.context_processors.i18n'``
+from your :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting.
-For text translations, you, the Django developer, can accomplish this goal by
-adding a minimal amount of hooks to your Python and templates. These hooks
-are called **translation strings**. They tell Django: "This text should be
-translated into the end user's language, if a translation for this text is
-available in that language." It's your responsibility to mark translatable
-strings; the system can only translate strings it knows about.
+.. note::
-Django takes care of using these hooks to translate Web apps, on the fly,
-according to users' language preferences.
+ There is also an independent but related :setting:`USE_L10N` setting that
+ controls if Django should implement format localization. See
+ :doc:`/topics/i18n/formatting` for more details.
-Specifying translation strings: In Python code
-==============================================
+Internationalization: in Python code
+====================================
Standard translation
--------------------
@@ -85,8 +102,8 @@ Translation works on variables. Again, here's an identical example::
(The caveat with using variables or computed values, as in the previous two
examples, is that Django's translation-string-detecting utility,
-``django-admin.py makemessages``, won't be able to find these strings. More on
-``makemessages`` later.)
+:djadmin:`django-admin.py makemessages <makemessages>`, won't be able to find
+these strings. More on :djadmin:`makemessages` later.)
The strings you pass to ``_()`` or ``ugettext()`` can take placeholders,
specified with Python's standard named-string interpolation syntax. Example::
@@ -126,7 +143,7 @@ This also works in templates with the :ttag:`comment` tag:
{% comment %}Translators: This is a text of the base template {% endcomment %}
-The comment will then appear in the resulting .po file and should also be
+The comment will then appear in the resulting ``.po`` file and should also be
displayed by most translation tools.
Marking strings as no-op
@@ -221,9 +238,10 @@ cardinality of the elements at play.
count
) % d
- You would get a ``a format specification for argument 'name', as in
- 'msgstr[0]', doesn't exist in 'msgid'`` error when running
- ``django-admin.py compilemessages``.
+ You would get an error when running :djadmin:`django-admin.py
+ compilemessages <compilemessages>`::
+
+ a format specification for argument 'name', as in 'msgstr[0]', doesn't exist in 'msgid'
.. _contextual-markers:
@@ -239,10 +257,10 @@ these words correctly in different contexts, you can use the
:func:`django.utils.translation.npgettext()` function if the string needs
pluralization. Both take a context string as the first variable.
-In the resulting .po file, the string will then appear as often as there are
-different contextual markers for the same string (the context will appear on
-the ``msgctxt`` line), allowing the translator to give a different translation
-for each of them.
+In the resulting ``.po`` file, the string will then appear as often as there are
+different contextual markers for the same string (the context will appear on the
+``msgctxt`` line), allowing the translator to give a different translation for
+each of them.
For example::
@@ -258,7 +276,7 @@ or::
name = models.CharField(help_text=pgettext_lazy(
'help text for MyThing model', 'This is the help text'))
-will appear in the .po file as:
+will appear in the ``.po`` file as:
.. code-block:: po
@@ -333,7 +351,7 @@ name::
class Meta:
verbose_name = _('my thing')
- verbose_name_plural = _('mythings')
+ verbose_name_plural = _('my things')
Notes on model classes translation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -398,7 +416,7 @@ strings when ``result`` itself is used in a string (usually at template
rendering time).
Localized names of languages
-============================
+----------------------------
.. function:: get_language_info
@@ -421,8 +439,8 @@ Similar access to this information is available for template code. See below.
.. _specifying-translation-strings-in-template-code:
-Specifying translation strings: In template code
-================================================
+Internationalization: in template code
+======================================
.. highlightlang:: html+django
@@ -672,8 +690,8 @@ There are also simple filters available for convenience:
.. _Django templates: ../templates_python/
-Specifying translation strings: In JavaScript code
-==================================================
+Internationalization: in JavaScript code
+========================================
.. highlightlang:: python
@@ -681,8 +699,8 @@ Adding translations to JavaScript poses some problems:
* JavaScript code doesn't have access to a ``gettext`` implementation.
-* JavaScript code doesn't have access to .po or .mo files; they need to be
- delivered by the server.
+* JavaScript code doesn't have access to ``.po`` or ``.mo`` files; they need to
+ be delivered by the server.
* The translation catalogs for JavaScript should be kept as small as
possible.
@@ -700,12 +718,12 @@ The ``javascript_catalog`` view
.. function:: javascript_catalog(request, domain='djangojs', packages=None)
-The main solution to these problems is the :meth:`django.views.i18n.javascript_catalog`
-view, which sends out a JavaScript code library with functions that mimic the
-``gettext`` interface, plus an array of translation strings. Those translation
-strings are taken from applications or Django core, according to what you
-specify in either the info_dict or the URL. Paths listed in
-:setting:`LOCALE_PATHS` are also included.
+The main solution to these problems is the
+:meth:`django.views.i18n.javascript_catalog` view, which sends out a JavaScript
+code library with functions that mimic the ``gettext`` interface, plus an array
+of translation strings. Those translation strings are taken from applications or
+Django core, according to what you specify in either the ``info_dict`` or the
+URL. Paths listed in :setting:`LOCALE_PATHS` are also included.
You hook it up like this::
@@ -815,8 +833,8 @@ to produce proper pluralizations).
.. _url-internationalization:
-Specifying translation strings: In URL patterns
-===============================================
+Internationalization: in URL patterns
+=====================================
.. versionadded:: 1.4
@@ -922,9 +940,9 @@ URL patterns can also be marked translatable using the
)
-After you've created the translations (see :doc:`localization` for more
-information), the :func:`~django.core.urlresolvers.reverse` function will
-return the URL in the active language. Example::
+After you've created the translations, the
+:func:`~django.core.urlresolvers.reverse` function will return the URL in the
+active language. Example::
from django.core.urlresolvers import reverse
from django.utils.translation import activate
@@ -971,10 +989,242 @@ template tag. It enables the given language in the enclosed template section:
The :ttag:`language` tag expects the language code as the only argument.
+.. _how-to-create-language-files:
+
+Localization: how to create language files
+==========================================
+
+Once the string literals of an application have been tagged for later
+translation, the translation themselves need to be written (or obtained). Here's
+how that works.
+
+.. _locale-restrictions:
+
+.. admonition:: Locale restrictions
+
+ Django does not support localizing your application into a locale for which
+ Django itself has not been translated. In this case, it will ignore your
+ translation files. If you were to try this and Django supported it, you
+ would inevitably see a mixture of translated strings (from your application)
+ and English strings (from Django itself). If you want to support a locale
+ for your application that is not already part of Django, you'll need to make
+ at least a minimal translation of the Django core.
+
+ A good starting point is to copy the Django English ``.po`` file and to
+ translate at least some :term:`translation strings <translation string>`.
+
+Message files
+-------------
+
+The first step is to create a :term:`message file` for a new language. A message
+file is a plain-text file, representing a single language, that contains all
+available translation strings and how they should be represented in the given
+language. Message files have a ``.po`` file extension.
+
+Django comes with a tool, :djadmin:`django-admin.py makemessages
+<makemessages>`, that automates the creation and upkeep of these files.
+
+.. admonition:: Gettext utilities
+
+ The ``makemessages`` command (and ``compilemessages`` discussed later) use
+ commands from the GNU gettext toolset: ``xgettext``, ``msgfmt``,
+ ``msgmerge`` and ``msguniq``.
+
+ .. versionchanged:: 1.2
+
+ The minimum version of the ``gettext`` utilities supported is 0.15.
+
+To create or update a message file, run this command::
+
+ django-admin.py makemessages -l de
+
+...where ``de`` is the language code for the message file you want to create.
+The language code, in this case, is in :term:`locale format<locale name>`. For
+example, it's ``pt_BR`` for Brazilian Portuguese and ``de_AT`` for Austrian
+German.
+
+The script should be run from one of two places:
+
+* The root directory of your Django project.
+* The root directory of your Django app.
+
+The script runs over your project source tree or your application source tree
+and pulls out all strings marked for translation. It creates (or updates) a
+message file in the directory ``locale/LANG/LC_MESSAGES``. In the ``de``
+example, the file will be ``locale/de/LC_MESSAGES/django.po``.
+
+By default :djadmin:`django-admin.py makemessages <makemessages>` examines every
+file that has the ``.html`` or ``.txt`` file extension. In case you want to
+override that default, use the ``--extension`` or ``-e`` option to specify the
+file extensions to examine::
+
+ django-admin.py makemessages -l de -e txt
+
+Separate multiple extensions with commas and/or use ``-e`` or ``--extension``
+multiple times::
+
+ django-admin.py makemessages -l de -e html,txt -e xml
+
+.. warning::
+
+ When :ref:`creating message files from JavaScript source code
+ <creating-message-files-from-js-code>` you need to use the special
+ 'djangojs' domain, **not** ``-e js``.
+
+.. admonition:: No gettext?
+
+ If you don't have the ``gettext`` utilities installed,
+ :djadmin:`makemessages` will create empty files. If that's the case, either
+ install the ``gettext`` utilities or just copy the English message file
+ (``locale/en/LC_MESSAGES/django.po``) if available and use it as a starting
+ point; it's just an empty translation file.
+
+.. admonition:: Working on Windows?
+
+ If you're using Windows and need to install the GNU gettext utilities so
+ :djadmin:`makemessages` works, see :ref:`gettext_on_windows` for more
+ information.
+
+The format of ``.po`` files is straightforward. Each ``.po`` file contains a
+small bit of metadata, such as the translation maintainer's contact
+information, but the bulk of the file is a list of **messages** -- simple
+mappings between translation strings and the actual translated text for the
+particular language.
+
+For example, if your Django app contained a translation string for the text
+``"Welcome to my site."``, like so::
+
+ _("Welcome to my site.")
+
+...then :djadmin:`django-admin.py makemessages <makemessages>` will have created
+a ``.po`` file containing the following snippet -- a message::
+
+ #: path/to/python/module.py:23
+ msgid "Welcome to my site."
+ msgstr ""
+
+A quick explanation:
+
+* ``msgid`` is the translation string, which appears in the source. Don't
+ change it.
+* ``msgstr`` is where you put the language-specific translation. It starts
+ out empty, so it's your responsibility to change it. Make sure you keep
+ the quotes around your translation.
+* As a convenience, each message includes, in the form of a comment line
+ prefixed with ``#`` and located above the ``msgid`` line, the filename and
+ line number from which the translation string was gleaned.
+
+Long messages are a special case. There, the first string directly after the
+``msgstr`` (or ``msgid``) is an empty string. Then the content itself will be
+written over the next few lines as one string per line. Those strings are
+directly concatenated. Don't forget trailing spaces within the strings;
+otherwise, they'll be tacked together without whitespace!
+
+.. admonition:: Mind your charset
+
+ When creating a PO file with your favorite text editor, first edit
+ the charset line (search for ``"CHARSET"``) and set it to the charset
+ you'll be using to edit the content. Due to the way the ``gettext`` tools
+ work internally and because we want to allow non-ASCII source strings in
+ Django's core and your applications, you **must** use UTF-8 as the encoding
+ for your PO file. This means that everybody will be using the same
+ encoding, which is important when Django processes the PO files.
+
+To reexamine all source code and templates for new translation strings and
+update all message files for **all** languages, run this::
+
+ django-admin.py makemessages -a
+
+Compiling message files
+-----------------------
+
+After you create your message file -- and each time you make changes to it --
+you'll need to compile it into a more efficient form, for use by ``gettext``. Do
+this with the :djadmin:`django-admin.py compilemessages <compilemessages>`
+utility.
+
+This tool runs over all available ``.po`` files and creates ``.mo`` files, which
+are binary files optimized for use by ``gettext``. In the same directory from
+which you ran :djadmin:`django-admin.py makemessages <makemessages>`, run :djadmin:`django-admin.py compilemessages <compilemessages>` like this::
+
+ django-admin.py compilemessages
+
+That's it. Your translations are ready for use.
+
+.. admonition:: Working on Windows?
+
+ If you're using Windows and need to install the GNU gettext utilities so
+ :djadmin:`django-admin.py compilemessages <compilemessages>` works see
+ :ref:`gettext_on_windows` for more information.
+
+.. admonition:: .po files: Encoding and BOM usage.
+
+ Django only supports ``.po`` files encoded in UTF-8 and without any BOM
+ (Byte Order Mark) so if your text editor adds such marks to the beginning of
+ files by default then you will need to reconfigure it.
+
+.. _creating-message-files-from-js-code:
+
+Creating message files from JavaScript source code
+--------------------------------------------------
+
+You create and update the message files the same way as the other Django message
+files -- with the :djadmin:`django-admin.py makemessages <makemessages>` tool.
+The only difference is you need to explicitly specify what in gettext parlance
+is known as a domain in this case the ``djangojs`` domain, by providing a ``-d
+djangojs`` parameter, like this::
+
+ django-admin.py makemessages -d djangojs -l de
+
+This would create or update the message file for JavaScript for German. After
+updating message files, just run :djadmin:`django-admin.py compilemessages
+<compilemessages>` the same way as you do with normal Django message files.
+
+.. _gettext_on_windows:
+
+``gettext`` on Windows
+----------------------
+
+This is only needed for people who either want to extract message IDs or compile
+message files (``.po``). Translation work itself just involves editing existing
+files of this type, but if you want to create your own message files, or want to
+test or compile a changed message file, you will need the ``gettext`` utilities:
+
+* Download the following zip files from the GNOME servers
+ http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/ or from one
+ of its mirrors_
+
+ * ``gettext-runtime-X.zip``
+ * ``gettext-tools-X.zip``
+
+ ``X`` is the version number, we are requiring ``0.15`` or higher.
+
+* Extract the contents of the ``bin\`` directories in both files to the
+ same folder on your system (i.e. ``C:\Program Files\gettext-utils``)
+
+* Update the system PATH:
+
+ * ``Control Panel > System > Advanced > Environment Variables``.
+ * In the ``System variables`` list, click ``Path``, click ``Edit``.
+ * Add ``;C:\Program Files\gettext-utils\bin`` at the end of the
+ ``Variable value`` field.
+
+.. _mirrors: http://ftp.gnome.org/pub/GNOME/MIRRORS
+
+You may also use ``gettext`` binaries you have obtained elsewhere, so long as
+the ``xgettext --version`` command works properly. Do not attempt to use Django
+translation utilities with a ``gettext`` package if the command ``xgettext
+--version`` entered at a Windows command prompt causes a popup window saying
+"xgettext.exe has generated errors and will be closed by Windows".
+
+
+Miscellaneous
+=============
+
.. _set_language-redirect-view:
The ``set_language`` redirect view
-==================================
+----------------------------------
.. highlightlang:: python
@@ -1019,3 +1269,293 @@ Here's example HTML template code:
</select>
<input type="submit" value="Go" />
</form>
+
+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.
+
+Implementation notes
+====================
+
+.. _specialties-of-django-i18n:
+
+Specialties of Django translation
+---------------------------------
+
+Django's translation machinery uses the standard ``gettext`` module that comes
+with Python. If you know ``gettext``, you might note these specialties in the
+way Django does translation:
+
+* The string domain is ``django`` or ``djangojs``. This string domain is
+ used to differentiate between different programs that store their data
+ in a common message-file library (usually ``/usr/share/locale/``). The
+ ``django`` domain is used for python and template translation strings
+ and is loaded into the global translation catalogs. The ``djangojs``
+ domain is only used for JavaScript translation catalogs to make sure
+ that those are as small as possible.
+* Django doesn't use ``xgettext`` alone. It uses Python wrappers around
+ ``xgettext`` and ``msgfmt``. This is mostly for convenience.
+
+.. _how-django-discovers-language-preference:
+
+How Django discovers language preference
+----------------------------------------
+
+Once you've prepared your translations -- or, if you just want to use the
+translations that come with Django -- you'll just need to activate translation
+for your app.
+
+Behind the scenes, Django has a very flexible model of deciding which language
+should be used -- installation-wide, for a particular user, or both.
+
+To set an installation-wide language preference, set :setting:`LANGUAGE_CODE`.
+Django uses this language as the default translation -- the final attempt if no
+other translator finds a translation.
+
+If all you want to do is run Django with your native language, and a language
+file is available for it, all you need to do is set :setting:`LANGUAGE_CODE`.
+
+If you want to let each individual user specify which language he or she
+prefers, use ``LocaleMiddleware``. ``LocaleMiddleware`` enables language
+selection based on data from the request. It customizes content for each user.
+
+To use ``LocaleMiddleware``, add ``'django.middleware.locale.LocaleMiddleware'``
+to your :setting:`MIDDLEWARE_CLASSES` setting. Because middleware order
+matters, you should follow these guidelines:
+
+* Make sure it's one of the first middlewares installed.
+* It should come after ``SessionMiddleware``, because ``LocaleMiddleware``
+ makes use of session data. And it should come before ``CommonMiddleware``
+ because ``CommonMiddleware`` needs an activated language in order
+ to resolve the requested URL.
+* If you use ``CacheMiddleware``, put ``LocaleMiddleware`` after it.
+
+For example, your :setting:`MIDDLEWARE_CLASSES` might look like this::
+
+ MIDDLEWARE_CLASSES = (
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.locale.LocaleMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ )
+
+(For more on middleware, see the :doc:`middleware documentation
+</topics/http/middleware>`.)
+
+``LocaleMiddleware`` tries to determine the user's language preference by
+following this algorithm:
+
+.. versionchanged:: 1.4
+
+* First, it looks for the language prefix in the requested URL. This is
+ only performed when you are using the ``i18n_patterns`` function in your
+ root URLconf. See :ref:`url-internationalization` for more information
+ about the language prefix and how to internationalize URL patterns.
+
+* Failing that, it looks for a ``django_language`` key in the current
+ user's session.
+
+* Failing that, it looks for a cookie.
+
+ The name of the cookie used is set by the :setting:`LANGUAGE_COOKIE_NAME`
+ setting. (The default name is ``django_language``.)
+
+* Failing that, it looks at the ``Accept-Language`` HTTP header. This
+ header is sent by your browser and tells the server which language(s) you
+ prefer, in order by priority. Django tries each language in the header
+ until it finds one with available translations.
+
+* Failing that, it uses the global :setting:`LANGUAGE_CODE` setting.
+
+.. _locale-middleware-notes:
+
+Notes:
+
+* In each of these places, the language preference is expected to be in the
+ standard :term:`language format<language code>`, as a string. For example,
+ Brazilian Portuguese is ``pt-br``.
+
+* If a base language is available but the sublanguage specified is not,
+ Django uses the base language. For example, if a user specifies ``de-at``
+ (Austrian German) but Django only has ``de`` available, Django uses
+ ``de``.
+
+* Only languages listed in the :setting:`LANGUAGES` setting can be selected.
+ If you want to restrict the language selection to a subset of provided
+ languages (because your application doesn't provide all those languages),
+ set :setting:`LANGUAGES` to a list of languages. For example::
+
+ LANGUAGES = (
+ ('de', _('German')),
+ ('en', _('English')),
+ )
+
+ This example restricts languages that are available for automatic
+ selection to German and English (and any sublanguage, like de-ch or
+ en-us).
+
+* If you define a custom :setting:`LANGUAGES` setting, as explained in the
+ previous bullet, it's OK to mark the languages as translation strings
+ -- but use a "dummy" ``ugettext()`` function, not the one in
+ ``django.utils.translation``. You should *never* import
+ ``django.utils.translation`` from within your settings file, because that
+ module in itself depends on the settings, and that would cause a circular
+ import.
+
+ The solution is to use a "dummy" ``ugettext()`` function. Here's a sample
+ settings file::
+
+ ugettext = lambda s: s
+
+ LANGUAGES = (
+ ('de', ugettext('German')),
+ ('en', ugettext('English')),
+ )
+
+ With this arrangement, :djadmin:`django-admin.py makemessages <makemessages>`
+ will still find and mark these strings for translation, but the translation
+ won't happen at runtime -- so you'll have to remember to wrap the languages in
+ the *real* ``ugettext()`` in any code that uses :setting:`LANGUAGES` at
+ runtime.
+
+* The ``LocaleMiddleware`` can only select languages for which there is a
+ Django-provided base translation. If you want to provide translations
+ for your application that aren't already in the set of translations
+ in Django's source tree, you'll want to provide at least a basic
+ one as described in the :ref:`Locale restrictions<locale-restrictions>`
+ note.
+
+Once ``LocaleMiddleware`` determines the user's preference, it makes this
+preference available as ``request.LANGUAGE_CODE`` for each
+:class:`~django.http.HttpRequest`. Feel free to read this value in your view
+code. Here's a simple example::
+
+ def hello_world(request, count):
+ if request.LANGUAGE_CODE == 'de-at':
+ return HttpResponse("You prefer to read Austrian German.")
+ else:
+ return HttpResponse("You prefer to read another language.")
+
+Note that, with static (middleware-less) translation, the language is in
+``settings.LANGUAGE_CODE``, while with dynamic (middleware) translation, it's
+in ``request.LANGUAGE_CODE``.
+
+.. _settings file: ../settings/
+.. _middleware documentation: ../middleware/
+.. _session: ../sessions/
+.. _request object: ../request_response/#httprequest-objects
+
+.. _how-django-discovers-translations:
+
+How Django discovers translations
+---------------------------------
+
+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.
+
+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
+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.
+
+.. 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:
+
+* All paths listed in :setting:`LOCALE_PATHS` in your settings file are
+ 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)``
+* ``$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``.
+
+You can also run :djadmin:`django-admin.py compilemessages
+--settings=path.to.settings <compilemessages>` 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. But using
+app-specific translations and project-specific translations could produce weird
+problems with :djadmin:`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.
+
+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,
+:djadmin:`django-admin.py makemessages <makemessages>`, when ran on a project
+level will only extract strings that are connected to your explicit project and
+not strings that are distributed independently.
Please sign in to comment.
Something went wrong with that request. Please try again.