Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixes #8847 - a bunch of cleanups to the i18n docs. Thanks, ramiro!

git-svn-id: http://code.djangoproject.com/svn/django/trunk@8946 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit ee28ee9311bb6e6d74d5c6cdaef7d7a20b6b6efe 1 parent 8df1580
Jacob Kaplan-Moss authored September 03, 2008
38  docs/internals/contributing.txt
@@ -388,21 +388,39 @@ the ticket database:
388 388
 Submitting and maintaining translations
389 389
 =======================================
390 390
 
391  
-Various parts of Django, such as the admin site and validator error messages,
  391
+Various parts of Django, such as the admin site and validation error messages,
392 392
 are internationalized. This means they display different text depending on a
393  
-user's language setting.
  393
+user's language setting. For this, Django uses the same internationalization
  394
+infrastructure that is available to Django applications that is described
  395
+in the :ref:`i18n documentation<topics-i18n>`.
394 396
 
395 397
 These translations are contributed by Django users worldwide. If you find an
396 398
 incorrect translation, or if you'd like to add a language that isn't yet
397 399
 translated, here's what to do:
398 400
 
399 401
     * Join the `Django i18n mailing list`_ and introduce yourself.
400  
-    * Create translations using the methods described in the
401  
-      :ref:`i18n documentation <topics-i18n>`.
402  
-    * Create a diff of the ``.po`` file against the current Subversion trunk.
403  
-    * Make sure that `` django-admin.py compilemessages -l <lang>`` runs without
  402
+    
  403
+    * Create translations using the methods described in the :ref:`i18n
  404
+      documentation <topics-i18n>`. For this you will use the ``django-admin.py
  405
+      makemessages`` tool. In this particular case it should be run from the
  406
+      top-level``django`` directory of the Django source tree.
  407
+
  408
+      The script runs over the entire Django source tree and pulls out all
  409
+      strings marked for translation. It creates (or updates) a message file in
  410
+      the directory ``conf/locale`` (for example for ``pt-BR``, the file will be
  411
+      ``conf/locale/pt-br/LC_MESSAGES/django.po``).
  412
+      
  413
+    * Make sure that ``django-admin.py compilemessages -l <lang>`` runs without
404 414
       producing any warnings.
405  
-    * Attach the patch to a ticket in Django's ticket system.
  415
+    
  416
+    * Repeat the last two steps for the ``djangojs`` domain (by appending the
  417
+      ``-d djangojs`` command line option to the ``django-admin.py``
  418
+      invocations.
  419
+    
  420
+    * Create a diff of the ``.po`` file(s) against the current Subversion trunk.
  421
+    
  422
+    * Open a ticket in Django's ticket system, set its ``Component`` field to
  423
+      ``Translations``, and attach the patch to it.
406 424
 
407 425
 .. _Django i18n mailing list: http://groups.google.com/group/django-i18n/
408 426
 
@@ -457,13 +475,13 @@ Template style
457 475
       brackets and the tag contents.
458 476
 
459 477
       Do this:
460  
-      
  478
+
461 479
       .. code-block:: html+django
462 480
 
463 481
           {{ foo }}
464 482
 
465 483
       Don't do this:
466  
-      
  484
+
467 485
       .. code-block:: html+django
468 486
 
469 487
           {{foo}}
@@ -743,7 +761,7 @@ You will also need to ensure that your database uses UTF-8 as the default
743 761
 character set. If your database server doesn't use UTF-8 as a default charset,
744 762
 you will need to include a value for ``TEST_DATABASE_CHARSET`` in your settings
745 763
 file.
746  
-   
  764
+
747 765
 If you want to run the full suite of tests, you'll need to install a number of
748 766
 dependencies:
749 767
 
136  docs/topics/i18n.txt
@@ -87,6 +87,8 @@ convention to import this as a shorter alias, ``_``, to save typing.
87 87
          global ``_()`` function causes interference. Explicitly importing
88 88
          ``ugettext()`` as ``_()`` avoids this problem.
89 89
 
  90
+.. highlightlang:: python
  91
+
90 92
 In this example, the text ``"Welcome to my site."`` is marked as a translation
91 93
 string::
92 94
 
@@ -128,16 +130,16 @@ examples, is that Django's translation-string-detecting utility,
128 130
 The strings you pass to ``_()`` or ``ugettext()`` can take placeholders,
129 131
 specified with Python's standard named-string interpolation syntax. Example::
130 132
 
131  
-    def my_view(request, n):
132  
-        output = _('%(name)s is my name.') % {'name': n}
  133
+    def my_view(request, m, d):
  134
+        output = _('Today is %(month)s, %s(day)s.') % {'month': m, 'day': d}
133 135
         return HttpResponse(output)
134 136
 
135 137
 This technique lets language-specific translations reorder the placeholder
136  
-text. For example, an English translation may be ``"Adrian is my name."``,
137  
-while a Spanish translation may be ``"Me llamo Adrian."`` -- with the
138  
-placeholder (the name) placed after the translated text instead of before it.
  138
+text. For example, an English translation may be ``"Today is November, 26."``,
  139
+while a Spanish translation may be ``"Hoy es 26 de Noviembre."`` -- with the
  140
+placeholders (the month and the day) with their positions swapped.
139 141
 
140  
-For this reason, you should use named-string interpolation (e.g., ``%(name)s``)
  142
+For this reason, you should use named-string interpolation (e.g., ``%(day)s``)
141 143
 instead of positional interpolation (e.g., ``%s`` or ``%d``) whenever you
142 144
 have more than a single parameter. If you used positional interpolation,
143 145
 translations wouldn't be able to reorder placeholder text.
@@ -215,11 +217,13 @@ translation languages as the ``count`` variable).
215 217
 In template code
