diff -r 3e1615f0af48 docs/internals/contributing.txt
a
|
b
|
Submitting and maintaining translations
|
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 | * Create translations using the methods described in the :ref:`i18n |
| 403 | documentation <topics-i18n>`. For this you will use the ``django-admin.py |
| 404 | makemessages`` tool, in this particular case it should be |
| 405 | run from the ``django`` directory of the Django source tree. |
| 406 | |
| 407 | The script runs over the entire Django source tree and pulls out all strings |
| 408 | marked for translation. It creates (or updates) a message file in the |
| 409 | directory ``conf/locale`` (for example for ``pt-BR``, the file will be |
| 410 | ``conf/locale/pt-br/LC_MESSAGES/django.po``). |
| 411 | * Make sure that ``django-admin.py compilemessages -l <lang>`` runs without |
404 | 412 | producing any warnings. |
405 | | * Attach the patch to a ticket in Django's ticket system. |
| 413 | * Repeat the last two steps for the ``djangojs`` domain (by appending the |
| 414 | ``-d djangojs`` command line option to the ``django-admin.py`` |
| 415 | invocations. |
| 416 | * Create a diff of the ``.po`` file(s) against the current Subversion trunk. |
| 417 | * Open a ticket in Django's ticket system, set its ``Component`` field to |
| 418 | ``Translations``, and attach the patch to it. |
406 | 419 | |
407 | 420 | .. _Django i18n mailing list: http://groups.google.com/group/django-i18n/ |
408 | 421 | |
… |
… |
Template style
|
457 | 470 | brackets and the tag contents. |
458 | 471 | |
459 | 472 | Do this: |
460 | | |
| 473 | |
461 | 474 | .. code-block:: html+django |
462 | 475 | |
463 | 476 | {{ foo }} |
464 | 477 | |
465 | 478 | Don't do this: |
466 | | |
| 479 | |
467 | 480 | .. code-block:: html+django |
468 | 481 | |
469 | 482 | {{foo}} |
… |
… |
character set. If your database server d
|
743 | 756 | character set. If your database server doesn't use UTF-8 as a default charset, |
744 | 757 | you will need to include a value for ``TEST_DATABASE_CHARSET`` in your settings |
745 | 758 | file. |
746 | | |
| 759 | |
747 | 760 | If you want to run the full suite of tests, you'll need to install a number of |
748 | 761 | dependencies: |
749 | 762 | |
diff -r 3e1615f0af48 docs/topics/i18n.txt
a
|
b
|
The strings you pass to ``_()`` or ``uge
|
128 | 128 | The strings you pass to ``_()`` or ``ugettext()`` can take placeholders, |
129 | 129 | specified with Python's standard named-string interpolation syntax. Example:: |
130 | 130 | |
131 | | def my_view(request, n): |
132 | | output = _('%(name)s is my name.') % {'name': n} |
| 131 | def my_view(request, m, d): |
| 132 | output = _('Today is %(month)s, %s(day)s.') % {'month': m, 'day': d} |
133 | 133 | return HttpResponse(output) |
134 | 134 | |
135 | 135 | 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. |
| 136 | text. For example, an English translation may be ``"Today is November, 26."``, |
| 137 | while a Spanish translation may be ``"Hoy es 26 de Noviembre."`` -- with the |
| 138 | placeholders (the month and the day) with their positions swapped. |
139 | 139 | |
140 | | For this reason, you should use named-string interpolation (e.g., ``%(name)s``) |
| 140 | For this reason, you should use named-string interpolation (e.g., ``%(day)s``) |
141 | 141 | instead of positional interpolation (e.g., ``%s`` or ``%d``) whenever you |
142 | 142 | have more than a single parameter. If you used positional interpolation, |
143 | 143 | translations wouldn't be able to reorder placeholder text. |
… |
… |
tags and a slightly different syntax tha
|
219 | 219 | tags and a slightly different syntax than in Python code. To give your template |
220 | 220 | access to these tags, put ``{% load i18n %}`` toward the top of your template. |
221 | 221 | |
222 | | The ``{% trans %}`` template tag translates either a constant string |
223 | | (enclosed in single or double quotes) or variable content:: |
| 222 | The ``{% trans %}`` template tag translates either a constant string |
| 223 | (enclosed in single or double quotes) or variable content: |
| 224 | |
| 225 | .. code-block:: html+django |
224 | 226 | |
225 | 227 | <title>{% trans "This is the title." %}</title> |
226 | 228 | <title>{% trans myvar %}</title> |
227 | 229 | |
228 | 230 | If the ``noop`` option is present, variable lookup still takes place but the |
229 | 231 | translation is skipped. This is useful when "stubbing out" content that will |
230 | | require translation in the future:: |
| 232 | require translation in the future: |
| 233 | |
| 234 | .. code-block:: html+django |
231 | 235 | |
232 | 236 | <title>{% trans "myvar" noop %}</title> |
233 | 237 | |
234 | 238 | It's not possible to mix a template variable inside a string within |
235 | 239 | ``{% trans %}``. If your translations require strings with variables (placeholders), |
236 | | use ``{% blocktrans %}``. Example:: |
| 240 | use ``{% blocktrans %}``. Example: |
| 241 | |
| 242 | .. code-block:: html+django |
237 | 243 | |
238 | 244 | {% blocktrans %}This string will have {{ value }} inside.{% endblocktrans %} |
239 | 245 | |
240 | 246 | To translate a template expression -- say, using template filters -- you need |
241 | 247 | to bind the expression to a local variable for use within the translation |
242 | | block:: |
| 248 | block: |
| 249 | |
| 250 | .. code-block:: html+django |
243 | 251 | |
244 | 252 | {% blocktrans with value|filter as myvar %} |
245 | 253 | This will have {{ myvar }} inside. |
246 | 254 | {% endblocktrans %} |
247 | 255 | |
248 | 256 | If you need to bind more than one expression inside a ``blocktrans`` tag, |
249 | | separate the pieces with ``and``:: |
| 257 | separate the pieces with ``and``: |
| 258 | |
| 259 | .. code-block:: html+django |
250 | 260 | |
251 | 261 | {% blocktrans with book|title as book_t and author|title as author_t %} |
252 | 262 | This is {{ book_t }} by {{ author_t }} |
… |
… |
separate the pieces with ``and``::
|
254 | 264 | |
255 | 265 | To pluralize, specify both the singular and plural forms with the |
256 | 266 | ``{% plural %}`` tag, which appears within ``{% blocktrans %}`` and |
257 | | ``{% endblocktrans %}``. Example:: |
| 267 | ``{% endblocktrans %}``. Example: |
| 268 | |
| 269 | .. code-block:: html+django |
258 | 270 | |
259 | 271 | {% blocktrans count list|length as counter %} |
260 | 272 | There is only one {{ name }} object. |
… |
… |
Each ``RequestContext`` has access to th
|
279 | 291 | |
280 | 292 | |
281 | 293 | If you don't use the ``RequestContext`` extension, you can get those values with |
282 | | three tags:: |
| 294 | three tags: |
| 295 | |
| 296 | .. code-block:: html+django |
283 | 297 | |
284 | 298 | {% get_current_language as LANGUAGE_CODE %} |
285 | 299 | {% get_available_languages as LANGUAGES %} |
… |
… |
These tags also require a ``{% load i18n
|
289 | 303 | |
290 | 304 | Translation hooks are also available within any template block tag that accepts |
291 | 305 | constant strings. In those cases, just use ``_()`` syntax to specify a |
292 | | translation string. Example:: |
| 306 | translation string. Example: |
| 307 | |
| 308 | .. code-block:: html+django |
293 | 309 | |
294 | 310 | {% some_special_tag _("Page not found") value|yesno:_("yes,no") %} |
295 | 311 | |
… |
… |
obtain) the language translations themse
|
388 | 404 | application) and English strings (from Django itself). If you want to |
389 | 405 | support a locale for your application that is not already part of |
390 | 406 | Django, you'll need to make at least a minimal translation of the Django |
391 | | core. |
| 407 | core. See the relevant :ref:LocaleMiddleware note`<locale-middleware-notes>` |
| 408 | for more details. |
392 | 409 | |
393 | 410 | Message files |
394 | 411 | ------------- |
… |
… |
The language code, in this case, is in l
|
416 | 433 | |
417 | 434 | The script should be run from one of three places: |
418 | 435 | |
| 436 | * The root directory of your Django project. |
| 437 | * The root directory of your Django app. |
419 | 438 | * The root ``django`` directory (not a Subversion checkout, but the one |
420 | 439 | that is linked-to via ``$PYTHONPATH`` or is located somewhere on that |
421 | | path). |
422 | | * The root directory of your Django project. |
423 | | * The root directory of your Django app. |
| 440 | path). This is only relevant when you are creating a translation for |
| 441 | Django itself, see :ref:`contributing-translations`. |
424 | 442 | |
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). |
| 443 | Th script runs over your project source tree or your application source tree and |
| 444 | pulls out all strings marked for translation. It creates (or updates) a message |
| 445 | file in the directory ``locale/LANG/LC_MESSAGES``. In the ``de`` example, the |
| 446 | file will be ``locale/de/LC_MESSAGES/django.po``. |
433 | 447 | |
434 | 448 | By default ``django-admin.py makemessages`` examines every file that has the |
435 | 449 | ``.html`` file extension. In case you want to override that default, use the |
… |
… |
When `creating JavaScript translation ca
|
448 | 462 | |
449 | 463 | .. admonition:: No gettext? |
450 | 464 | |
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. |
| 465 | If you don't have the ``gettext`` utilities installed, ``django-admin.py |
| 466 | makemessages`` will create empty files. If that's the case, either install |
| 467 | the ``gettext`` utilities or just copy the English message file |
| 468 | (``locale/en/LC_MESSAGES/django.po``) if available and use it as a starting |
| 469 | point; it's just an empty translation file. |
456 | 470 | |
457 | 471 | .. admonition:: Working on Windows? |
458 | 472 | |
… |
… |
A quick explanation:
|
485 | 499 | * ``msgstr`` is where you put the language-specific translation. It starts |
486 | 500 | out empty, so it's your responsibility to change it. Make sure you keep |
487 | 501 | 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. |
| 502 | * As a convenience, each message includes, in the form of a comment line |
| 503 | prefixed with ``#`` and locted above the ``msgid`` line, the filename and |
| 504 | line number from which the translation string was gleaned. |
490 | 505 | |
491 | 506 | Long messages are a special case. There, the first string directly after the |
492 | 507 | ``msgstr`` (or ``msgid``) is an empty string. Then the content itself will be |
… |
… |
you'll need to compile it into a more ef
|
516 | 531 | you'll need to compile it into a more efficient form, for use by ``gettext``. |
517 | 532 | Do this with the ``django-admin.py compilemessages`` utility. |
518 | 533 | |
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:: |
| 534 | This tool runs over all available ``.po`` files and creates ``.mo`` files, which |
| 535 | are binary files optimized for use by ``gettext``. In the same directory from |
| 536 | which you ran ``django-admin.py makemessages``, run ``django-admin.py |
| 537 | compilemessages`` like this:: |
524 | 538 | |
525 | 539 | django-admin.py compilemessages |
526 | 540 | |
… |
… |
That's it. Your translations are ready f
|
531 | 545 | The old tool ``bin/compile-messages.py`` has been moved to the command |
532 | 546 | ``django-admin.py compilemessages`` to provide consistency throughout |
533 | 547 | Django. |
534 | | |
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 | 548 | |
541 | 549 | .. admonition:: Working on Windows? |
542 | 550 | |
… |
… |
following this algorithm:
|
591 | 599 | |
592 | 600 | * First, it looks for a ``django_language`` key in the current user's |
593 | 601 | 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``.) |
| 602 | * Failing that, it looks for a cookie |
| 603 | |
| 604 | * In Django version 0.96 and before, the cookie's name is hard-coded to |
| 605 | ``django_language``. |
| 606 | * .. versionadded:: 1.0 |
| 607 | |
| 608 | The cookie name is set by the ``LANGUAGE_COOKIE_NAME`` setting. (The |
| 609 | default name is ``django_language``.) |
595 | 610 | * Failing that, it looks at the ``Accept-Language`` HTTP header. This |
596 | 611 | header is sent by your browser and tells the server which language(s) you |
597 | 612 | prefer, in order by priority. Django tries each language in the header |
598 | 613 | until it finds one with available translations. |
599 | 614 | * Failing that, it uses the global ``LANGUAGE_CODE`` setting. |
| 615 | |
| 616 | .. _locale-middleware-notes: |
600 | 617 | |
601 | 618 | Notes: |
602 | 619 | |
… |
… |
Notes:
|
655 | 672 | need at least those translations for the system to work correctly. |
656 | 673 | |
657 | 674 | A good starting point is to copy the English ``.po`` file and to |
658 | | translate at least the technical messages -- maybe the validator |
| 675 | translate at least the technical messages -- maybe the validation |
659 | 676 | messages, too. |
660 | 677 | |
661 | 678 | Technical message IDs are easily recognized; they're all upper case. You |
… |
… |
Django looks for translations by followi
|
697 | 714 | selected language, the translation will be installed. |
698 | 715 | * Next, it looks for a ``locale`` directory in the project directory. If it |
699 | 716 | finds a translation, the translation will be installed. |
700 | | * Finally, it checks the base translation in ``django/conf/locale``. |
| 717 | * Finally, it checks the Django-provided base translation in |
| 718 | ``django/conf/locale``. |
701 | 719 | |
702 | 720 | This way, you can write applications that include their own translations, and |
703 | 721 | you can override base translations in your project path. Or, you can just build |
… |
… |
algorithm:
|
779 | 797 | * If that's empty -- say, if a user's browser suppresses that header -- |
780 | 798 | then the user will be redirected to ``/`` (the site root) as a fallback. |
781 | 799 | |
782 | | Here's example HTML template code:: |
| 800 | Here's example HTML template code: |
| 801 | |
| 802 | .. code-block:: html+django |
783 | 803 | |
784 | 804 | <form action="/i18n/setlang/" method="post"> |
785 | 805 | <input name="next" type="hidden" value="/next/page/" /> |
… |
… |
does translation:
|
933 | 953 | ``gettext`` on Windows |
934 | 954 | ====================== |
935 | 955 | |
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: |
| 956 | This is only needed for people who either want to extract message IDs or compile |
| 957 | message files (``.po``). Translation work itself just involves editing existing |
| 958 | files of this type, but if you want to create your own message files, or want to |
| 959 | test or compile a changed message file, you will need the ``gettext`` utilities: |
940 | 960 | |
941 | 961 | * Download the following zip files from http://sourceforge.net/projects/gettext |
942 | 962 | |
… |
… |
or compile a changed ``.po`` file, you w
|
950 | 970 | |
951 | 971 | * ``Control Panel > System > Advanced > Environment Variables`` |
952 | 972 | * In the ``System variables`` list, click ``Path``, click ``Edit`` |
953 | | * Add ``;C:\Program Files\gettext-utils\bin`` at the end of the ``Variable value`` |
| 973 | * Add ``;C:\Program Files\gettext-utils\bin`` at the end of the |
| 974 | ``Variable value`` field |