Browse Source

Fixed #17087 -- Re-organized the i18n docs to reduce confusion between 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

Aymeric Augustin 13 years ago
parent
commit
67e6e0fcf3

+ 0 - 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.

+ 0 - 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

+ 1 - 1
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

+ 11 - 11
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

+ 1 - 1
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
 ==============

+ 8 - 8
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`
 

+ 1 - 1
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)
 

+ 3 - 6
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`_
 

+ 0 - 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.

+ 182 - 0
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.

+ 47 - 49
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.

+ 0 - 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.

+ 586 - 46
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.