216 218
 ----------------
217 219
 
  220
+.. highlightlang:: html+django
  221
+
218 222
 Translations in :ref:`Django templates <topics-templates>` uses two template
219 223
 tags and a slightly different syntax than in Python code. To give your template
220 224
 access to these tags, put ``{% load i18n %}`` toward the top of your template.
221 225
 
222  
-The ``{% trans %}`` template tag translates either a constant string 
  226
+The ``{% trans %}`` template tag translates either a constant string
223 227
 (enclosed in single or double quotes) or variable content::
224 228
 
225 229
     <title>{% trans "This is the title." %}</title>
@@ -231,9 +235,9 @@ require translation in the future::
231 235
 
232 236
     <title>{% trans "myvar" noop %}</title>
233 237
 
234  
-It's not possible to mix a template variable inside a string within
235  
-``{% trans %}``. If your translations require strings with variables (placeholders),
236  
-use ``{% blocktrans %}``. Example::
  238
+It's not possible to mix a template variable inside a string within ``{% trans
  239
+%}``. If your translations require strings with variables (placeholders), use
  240
+``{% blocktrans %}``::
237 241
 
238 242
     {% blocktrans %}This string will have {{ value }} inside.{% endblocktrans %}
239 243
 
@@ -273,6 +277,7 @@ Each ``RequestContext`` has access to three translation-specific variables:
273 277
 
274 278
     * ``LANGUAGE_CODE`` is the current user's preferred language, as a string.
275 279
       Example: ``en-us``. (See "How language preference is discovered", below.)
  280
+      
276 281
     * ``LANGUAGE_BIDI`` is the current locale's direction. If True, it's a
277 282
       right-to-left language, e.g.: Hebrew, Arabic. If False it's a
278 283
       left-to-right language, e.g.: English, French, German etc.
@@ -289,7 +294,7 @@ These tags also require a ``{% load i18n %}``.
289 294
 
290 295
 Translation hooks are also available within any template block tag that accepts
291 296
 constant strings. In those cases, just use ``_()`` syntax to specify a
292  
-translation string. Example::
  297
+translation string::
293 298
 
294 299
     {% some_special_tag _("Page not found") value|yesno:_("yes,no") %}
295 300
 
@@ -309,6 +314,8 @@ string, so they don't need to be aware of translations.
309 314
 Working with lazy translation objects
310 315
 -------------------------------------
311 316
 
  317
+.. highlightlang:: python
  318
+
312 319
 Using ``ugettext_lazy()`` and ``ungettext_lazy()`` to mark strings in models
