Django

Code

Changeset 1087

Show
Ignore:
Timestamp:
11/04/05 22:22:25 (3 years ago)
Author:
adrian
Message:

Moderately heavy rewrite of docs/translation.txt

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/docs/translation.txt

    r1068 r1087  
    1 ====================== 
    2 How to do translations 
    3 ====================== 
    4  
    5 Django has support for internationalization of program strings and template 
    6 content. Translations use the ``gettext`` library to produce strings in several 
    7 languages. Here's an overview of how translation works with Django. 
    8  
    9 The goal of this document is to explain how to use translations in projects, 
    10 how to add translations to Django patches and how to update and create 
    11 translation files. 
    12  
    13 Using translations in Python 
    14 ============================ 
    15  
    16 The translation machinery in Django uses the standard ``gettext`` module that 
    17 comes with Python. Django uses in its own functions and classes, but it uses 
    18 standard ``gettext`` machinery under the hood. 
    19  
    20 To translate strings in your code, use one of the ``gettext`` helper functions. 
    21 There are essentially two ways to use them: 
    22  
    23     * Use the ``_()`` function, which is available globally. This function 
    24       translates any string value. 
    25     * Use ``django.utils.translation`` and import ``gettext`` or 
    26       ``gettext_noop`` from there. ``gettext`` is identical to ``_()``. 
    27  
    28 Note one important thing about translations: The system can only translate 
    29 strings it knows about. That means you have to mark strings for translation. 
    30 This is done either by calling ``_()``, ``gettext()`` or ``gettext_noop()`` on 
    31 string constants. You can translate variable values or computed values, but the 
    32 system needs to know those strings beforehand. 
    33  
    34 The usual method is to build your strings using string interpolation and using 
    35 the ``gettext`` functions to do the actual translation. Example:: 
    36  
    37     def hello_world(request, name, site): 
    38         page = _('Hello %(name)s, welcome to %(site)s!') % { 
    39             'name': name, 
    40             'site': site, 
    41         } 
    42         return HttpResponse(page) 
    43  
    44 This short snippet shows one important thing: You shouldn't use positional 
    45 string interpolation (e.g., ``%s`` or ``%d``). Use the named string 
    46 interpolation (e.g., ``%(name)s``), instead. Do this because other languages 
    47 might require reordering of text. 
    48  
    49 The other two helper functions are similar:: 
     1==================== 
     2Internationalization 
     3==================== 
     4 
     5Django has full support for internationalization of text in code and templates. 
     6Here's an overview of how translation works in Django. 
     7 
     8.. admonition:: Behind the scenes 
     9 
     10    Django's translation machinery uses the standard ``gettext`` module that 
     11    comes with Python. 
     12 
     13Overview 
     14======== 
     15 
     16The goal of internationalization is to allow a single Web application to offer 
     17its content and functionality in multiple languages. 
     18 
     19You, the Django developer, can accomplish this goal by adding a minimal amount 
     20of hooks to your Python code and templates. These hooks are called 
     21**translation strings**. They tell Django: "This text should be translated into 
     22the end user's language, if a translation for this text is available in that 
     23language." 
     24 
     25Django takes care of using these hooks to translate Web apps, on the fly, 
     26according to users' language preferences. 
     27 
     28Essentially, Django does two things: 
     29 
     30    * It lets developers and template authors specify which parts of their apps 
     31      should be translatable. 
     32    * It uses these hooks to translate Web apps for particular users according 
     33      to their language preferences. 
     34 
     35How to internationalize your app: in three steps 
     36------------------------------------------------ 
     37 
     38    1. Embed translation strings in your Python code and templates. 
     39    2. Get translations for those strings, in whichever languages you want to 
     40       support. 
     41    2. Activate the locale middleware in your Django settings. 
     42 
     43How to specify translation strings 
     44================================== 
     45 
     46Translation strings specify "This text should be translated." These strings can 
     47appear in your Python code and templates. It's your responsibility to mark 
     48translatable strings; the system can only translate strings it knows about. 
     49 
     50In Python code 
     51-------------- 
     52 
     53Standard translation 
     54~~~~~~~~~~~~~~~~~~~~ 
     55 
     56Specify a translation string by using the function ``_()``. (Yes, the name of 
     57the function is the "underscore" character.) This function is available 
     58globally in any Python module; you don't have to import it. 
     59 
     60In this example, the text ``"Welcome to my site."`` is marked as a translation 
     61string:: 
     62 
     63    def my_view(request): 
     64        output = _("Welcome to my site.") 
     65        return HttpResponse(output) 
     66 
     67The function ``django.utils.translation.gettext()`` is identical to ``_()``. 
     68This example is identical to the previous one:: 
    5069 
    5170    from django.utils.translation import gettext 
    52     def hello_world(request, name, site): 
    53         page = gettext('Hello %(name)s, welcome to %(site)s!') % { 
    54             'name': name, 
    55             'site': site, 
    56         } 
    57         return HttpResponse(page) 
    58  
    59 The difference here is that ``gettext`` is explicitly imported. 
    60  
    61 Two important helper functions are available: ``gettext`` and ``gettext_noop``. 
    62  
    63     * ``gettext`` is just like ``_()`` -- it translates its argument. 
    64     * ``gettext_noop`` is different. It marks a string for inclusion into the 
    65       message file but doesn't do translation. Instead, the string is later 
    66       translated from a variable. Use this if you have constant strings that 
    67       should be stored in the source language because they are exchanged over 
    68       systems or users -- such as strings in a database -- but should be 
    69       translated at the last possible point in time, such as when the string is 
    70       presented to the user. 
    71  
    72 One function, ``django.utils.translation.gettext_lazy()``, isn't available in 
    73 the standard ``gettext`` module. Use it for lazily translated strings, such as 
    74 messages in Django models that are stored internally and translated on access 
    75 -- but not translated on storage, as that would only take the default language 
    76 into account. 
     71    def my_view(request): 
     72        output = gettext("Welcome to my site.") 
     73        return HttpResponse(output) 
     74 
     75Translation works on computed values. This example is identical to the previous 
     76two:: 
     77 
     78    def my_view(request): 
     79        words = ['Welcome', 'to', 'my', 'site.'] 
     80        output = _(' '.join(words)) 
     81        return HttpResponse(output) 
     82 
     83Translation works on variables. Again, here's an identical example:: 
     84 
     85    def my_view(request): 
     86        sentence = 'Welcome to my site.' 
     87        output = _(sentence) 
     88        return HttpResponse(output) 
     89 
     90The strings you pass to ``_()`` or ``gettext()`` can take placeholders, 
     91specified with Python's standard named-string interpolation syntax. Example:: 
     92 
     93    def my_view(request, n): 
     94        output = _('%(name)s is my name.') % {'name': n} 
     95        return HttpResponse(output) 
     96 
     97This technique lets language-specific translations reorder the placeholder 
     98text. For example, an English translation may be ``"Adrian is my name."``, 
     99while a Spanish translation may be ``"Me llamo Adrian."`` -- with the 
     100placeholder (the name) placed after the translated text instead of before it. 
     101 
     102For this reason, you should use named-string interpolation (e.g., ``%(name)s``) 
     103instead of positional interpolation (e.g., ``%s`` or ``%d``). If you used 
     104positional interpolation, translations wouldn't be able to reorder placeholder 
     105text. 
     106 
     107Marking strings as no-op 
     108~~~~~~~~~~~~~~~~~~~~~~~~ 
     109 
     110Use the function ``django.utils.translation.gettext_noop()`` to mark a string 
     111as a translate string without translating it. The string is later translated 
     112from a variable. 
     113 
     114Use this if you have constant strings that should be stored in the source 
     115language because they are exchanged over systems or users -- such as strings in 
     116a database -- but should be translated at the last possible point in time, such 
     117as when the string is presented to the user. 
     118 
     119Lazy translation 
     120~~~~~~~~~~~~~~~~ 
     121 
     122Use the function ``django.utils.translation.gettext_lazy()`` to translate 
     123strings lazily -- when the value is accessed rather than when the 
     124``gettext_lazy()`` function is called. 
    77125 
    78126For example, to translate a model's ``help_text``, do the following:: 
     
    108156            verbose_name_plural = _('mythings') 
    109157 
    110 A standard problem with translations is pluralization of strings. Use 
    111 ``ngettext`` to solve this problem. Example:: 
    112  
     158Pluralization 
     159~~~~~~~~~~~~~ 
     160 
     161Use the function ``django.utils.translation.ngettext()`` to specify pluralized 
     162messages. Example:: 
     163 
     164    from django.utils.translation import ngettext 
    113165    def hello_world(request, count): 
    114         from django.utils.translation import ngettext 
    115166        page = ngettext('there is %(count)d object', 'there are %(count)d objects', count) % { 
    116167            'count': count, 
     
    118169        return HttpResponse(page) 
    119170 
    120 Using translations in templates 
    121 =============================== 
     171``ngettext`` takes three arguments: the singular translation string, the plural 
     172translation string and the number of objects (which is passed to the 
     173translation languages as the ``count`` variable). 
     174 
     175In template code 
     176---------------- 
    122177 
    123178Using translations in Django templates uses two template tags and a slightly 
    124 different syntax than standard gettext. The ``{% trans %}`` template tag 
    125 translates a constant string or a variable content:: 
    126  
    127     <title>{% trans 'This is the title.' %}</title> 
    128  
    129 If you only want to mark some value for translation, but translate it 
    130 later from a variable, use the ``noop`` option:: 
    131  
    132     <input name="field" value="{% trans "value" noop %}"/> 
    133  
    134 It is not possible to use variables in this constant string. If you 
    135 have variables you need to put in your translations, you have to use the 
    136 ``{% blocktrans %}`` tag:: 
    137  
    138     {% blocktrans %}This will have {{ value }} inside{% endblocktrans %} 
    139  
    140 If your expressions are more complex (like you need to have filters applied), 
    141 you need to bind them to local variables for the translation block:: 
    142  
    143     {% blocktrans with value|filter as variable %} 
    144     This will have {{ value }} inside 
     179different syntax than in Python code. To give your template access to these 
     180tags, put ``{% load i18n %}`` toward the top of your template. 
     181 
     182The ``{% trans %}`` template tag translates a constant string or a variable 
     183content:: 
     184 
     185    <title>{% trans "This is the title." %}</title> 
     186 
     187If you only want to mark a value for translation, but translate it later from a 
     188variable, use the ``noop`` option:: 
     189 
     190    <title>{% trans "value" noop %}</title> 
     191 
     192It's not possible to use template variables in ``{% trans %}`` -- only constant 
     193strings, in single or double quotes, are allowed. If your translations require 
     194variables (placeholders), use ``{% blocktrans %}``. Example:: 
     195 
     196    {% blocktrans %}This will have {{ value }} inside.{% endblocktrans %} 
     197 
     198To translate a template expression -- say, using template filters -- you need 
     199to bind the expression to a local variable for use within the translation 
     200block:: 
     201 
     202    {% blocktrans with value|filter as myvar %} 
     203    This will have {{ myvar }} inside. 
    145204    {% endblocktrans %} 
    146205 
    147 The last variant is the pluralization form: you need to specify both the singular 
    148 and plural sentence with intersparsed variables like this:: 
     206To pluralize, specify both the singular and plural forms with the 
     207``{% plural %}`` tag, which appears within ``{% blocktrans %}`` and 
     208``{% endblocktrans %}``. Example:: 
    149209 
    150210    {% blocktrans count list|counted as counter %} 
     
    154214    {% endblocktrans %} 
    155215 
    156 Internally all block translations and inline translations are translated into 
    157 the actual gettext/ngettext call. 
     216Internally, all block and inline translations use the appropriate 
     217``gettext`` / ``ngettext`` call. 
    158218 
    159219Each ``DjangoContext`` has access to two translation-specific variables: 
     
    170230    {% get_available_languages as LANGUAGES %} 
    171231 
    172 All tags live in the ``i18n`` tag library, so you need to specify 
    173 ``{% load i18n %}`` in the head of your template to make use of them. 
    174  
    175 There are some places where you will encounter constant strings in your template code. 
    176 One is filter arguments, the other are normal string constants for tags. If you need to 
    177 translate those, you can use the ``_("....")`` syntax:: 
     232These tags also require a ``{% load i18n %}``. 
     233 
     234Translation hooks are also available within any template block tag that accepts 
     235constant strings. In those cases, just use ``_()`` syntax to specify a 
     236translation string. Example:: 
    178237 
    179238    {% some_special_tag _("Page not found") value|yesno:_("yes,no") %} 
    180239 
    181 In this case both the filter and the tag will see the already translated string, so they 
    182 don't need to be aware of translations. And both strings will be pulled out of the templates 
    183 for translation and stored in the .po files. 
    184  
    185 The ``setlang`` redirect view 
    186 ----------------------------- 
    187  
    188 Django comes with a view, ``django.views.i18n.set_language`` that sets a user's 
    189 language preference and redirects back to the previous page. For example, put 
    190 this HTML code in your template:: 
    191  
    192     <form action="/i18n/setlang/" method="POST"> 
     240In this case, both the tag and the filter will see the already-translated 
     241string, so they don't need to be aware of translations. 
     242 
     243How to create language files 
     244============================ 
     245 
     246Once you've tagged your strings for later translation, you need to write (or 
     247obtain) the language translations themselves. Here's how that works. 
     248 
     249Message files 
     250------------- 
     251 
     252The first step is to create a **message file** for a new language. A message 
     253file is a plain-text file, representing a single language, that contains all 
     254available translation strings and how they should be represented in the given 
     255language. Message files have a ``.po`` file extension. 
     256 
     257Django comes with a tool, ``bin/make-messages.py``, that automates the creation 
     258and upkeep of these files. 
     259 
     260To create or update a message file, run this command:: 
     261 
     262    bin/make-messages.py -l de 
     263 
     264...where ``de`` is the language code for the message file you want to create. 
     265(The language code, in this case, is in locale format. So, for example, it's 
     266``pt_BR`` for Brazilian and ``de_AT`` for Austrian German.) 
     267 
     268The script should be run from one of three places:: 
     269 
     270    * The root ``django`` directory (not a Subversion checkout, but the one 
     271      that is linked-to via ``$PYTHONPATH`` or is located somewhere on that 
     272      path). 
     273    * The root directory of your Django project. 
     274    * The root directory of your Django app. 
     275 
     276The script runs over the entire Django source tree and pulls out all strings 
     277marked for translation. It creates (or updates) a message file in the directory 
     278``conf/locale``. In the ``de`` example, the file will be 
     279``conf/locale/de/LC_MESSAGES/django.po``. 
     280 
     281.. admonition:: No gettext? 
     282 
     283    If you don't have the ``gettext`` utilities installed, ``make-messages.py`` 
     284    will create empty files. If that's the case, either install the ``gettext`` 
     285    utilities or just copy the English message file 
     286    (``conf/locale/en/LC_MESSAGES/django.po``) and use it as a starting point; 
     287    it's just an empty translation file. 
     288 
     289The format of ``.po`` files is straightforward. Each ``.po`` file contains a 
     290small bit of metadata, such as the translation maintainer's contact 
     291information, but the bulk of the file is a list of **messages** -- simple 
     292mappings between translation strings and the actual translated text for the 
     293particular language. 
     294 
     295For example, if your Django app contained a translation string for the text 
     296``"Welcome to my site.", like so:: 
     297 
     298    _("Welcome to my site.") 
     299 
     300...then ``make-messages.py`` will have created a ``.po`` file containing the 
     301following snippet -- a message:: 
     302 
     303    #: path/to/python/module.py:23 
     304    msgid "Welcome to my site." 
     305    msgstr "" 
     306 
     307A quick explanation: 
     308 
     309    * ``msgid`` is the translation string, which appears in the source. Don't 
     310      change it. 
     311    * ``msgstr`` is where you put the language-specific translation. It starts 
     312      out empty, so it's your responsibility to change it. Make sure you keep 
     313      the quotes around your translation. 
     314    * As a convenience, each message includes the filename and line number 
     315      from which the translation string was gleaned. 
     316 
     317Long messages are a special case. There, the first string directly after the 
     318``msgstr`` (or ``msgid``) is an empty string. Then the content itself will be 
     319written over the next few lines as one string per line. Those strings are 
     320directlyconcatenated. Don't forget trailing spaces within the strings; 
     321otherwise, they'll be tacked together without whitespace! 
     322 
     323.. admonition:: Mind your charset 
     324 
     325    When creating a ``.po`` file with your favorite text editor, first edit 
     326    the charset line (search for ``"CHARSET"``) and set it to the charset 
     327    you'll be using to edit the content. Generally, utf-8 should work for most 
     328    languages, but ``gettext`` can handle any charset you throw at it. 
     329 
     330To reexamine all source code and templates for new translation strings and 
     331update all message files for **all** languages, run ``make-messages.py -a``. 
     332 
     333Compiling message files 
     334----------------------- 
     335 
     336After you create your message file -- and each time you make changes to it -- 
     337you'll need to compile it into a more efficient form, for use by ``gettext``. 
     338Do this with the ``bin/compile-messages.py`` utility. 
     339 
     340This tool runs over all available ``.po`` files and creates ``.mo`` files, 
     341which are binary files optimized for use by ``gettext``. In the same directory 
     342from which you ran ``make-messages.py``, run ``compile-messages.py`` like 
     343this:: 
     344 
     345   bin/compile-messages.py 
     346 
     347That's it. Your translations are ready for use. 
     348 
     349.. admonition:: A note to translators 
     350 
     351    If you've created a translation in a language Django doesn't yet support, 
     352    please let us know! We'll add it to the global list of available languages 
     353    in the global Django settings (``settings.LANGUAGES``). 
     354 
     355How Django discovers language preference 
     356======================================== 
     357 
     358Once you've prepared your translations -- or, if you just want to use the 
     359translations that come with Django -- you'll just need to activate translation 
     360for your app. 
     361 
     362Behind the scenes, Django has a very flexible model of deciding which language 
     363should be used -- installation-wide, for a particular user, or both. 
     364 
     365To set an installation-wide language preference, set ``LANGUAGE_CODE`` in your 
     366`settings file`_. Django uses this language as the default translation -- the 
     367final attempt if no other translator finds a translation. 
     368 
     369If all you want to do is run Django with your native language, and a language 
     370file is available for your language, all you need to do is set 
     371``LANGUAGE_CODE``. 
     372 
     373If you want to let each individual user specify which language he or she 
     374prefers, use ``LocaleMiddleware``. ``LocaleMiddleware`` enables language 
     375selection based on data from the request. It customizes content for each user. 
     376 
     377To use ``LocaleMiddleware``, add ``'django.middleware.locale.LocaleMiddleware'`` 
     378to your ``MIDDLEWARE_CLASSES`` setting. Because middleware order matters, you 
     379should follow these guidelines: 
     380 
     381    * Make sure it's one of the first middlewares installed. 
     382    * It should come after ``SessionMiddleware``, because ``LocaleMiddleware`` 
     383      makes use of session data. 
     384 
     385For example, your ``MIDDLEWARE_CLASSES`` might look like this:: 
     386 
     387    MIDDLEWARE_CLASSES = ( 
     388       'django.middleware.sessions.SessionMiddleware', 
     389       'django.middleware.locale.LocaleMiddleware', 
     390       'django.middleware.common.CommonMiddleware', 
     391    ) 
     392 
     393(For more on middleware, see the `middleware documentation`_.) 
     394 
     395``LocaleMiddleware`` tries to determine the user's language preference by 
     396following this algorithm: 
     397 
     398    * First, it looks for a ``django_language`` key in the the current user's 
     399      `session`_. 
     400    * Failing that, it looks for a cookie called ``django_language``. 
     401    * Failing that, it looks at the ``Accept-Language`` HTTP header. This 
     402      header is sent by your browser and tells the server which language(s) you 
     403      prefer, in order by priority. Django tries each language in the header 
     404      until it finds one with available translations. 
     405    * Failing that, it uses the global ``LANGUAGE_CODE`` setting. 
     406 
     407Notes: 
     408 
     409    * In each of these places, the language preference is expected to be in the 
     410      standard language format, as a string. For example, Brazilian is 
     411      ``pt-br``. 
     412    * If a base language is available but the sublanguage specified is not, 
     413      Django uses the base language. For example, if a user specifies ``de-at`` 
     414      (Austrian German) but Django only has ``de`` available, Django uses 
     415      ``de``. 
     416 
     417Once ``LocaleMiddleware`` determines the user's preference, it makes this 
     418preference available as ``request.LANGUAGE_CODE`` for each `request object`_. 
     419Feel free to read this value in your view code. Here's a simple example:: 
     420 
     421    def hello_world(request, count): 
     422        if request.LANGUAGE_CODE == 'de-at': 
     423            return HttpResponse("You prefer to read Austrian German.") 
     424        else: 
     425            return HttpResponse("You prefer to read another language.") 
     426 
     427Note that, with static (middleware-less) translation, the language is in 
     428``settings.LANGUAGE_CODE``, while with dynamic (middleware) translation, it's 
     429in ``request.LANGUAGE_CODE``. 
     430 
     431.. _settings file: http://www.djangoproject.com/documentation/settings/ 
     432.. _middleware documentation: http://www.djangoproject.com/documentation/middleware/ 
     433.. _session: http://www.djangoproject.com/documentation/sessions/ 
     434.. _request object: http://www.djangoproject.com/documentation/request_response/#httprequest-objects 
     435 
     436The ``set_language`` redirect view 
     437================================== 
     438 
     439As a convenience, Django comes with a view, ``django.views.i18n.set_language``, 
     440that sets a user's language preference and redirects back to the previous page. 
     441 
     442Activate this view by adding the following line to your URLconf:: 
     443 
     444    (r'^i18n/', include('django.conf.urls.i18n'), 
     445 
     446(Note that this example makes the view available at ``/i18n/setlang/``.) 
     447 
     448The view expects to be called via the ``GET`` method, with a ``language`` 
     449parameter set in the query string. If session support is enabled, the view 
     450saves the language choice in the user's session. Otherwise, it saves the 
     451language choice in a ``django_language`` cookie. 
     452 
     453After setting the language choice, Django redirects the user, following this 
     454algorithm: 
     455 
     456    * Django looks for a ``next`` parameter in the query string. 
     457    * If that doesn't exist, or is empty, Django tries the URL in the 
     458      ``Referer`` header. 
     459    * If that's empty -- say, if a user's browser suppresses that header -- 
     460      then the user will be redirected to ``/`` (the site root) as a fallback. 
     461 
     462Here's example HTML template code:: 
     463 
     464    <form action="/i18n/setlang/" method="get"> 
    193465    <input name="next" type="hidden" value="/next/page/" /> 
    194466    <select name="language"> 
     
    200472    </form> 
    201473 
    202 When a user submits the form, his chosen language will be saved in a cookie, 
    203 and he'll be redirected either to the URL specified in the ``next`` field, or, 
    204 if ``next`` is empty, to the URL in the ``Referer`` header. If the ``Referer`` 
    205 is blank -- say, if a user's browser suppresses that header -- then the user 
    206 will be redirected to ``/`` (the site root) as a fallback. 
    207  
    208 Activate the ``setlang`` redirect view by adding the following line to your 
    209 URLconf:: 
    210  
    211     (r'^i18n/', include('django.conf.urls.i18n'), 
    212  
    213 Note that this example makes the view available at ``/i18n/setlang/``. 
    214  
    215 How language preference is discovered 
    216 ===================================== 
    217  
    218 Django has a very flexible model of deciding which language should be used -- 
    219 installation-wide, for a particular user, or both. 
    220  
    221 To set an installation-wide language preference, set ``LANGUAGE_CODE`` in your 
    222 settings file. Django uses this language as the default translation -- the 
    223 final attempt if no other translator finds a translation. 
    224  
    225 If all you want to do is run Django with your native language, and a language 
    226 file is available for your language, all you need to do is set 
    227 ``LANGUAGE_CODE``. 
    228  
    229 If you want to let each individual user specify which language he or she 
    230 prefers, use ``LocaleMiddleware``. ``LocaleMiddleware`` enables language 
    231 selection based on data from the request. It lets each user have his or her own 
    232 setting. 
    233  
    234 To use ``LocaleMiddleware``, add ``'django.middleware.locale.LocaleMiddleware'`` 
    235 to your ``MIDDLEWARE_CLASSES`` setting. Because middleware order matters, you 
    236 should follow these guidelines: 
    237  
    238     * Make sure it's one of the first middlewares installed. 
    239     * It should come after ``SessionMiddleware``, because ``LocaleMiddleware`` 
    240       makes use of session data. 
    241  
    242 For example, your ``MIDDLEWARE_CLASSES`` might look like this:: 
    243  
    244     MIDDLEWARE_CLASSES = ( 
    245        'django.middleware.sessions.SessionMiddleware', 
    246        'django.middleware.locale.LocaleMiddleware', 
    247        'django.middleware.common.CommonMiddleware', 
    248     ) 
    249  
    250 ``LocaleMiddleware`` tries to determine the user's language preference by 
    251 following this algorithm: 
    252  
    253     * First, it looks for a ``django_language`` key in the the current user's 
    254       session. 
    255     * Failing that, it looks for a cookie called ``django_language``. 
    256     * Failing that, it looks at the ``Accept-Language`` HTTP header. This 
    257       header is sent by your browser and tells the server which language(s) you 
    258       prefer, in order by priority. Django tries each language in the header 
    259       until it finds one with available translations. 
    260     * Failing that, it uses the global ``LANGUAGE_CODE`` setting. 
    261  
    262 Notes: 
    263  
    264     * In each of these places, the language preference is expected to be in the 
    265       standard language format, as a string. For example, Brazilian is 
    266       ``pt-br``. 
    267     * If a base language is available but the sublanguage specified is not, 
    268       Django uses the base language. For example, if a user specifies ``de-at`` 
    269       (Austrian German) but Django only has ``de`` available, Django uses 
    270       ``de``. 
    271  
    272 Once ``LocaleMiddleware`` determines the user's preference, it makes this 
    273 preference available as ``request.LANGUAGE_CODE`` for each `request object`_. 
    274 Feel free to read this value in your view code. Here's a simple example:: 
    275  
    276     def hello_world(request, count): 
    277         if request.LANGUAGE_CODE == 'de-at': 
    278             return HttpResponse("You prefer to read Austrian German.") 
    279         else: 
    280             return HttpResponse("You prefer to read another language.") 
    281  
    282 Note that, with static (middleware-less) translation, the language is in 
    283 ``settings.LANGUAGE_CODE``, while with dynamic (middleware) translation, it's 
    284 in ``request.LANGUAGE_CODE``. 
    285  
    286 .. _request object: http://www.djangoproject.com/documentation/request_response/#httprequest-objects 
    287  
    288 Creating language files 
    289 ======================= 
    290  
    291 So, you've tagged all of your strings for later translation. But you need to 
    292 write the translations themselves. 
    293  
    294 They need to be in a format grokable by ``gettext``. You need to update them. 
    295 You may need to create new ones for new languages. This section shows you how 
    296 to do it. 
    297  
    298 Creating message files 
    299 ---------------------- 
    300  
    301 The first step is to create a message file for a new language. Django comes 
    302 with a tool, ``make-messages.py``, that automates this. 
    303  
    304 To run it on the Django source tree, navigate to the ``django`` directory 
    305 itself -- not a Subversion check out, but the one linked to via ``$PYTHONPATH`` 
    306 or located somewhere on that path. 
    307  
    308 Then run this command:: 
    309  
    310     bin/make-messages.py -l de 
    311  
    312 ...where ``de`` is the language code for the message file you want to create. 
    313  
    314 This script runs over the entire Django source tree and pulls out all strings 
    315 marked for translation, creating or updating the language's message file. 
    316  
    317 When it's done, it will have created (or updated) a message file under the 
    318 directory ``conf/locale``. In this example, the file will be 
    319 ``conf/locale/de/LC_MESSAGES/django.po``. 
    320  
    321 If you don't have the ``gettext`` utilities installed, ``make-messages.py`` 
    322 will create empty files. If that's the case, either install the ``gettext`` 
    323 utilities or just copy the English message file 
    324 (``conf/locale/en/LC_MESSAGES/django.po``) and use it as a starting point; it's 
    325 just an empty translation file. 
    326  
    327 Once you've created the ``.po`` file, edit the file with your favorite text 
    328 editor. First, edit the charset line (search for ``"CHARSET"``) and set it to 
    329 the charset you'll be using to edit the content. Then, proceed to write your 
    330 translations. 
    331  
    332 The language code for storage is in locale format -- so it's ``pt_BR`` for 
    333 Brazilian and ``de_AT`` for Austrian German. 
    334  
    335 Every message in the message file is in the same format: 
    336  
    337     * One line is the msgid. This is the actual string in the source. Don't 
    338       change it. 
    339     * The other line is msgstr. This is the translation. It starts out empty. 
    340       You change it. 
    341  
    342 Long messages are a special case. There, the first string directly after the 
    343 msgstr (or msgid) is an empty string. Then the content itself will be written 
    344 over the next few lines as one string per line. Those strings are directly 
    345 concatenated. Don't forget trailing spaces within the strings; otherwise, 
    346 they'll be tacked together without whitespace! 
    347  
    348 Compiling message files 
    349 ----------------------- 
    350  
    351 After you create your message file, you'll need to transform it into a more 
    352 efficient form to be read by ``gettext``. Do this with the 
    353 ``compile-messages.py`` utility. This tool runs over all available ``.po`` 
    354 files and creates ``.mo`` files. Run it like this:: 
    355  
    356    bin/compile-messages.py 
    357  
    358 That's it. You made your first translation. Now, if you configure your browser 
    359 to request your language, Django apps will use your language preference. 
    360  
    361 Another thing: Please submit the name of your newly-created language in that 
    362 native language, so we can add it to the global list of available languages 
    363 that is mirrored in ``settings.LANGUAGES`` (and the ``LANGUAGES`` template 
    364 variable). 
    365  
    366474Using translations in your own projects 
    367475======================================= 
    368  
    369 Of course, your own projects should make use of translations. Django makes this 
    370 simple, because it looks for message files in several locations. 
    371476 
    372477Django looks for translations by following this algorithm: 
     
    380485 
    381486This way, you can write applications that include their own translations, and 
    382 you can override base translations in your project path if you want to do that. 
    383 Or, you can just build a big project out of several apps and put all 
    384 translations into one big project message file. The choice is yours. 
     487you can override base translations in your project path. Or, you can just build 
     488a big project out of several apps and put all translations into one big project 
     489message file. The choice is yours. 
    385490 
    386491All message file repositories are structured the same way. They are: 
     
    388493    * ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)`` 
    389494    * ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)`` 
    390     * all paths listed in ``LOCALE_PATHS`` in your settings file are 
     495    * All paths listed in ``LOCALE_PATHS`` in your settings file are 
    391496      searched in that order for ``<language>/LC_MESSAGES/django.(po|mo)`` 
    392497    * ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)`` 
     
    407512be used in other projects, you might want to use app-specific translations. 
    408513But using app-specific translations and project translations could produce 
    409 weird problems with ``make-messages``: ``make-messages`` will traverse all directories 
    410 below the current path and so might put message IDs into the project 
    411 message file that are already in application message files. 
     514weird problems with ``make-messages``: ``make-messages`` will traverse all 
     515directories below the current path and so might put message IDs into the 
     516project message file that are already in application message files. 
    412517 
    413518The easiest way out is to store applications that are not part of the project 
     
    425530    * The string domain is always ``django``. The string domain is used to 
    426531      differentiate between different programs that store their data in a 
    427       common messagefile library (usually ``/usr/share/locale/``). In Django's 
     532      common message-file library (usually ``/usr/share/locale/``). In Django's 
    428533      case, there are Django-specific locale libraries, so the domain itself 
    429534      isn't used. We could store app message files with different names and put