313 320
 and utility functions is a common operation. When you're working with these
314 321
 objects elsewhere in your code, you should ensure that you don't accidentally
@@ -388,7 +395,8 @@ obtain) the language translations themselves. Here's how that works.
388 395
     application) and English strings (from Django itself). If you want to
389 396
     support a locale for your application that is not already part of
390 397
     Django, you'll need to make at least a minimal translation of the Django
391  
-    core.
  398
+    core. See the relevant :ref:LocaleMiddleware note`<locale-middleware-notes>`
  399
+    for more details.
392 400
 
393 401
 Message files
394 402
 -------------
@@ -416,20 +424,17 @@ The language code, in this case, is in locale format. For example, it's
416 424
 
417 425
 The script should be run from one of three places:
418 426
 
419  
-    * The root ``django`` directory (not a Subversion checkout, but the one
420  
-      that is linked-to via ``$PYTHONPATH`` or is located somewhere on that
421  
-      path).
422 427
     * The root directory of your Django project.
423 428
     * The root directory of your Django app.
  429
+    * The root ``django`` directory (not a Subversion checkout, but the one
  430
+      that is linked-to via ``$PYTHONPATH`` or is located somewhere on that
  431
+      path). This is only relevant when you are creating a translation for
  432
+      Django itself, see :ref:`contributing-translations`.
424 433
 
425  
-The script runs over the entire Django source tree and pulls out all strings
426  
-marked for translation. It creates (or updates) a message file in the directory
427  
-``conf/locale``. In the ``de`` example, the file will be
428  
-``conf/locale/de/LC_MESSAGES/django.po``.
429  
-
430  
-If run over your project source tree or your application source tree, it will
431  
-do the same, but the location of the locale directory is ``locale/LANG/LC_MESSAGES``
432  
-(note the missing ``conf`` prefix).
  434
+Th script runs over your project source tree or your application source tree and
  435
+pulls out all strings marked for translation. It creates (or updates) a message
  436
+file in the directory ``locale/LANG/LC_MESSAGES``. In the ``de`` example, the
  437
+file will be ``locale/de/LC_MESSAGES/django.po``.
433 438
 
434 439
 By default ``django-admin.py makemessages`` examines every file that has the
435 440
 ``.html`` file extension. In case you want to override that default, use the
@@ -437,22 +442,23 @@ By default ``django-admin.py makemessages`` examines every file that has the
437 442
 
438 443
     django-admin.py makemessages -l de -e txt
439 444
 
440  
-Separate multiple extensions with commas and/or use ``-e`` or ``--extension`` multiple times::
  445
+Separate multiple extensions with commas and/or use ``-e`` or ``--extension``
  446
+multiple times::
441 447
 
442 448
     django-admin.py makemessages -l=de -e=html,txt -e xml
443 449
 
444 450
 When `creating JavaScript translation catalogs`_ you need to use the special
445 451
 'djangojs' domain, **not** ``-e js``.
446 452
 
447  
-.. _create a JavaScript translation catalog: #creating-javascript-translation-catalogs
  453
+.. _create a JavaScript translation catalog: `Creating JavaScript translation catalogs`_
448 454
 
449 455
 .. admonition:: No gettext?
450 456
 
451  
-    If you don't have the ``gettext`` utilities installed,
452  
-    ``django-admin.py makemessages`` will create empty files. If that's the
453  
-    case, either install the ``gettext`` utilities or just copy the English
454  
-    message file (``conf/locale/en/LC_MESSAGES/django.po``) and use it as a
455  
-    starting point; it's just an empty translation file.
  457
+    If you don't have the ``gettext`` utilities installed, ``django-admin.py
  458
+    makemessages`` will create empty files. If that's the case, either install
  459
+    the ``gettext`` utilities or just copy the English message file
  460
+    (``locale/en/LC_MESSAGES/django.po``) if available and use it as a starting
  461
+    point; it's just an empty translation file.
456 462
 
457 463
 .. admonition:: Working on Windows?
458 464
 
@@ -485,8 +491,9 @@ A quick explanation:
485 491
     * ``msgstr`` is where you put the language-specific translation. It starts
486 492
       out empty, so it's your responsibility to change it. Make sure you keep
487 493
       the quotes around your translation.
488  
-    * As a convenience, each message includes the filename and line number
489  
-      from which the translation string was gleaned.
  494
+    * As a convenience, each message includes, in the form of a comment line
  495
+      prefixed with ``#`` and locted above the ``msgid`` line, the filename and
  496
+      line number from which the translation string was gleaned.
490 497
 
491 498
 Long messages are a special case. There, the first string directly after the
492 499
 ``msgstr`` (or ``msgid``) is an empty string. Then the content itself will be
@@ -516,11 +523,10 @@ After you create your message file -- and each time you make changes to it --
516 523
 you'll need to compile it into a more efficient form, for use by ``gettext``.
517 524
 Do this with the ``django-admin.py compilemessages`` utility.
518 525
 
519  
-This tool runs over all available ``.po`` files and creates ``.mo`` files,
520  
-which are binary files optimized for use by ``gettext``. In the same directory
521  
-
522  
-from which you ran ``django-admin.py makemessages``, run
523  
-``django-admin.py compilemessages`` like this::
  526
+This tool runs over all available ``.po`` files and creates ``.mo`` files, which
  527
+are binary files optimized for use by ``gettext``. In the same directory from
  528
+which you ran ``django-admin.py makemessages``, run ``django-admin.py
  529
+compilemessages`` like this::
524 530
 
525 531
    django-admin.py compilemessages
526 532
 
@@ -532,12 +538,6 @@ That's it. Your translations are ready for use.
532 538
     ``django-admin.py compilemessages`` to provide consistency throughout
533 539
     Django.
534 540
 
535  
-.. admonition:: A note to translators
536  
-
537  
-    If you've created a translation in a language Django doesn't yet support,
538  
-    please let us know! See :ref:`contributing-translations` for the steps to
539  
-    take.
540  
-
541 541
 .. admonition:: Working on Windows?
542 542
 
543 543
    If you're using Windows and need to install the GNU gettext utilities so
@@ -591,24 +591,38 @@ following this algorithm:
591 591
 
592 592
     * First, it looks for a ``django_language`` key in the current user's
593 593
       session.
594  
-    * Failing that, it looks for a cookie that is named according to your ``LANGUAGE_COOKIE_NAME`` setting. (The default name is ``django_language``, and this setting is new in the Django development version. In Django version 0.96 and before, the cookie's name is hard-coded to ``django_language``.)
  594
+    
  595
+    * Failing that, it looks for a cookie.
  596
+    
  597
+      .. versionchanged:: 1.0
  598
+    
  599
+      In Django version 0.96 and before, the cookie's name is hard-coded to
  600
+      ``django_language``. In Django 1,0, The cookie name is set by the
  601
+      ``LANGUAGE_COOKIE_NAME`` setting. (The default name is
  602
+      ``django_language``.)
  603
+    
595 604
     * Failing that, it looks at the ``Accept-Language`` HTTP header. This
596 605
       header is sent by your browser and tells the server which language(s) you
597 606
       prefer, in order by priority. Django tries each language in the header
598 607
       until it finds one with available translations.
  608
+    
599 609
     * Failing that, it uses the global ``LANGUAGE_CODE`` setting.
600 610
 
  611
+.. _locale-middleware-notes:
  612
+
601 613
 Notes:
602 614
 
603 615
     * In each of these places, the language preference is expected to be in the
604 616
       standard language format, as a string. For example, Brazilian Portuguese
605 617
       is ``pt-br``.
  618
+    
606 619
     * If a base language is available but the sublanguage specified is not,
607 620
       Django uses the base language. For example, if a user specifies ``de-at``
608 621
       (Austrian German) but Django only has ``de`` available, Django uses
609 622
       ``de``.
610  
-    * Only languages listed in the :setting:`LANGUAGES` setting can be selected. If
611  
-      you want to restrict the language selection to a subset of provided
  623
+    
  624
+    * Only languages listed in the :setting:`LANGUAGES` setting can be selected.
  625
+      If you want to restrict the language selection to a subset of provided
612 626
       languages (because your application doesn't provide all those languages),
613 627
       set ``LANGUAGES`` to a list of languages. For example::
614 628
 
@@ -643,8 +657,8 @@ Notes:
643 657
 
644 658
       With this arrangement, ``django-admin.py makemessages`` will still find
645 659
       and mark these strings for translation, but the translation won't happen
646  
-      at runtime -- so you'll have to remember to wrap the languages in the *real*
647  
-      ``ugettext()`` in any code that uses ``LANGUAGES`` at runtime.
  660
+      at runtime -- so you'll have to remember to wrap the languages in the
  661
+      *real* ``ugettext()`` in any code that uses ``LANGUAGES`` at runtime.
648 662
 
649 663
     * The ``LocaleMiddleware`` can only select languages for which there is a
650 664
       Django-provided base translation. If you want to provide translations
@@ -655,7 +669,7 @@ Notes:
655 669
       need at least those translations for the system to work correctly.
656 670
 
657 671
       A good starting point is to copy the English ``.po`` file and to
658  
-      translate at least the technical messages -- maybe the validator
  672
+      translate at least the technical messages -- maybe the validation
659 673
       messages, too.
660 674
 
661 675
       Technical message IDs are easily recognized; they're all upper case. You
@@ -697,7 +711,8 @@ Django looks for translations by following this algorithm:
697 711
       selected language, the translation will be installed.
698 712
     * Next, it looks for a ``locale`` directory in the project directory. If it
699 713
       finds a translation, the translation will be installed.
700  
-    * Finally, it checks the base translation in ``django/conf/locale``.
  714
+    * Finally, it checks the Django-provided base translation in
  715
+      ``django/conf/locale``.
701 716
 
702 717
 This way, you can write applications that include their own translations, and
703 718
 you can override base translations in your project path. Or, you can just build
@@ -779,7 +794,9 @@ algorithm:
779 794
     * If that's empty -- say, if a user's browser suppresses that header --
780 795
       then the user will be redirected to ``/`` (the site root) as a fallback.
781 796
 
782  
-Here's example HTML template code::
  797
+Here's example HTML template code:
  798
+
  799
+.. code-block:: html+django
783 800
 
784 801
     <form action="/i18n/setlang/" method="post">
785 802
     <input name="next" type="hidden" value="/next/page/" />
@@ -933,21 +950,24 @@ does translation:
933 950
 ``gettext`` on Windows
934 951
 ======================
935 952
 
936  
-This is only needed for people who either want to extract message IDs or
937  
-compile ``.po`` files. Translation work itself just involves editing existing
938  
-``.po`` files, but if you want to create your own .po files, or want to test
939  
-or compile a changed ``.po`` file, you will need the ``gettext`` utilities:
  953
+This is only needed for people who either want to extract message IDs or compile
  954
+message files (``.po``). Translation work itself just involves editing existing
  955
+files of this type, but if you want to create your own message files, or want to
  956
+test or compile a changed message file, you will need the ``gettext`` utilities:
940 957
 
941  
-    * Download the following zip files from http://sourceforge.net/projects/gettext
  958
+    * Download the following zip files from
  959
+      http://sourceforge.net/projects/gettext
942 960
 
943 961
       * ``gettext-runtime-X.bin.woe32.zip``
944 962
       * ``gettext-tools-X.bin.woe32.zip``
945 963
       * ``libiconv-X.bin.woe32.zip``
946 964
 
947  
-    * Extract the 3 files in the same folder (i.e. ``C:\Program Files\gettext-utils``)
  965
+    * Extract the 3 files in the same folder (i.e. ``C:\Program
  966
+      Files\gettext-utils``)
948 967
 
949 968
     * Update the system PATH:
950 969
 
951 970
       * ``Control Panel > System > Advanced > Environment Variables``
952 971
       * In the ``System variables`` list, click ``Path``, click ``Edit``
953  
-      * Add ``;C:\Program Files\gettext-utils\bin`` at the end of the ``Variable value``
  972
+      * Add ``;C:\Program Files\gettext-utils\bin`` at the end of the
  973
+        ``Variable value`` field

0 notes on commit ee28ee9

Please sign in to comment.
Something went wrong with that request. Please try again.