Steve Piercy
2017-06-26 ea593f9dd35df6892fa73061dda22fdf8a8a6055
commit | author | age
7534ba 1 .. index::
CM 2    single: i18n
3    single: l10n
4    single: internationalization
5    single: localization
6
7 .. _i18n_chapter:
8
9 Internationalization and Localization
10 =====================================
11
d2b365 12 :term:`Internationalization` (i18n) is the act of creating software with a user
SP 13 interface that can potentially be displayed in more than one language or
14 cultural context.  :term:`Localization` (l10n) is the process of displaying the
15 user interface of an internationalized application in a *particular* language
16 or cultural context.
df3beb 17
d2b365 18 :app:`Pyramid` offers internationalization and localization subsystems that can
SP 19 be used to translate the text of buttons, error messages, and other software-
20 and template-defined values into the native language of a user of your
21 application.
7534ba 22
CM 23 .. index::
24    single: translation string
25    pair: domain; translation
26    pair: msgid; translation
27    single: message identifier
28
29 Creating a Translation String
30 -----------------------------
31
d2b365 32 While you write your software, you can insert specialized markup into your
SP 33 Python code that makes it possible for the system to translate text values into
34 the languages used by your application's users.  This markup creates a
35 :term:`translation string`.  A translation string is an object that behaves
36 mostly like a normal Unicode object, except that it also carries around extra
37 information related to its job as part of the :app:`Pyramid` translation
38 machinery.
7534ba 39
d2b365 40 Using the ``TranslationString`` Class
7534ba 41 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CM 42
43 The most primitive way to create a translation string is to use the
fec0f0 44 :class:`pyramid.i18n.TranslationString` callable:
7534ba 45
CM 46 .. code-block:: python
47    :linenos:
48
fec0f0 49    from pyramid.i18n import TranslationString
7534ba 50    ts = TranslationString('Add')
CM 51
52 This creates a Unicode-like object that is a TranslationString.
53
54 .. note::
55
d2b365 56    For people more familiar with :term:`Zope` i18n, a TranslationString is a
SP 57    lot like a ``zope.i18nmessageid.Message`` object.  It is not a subclass,
58    however.  For people more familiar with :term:`Pylons` or :term:`Django`
59    i18n, using a TranslationString is a lot like using "lazy" versions of
60    related gettext APIs.
7534ba 61
d2b365 62 The first argument to :class:`~pyramid.i18n.TranslationString` is the
SP 63 ``msgid``; it is required.  It represents the key into the translation mappings
64 provided by a particular localization. The ``msgid`` argument must be a Unicode
65 object or an ASCII string.  The msgid may optionally contain *replacement
66 markers*.  For instance:
7534ba 67
CM 68 .. code-block:: python
69    :linenos:
70
fec0f0 71    from pyramid.i18n import TranslationString
7534ba 72    ts = TranslationString('Add ${number}')
CM 73
d2b365 74 Within the string above, ``${number}`` is a replacement marker.  It will be
SP 75 replaced by whatever is in the *mapping* for a translation string.  The mapping
76 may be supplied at the same time as the replacement marker itself:
7534ba 77
CM 78 .. code-block:: python
79    :linenos:
80
fec0f0 81    from pyramid.i18n import TranslationString
7534ba 82    ts = TranslationString('Add ${number}', mapping={'number':1})
CM 83
d2b365 84 Any number of replacement markers can be present in the msgid value, any number
SP 85 of times.  Only markers which can be replaced by the values in the *mapping*
86 will be replaced at translation time.  The others will not be interpolated and
87 will be output literally.
7534ba 88
CM 89 A translation string should also usually carry a *domain*.  The domain
d2b365 90 represents a translation category to disambiguate it from other translations of
SP 91 the same msgid, in case they conflict.
7534ba 92
CM 93 .. code-block:: python
94    :linenos:
95
fec0f0 96    from pyramid.i18n import TranslationString
879bb5 97    ts = TranslationString('Add ${number}', mapping={'number':1},
7534ba 98                           domain='form')
CM 99
d2b365 100 The above translation string named a domain of ``form``.  A :term:`translator`
SP 101 function will often use the domain to locate the right translator file on the
102 filesystem which contains translations for a given domain.  In this case, if it
103 were trying to translate our msgid to German, it might try to find a
104 translation from a :term:`gettext` file within a :term:`translation directory`
105 like this one:
23bfce 106
BL 107 .. code-block:: text
7534ba 108
CM 109    locale/de/LC_MESSAGES/form.mo
110
111 In other words, it would want to take translations from the ``form.mo``
112 translation file in the German language.
113
d2b365 114 Finally, the TranslationString constructor accepts a ``default`` argument.  If
SP 115 a ``default`` argument is supplied, it replaces usages of the ``msgid`` as the
116 *default value* for the translation string. When ``default`` is ``None``, the
117 ``msgid`` value passed to a TranslationString is used as an implicit message
118 identifier.  Message identifiers are matched with translations in translation
119 files, so it is often useful to create translation strings with "opaque"
120 message identifiers unrelated to their default text:
7534ba 121
CM 122 .. code-block:: python
123    :linenos:
124
fec0f0 125    from pyramid.i18n import TranslationString
7534ba 126    ts = TranslationString('add-number', default='Add ${number}',
CM 127                            domain='form', mapping={'number':1})
128
d2b365 129 When default text is used, Default text objects may contain replacement values.
7534ba 130
CM 131 .. index::
132    single: translation string factory
133
134 Using the ``TranslationStringFactory`` Class
135 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
136
137 Another way to generate a translation string is to use the
d2b365 138 :attr:`~pyramid.i18n.TranslationStringFactory` object.  This object is a
SP 139 *translation string factory*.  Basically a translation string factory presets
140 the ``domain`` value of any :term:`translation string` generated by using it.
141 For example:
7534ba 142
CM 143 .. code-block:: python
144    :linenos:
145
fec0f0 146    from pyramid.i18n import TranslationStringFactory
CM 147    _ = TranslationStringFactory('pyramid')
c12653 148    ts = _('add-number', default='Add ${number}', mapping={'number':1})
7534ba 149
d2b365 150 .. note:: We assigned the translation string factory to the name ``_``.  This
SP 151    is a convention which will be supported by translation file generation
152    tools.
7534ba 153
CM 154 After assigning ``_`` to the result of a
d2b365 155 :func:`~pyramid.i18n.TranslationStringFactory`, the subsequent result of
SP 156 calling ``_`` will be a :class:`~pyramid.i18n.TranslationString` instance.
157 Even though a ``domain`` value was not passed to ``_`` (as would have been
158 necessary if the :class:`~pyramid.i18n.TranslationString` constructor were used
159 instead of a translation string factory), the ``domain`` attribute of the
160 resulting translation string will be ``pyramid``.  As a result, the previous
161 code example is completely equivalent (except for spelling) to:
7534ba 162
CM 163 .. code-block:: python
164    :linenos:
165
fec0f0 166    from pyramid.i18n import TranslationString as _
c12653 167    ts = _('add-number', default='Add ${number}', mapping={'number':1},
fec0f0 168           domain='pyramid')
7534ba 169
d2b365 170 You can set up your own translation string factory much like the one provided
SP 171 above by using the :class:`~pyramid.i18n.TranslationStringFactory` class.  For
172 example, if you'd like to create a translation string factory which presets the
173 ``domain`` value of generated translation strings to ``form``, you'd do
174 something like this:
7534ba 175
CM 176 .. code-block:: python
177    :linenos:
178
fec0f0 179    from pyramid.i18n import TranslationStringFactory
7534ba 180    _ = TranslationStringFactory('form')
c12653 181    ts = _('add-number', default='Add ${number}', mapping={'number':1})
7534ba 182
d2b365 183 Creating a unique domain for your application via a translation string factory
SP 184 is best practice.  Using your own unique translation domain allows another
185 person to reuse your application without needing to merge your translation
186 files with their own.  Instead they can just include your package's
187 :term:`translation directory` via the
188 :meth:`pyramid.config.Configurator.add_translation_dirs` method.
7534ba 189
CM 190 .. note::
191
192    For people familiar with Zope internationalization, a
193    TranslationStringFactory is a lot like a
d2b365 194    ``zope.i18nmessageid.MessageFactory`` object.  It is not a subclass,
SP 195    however.
7534ba 196
CM 197 .. index::
198    single: gettext
199    single: translation directories
200
d2b365 201 Working with ``gettext`` Translation Files
7534ba 202 ------------------------------------------
CM 203
d2b365 204 The basis of :app:`Pyramid` translation services is GNU :term:`gettext`. Once
SP 205 your application source code files and templates are marked up with translation
206 markers, you can work on translations by creating various kinds of gettext
207 files.
7534ba 208
CM 209 .. note::
210
d2b365 211    The steps a developer must take to work with :term:`gettext` :term:`message
SP 212    catalog` files within a :app:`Pyramid` application are very similar to the
213    steps a :term:`Pylons` developer must take to do the same.  See the
214    :ref:`Pylons Internationalization and Localization documentation
82862b 215    <pylonswebframework:i18n>` for more information.
b5dc7f 216
d2b365 217 GNU gettext uses three types of files in the translation framework, ``.pot``
SP 218 files, ``.po`` files, and ``.mo`` files.
b5dc7f 219
CM 220 ``.pot`` (Portable Object Template) files
221
d2b365 222   A ``.pot`` file is created by a program which searches through your project's
SP 223   source code and which picks out every :term:`message identifier` passed to
224   one of the ``_()`` functions (e.g., :term:`translation string`
225   constructions). The list of all message identifiers is placed into a ``.pot``
226   file, which serves as a template for creating ``.po`` files.
b5dc7f 227
CM 228 ``.po`` (Portable Object) files
229
d2b365 230   The list of messages in a ``.pot`` file are translated by a human to a
SP 231   particular language; the result is saved as a ``.po`` file.
b5dc7f 232
CM 233 ``.mo`` (Machine Object) files
234
d2b365 235   A ``.po`` file is turned into a machine-readable binary file, which is the
SP 236   ``.mo`` file. Compiling the translations to machine code makes the
237   localized program start faster.
b5dc7f 238
5119ae 239 The tools for working with :term:`gettext` translation files related to a
d2b365 240 :app:`Pyramid` application are :term:`Lingua` and :term:`Gettext`. Lingua can
SP 241 scrape i18n references out of Python and Chameleon files and create the
242 ``.pot`` file. Gettext includes ``msgmerge`` tool to update a ``.po`` file from
243 an updated ``.pot`` file and ``msgfmt`` to compile ``.po`` files to ``.mo``
244 files.
7534ba 245
CM 246 .. index::
e4dc74 247    single: Gettext
5119ae 248    single: Lingua
7534ba 249
CM 250 .. _installing_babel:
251
e4dc74 252 Installing Lingua and Gettext
WA 253 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7534ba 254
d2b365 255 In order for the commands related to working with ``gettext`` translation files
SP 256 to work properly, you will need to have :term:`Lingua` and :term:`Gettext`
257 installed into the same environment in which :app:`Pyramid` is installed.
7534ba 258
CM 259 Installation on UNIX
260 ++++++++++++++++++++
261
e4dc74 262 Gettext is often already installed on UNIX systems. You can check if it is
WA 263 installed by testing if the ``msgfmt`` command is available. If it is not
d2b365 264 available you can install it through the packaging system from your OS; the
SP 265 package name is almost always ``gettext``. For example on a Debian or Ubuntu
266 system run this command:
e4dc74 267
c843d6 268 .. code-block:: bash
e4dc74 269
WA 270    $ sudo apt-get install gettext
271
272 Installing Lingua is done with the Python packaging tools. If the
d67566 273 :term:`virtual environment` into which you've installed your :app:`Pyramid`
c843d6 274 application lives at the environment variable ``$VENV``, you can install Lingua
SP 275 like so:
7534ba 276
c843d6 277 .. code-block:: bash
7534ba 278
c843d6 279    $ $VENV/bin/pip install lingua
7534ba 280
CM 281 Installation on Windows
282 +++++++++++++++++++++++
283
e4dc74 284 There are several ways to install Gettext on Windows: it is included in the
WA 285 `Cygwin <http://www.cygwin.com/>`_ collection, or you can use the `installer
d2b365 286 from the GnuWin32 <http://gnuwin32.sourceforge.net/packages/gettext.htm>`_, or
SP 287 compile it yourself. Make sure the installation path is added to your
e4dc74 288 ``$PATH``.
WA 289
290 Installing Lingua is done with the Python packaging tools. If the
d67566 291 :term:`virtual environment` into which you've installed your :app:`Pyramid`
c843d6 292 application lives at the environment variable ``%VENV%``, you can install
SP 293 Lingua like so:
7534ba 294
a651b3 295 .. code-block:: doscon
7534ba 296
108121 297    c:\> %VENV%\Scripts\pip install lingua
7534ba 298
5c5f7a 299
CM 300 .. index::
7534ba 301    pair: extracting; messages
b5dc7f 302
CM 303 .. _extracting_messages:
7534ba 304
CM 305 Extracting Messages from Code and Templates
306 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
307
d2b365 308 Once Lingua is installed, you may extract a message catalog template from the
e4dc74 309 code and :term:`Chameleon` templates which reside in your :app:`Pyramid`
WA 310 application.  You run a ``pot-create`` command to extract the messages:
5c5f7a 311
c843d6 312 .. code-block:: bash
7534ba 313
c843d6 314    $ cd /file/path/to/myapplication_setup.py
7534ba 315    $ mkdir -p myapplication/locale
5e6160 316    $ $VENV/bin/pot-create -o myapplication/locale/myapplication.pot src
7534ba 317
d2b365 318 The message catalog ``.pot`` template will end up in
7534ba 319 ``myapplication/locale/myapplication.pot``.
b5dc7f 320
7534ba 321
CM 322 .. index::
8e3b34 323    pair: initializing; message catalog
7534ba 324
8e3b34 325 Initializing a Message Catalog File
CM 326 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7534ba 327
b5dc7f 328 Once you've extracted messages into a ``.pot`` file (see
d2b365 329 :ref:`extracting_messages`), to begin localizing the messages present in the
SP 330 ``.pot`` file, you need to generate at least one ``.po`` file. A ``.po`` file
331 represents translations of a particular set of messages to a particular locale.
332 Initialize a ``.po`` file for a specific locale from a pre-generated ``.pot``
333 template by using the ``msginit`` command from Gettext:
23bfce 334
c843d6 335 .. code-block:: bash
7534ba 336
c843d6 337    $ cd /file/path/to/myapplication_setup.py
e4dc74 338    $ cd myapplication/locale
WA 339    $ mkdir -p es/LC_MESSAGES
b4245a 340    $ msginit -l es -o es/LC_MESSAGES/myapplication.po
7534ba 341
d2b365 342 This will create a new message catalog ``.po`` file in
7534ba 343 ``myapplication/locale/es/LC_MESSAGES/myapplication.po``.
CM 344
d2b365 345 Once the file is there, it can be worked on by a human translator. One tool
1cb30e 346 which may help with this is `Poedit <https://poedit.net/>`_.
b5dc7f 347
d2b365 348 Note that :app:`Pyramid` itself ignores the existence of all ``.po`` files.
SP 349 For a running application to have translations available, a ``.mo`` file must
350 exist.  See :ref:`compiling_message_catalog`.
7534ba 351
CM 352 .. index::
353    pair: updating; message catalog
354
355 Updating a Catalog File
356 ~~~~~~~~~~~~~~~~~~~~~~~
357
d2b365 358 If more translation strings are added to your application, or translation
SP 359 strings change, you will need to update existing ``.po`` files based on changes
360 to the ``.pot`` file, so that the new and changed messages can also be
361 translated or re-translated.
b5dc7f 362
d2b365 363 First, regenerate the ``.pot`` file as per :ref:`extracting_messages`. Then use
SP 364 the ``msgmerge`` command from Gettext.
b5dc7f 365
c843d6 366 .. code-block:: bash
7534ba 367
c843d6 368    $ cd /file/path/to/myapplication_setup.py
e4dc74 369    $ cd myapplication/locale
WA 370    $ msgmerge --update es/LC_MESSAGES/myapplication.po myapplication.pot
7534ba 371
CM 372 .. index::
373    pair: compiling; message catalog
b5dc7f 374
CM 375 .. _compiling_message_catalog:
7534ba 376
CM 377 Compiling a Message Catalog File
378 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
379
d2b365 380 Finally, to prepare an application for performing actual runtime translations,
SP 381 compile ``.po`` files to ``.mo`` files using the ``msgfmt`` command from
382 Gettext:
23bfce 383
c843d6 384 .. code-block:: bash
7534ba 385
c843d6 386    $ cd /file/path/to/myapplication_setup.py
d2b365 387    $ msgfmt -o myapplication/locale/es/LC_MESSAGES/myapplication.mo \
SP 388          myapplication/locale/es/LC_MESSAGES/myapplication.po
7534ba 389
02801e 390 This will create a ``.mo`` file for each ``.po`` file in your application.  As
SP 391 long as the :term:`translation directory` in which the ``.mo`` file ends up in
392 is configured into your application (see
d2b365 393 :ref:`adding_a_translation_directory`), these translations will be available to
SP 394 :app:`Pyramid`.
7534ba 395
CM 396 .. index::
397    single: localizer
6ce1e0 398    single: translation
CM 399    single: pluralization
7534ba 400
CM 401 Using a Localizer
402 -----------------
403
70acd2 404 A :term:`localizer` is an object that allows you to perform translation or
d2b365 405 pluralization "by hand" in an application.  You may use the
SP 406 :attr:`pyramid.request.Request.localizer` attribute to obtain a
407 :term:`localizer`.  The localizer object will be configured to produce
408 translations implied by the active :term:`locale negotiator`, or a default
330164 409 localizer object if no explicit locale negotiator is registered.
7534ba 410
CM 411 .. code-block:: python
412    :linenos:
413
414    def aview(request):
330164 415        localizer = request.localizer
7534ba 416
012b97 417 .. note::
M 418
d2b365 419     If you need to create a localizer for a locale, use the
86bbe8 420     :func:`pyramid.i18n.make_localizer` function.
CL 421
7534ba 422 .. index::
CM 423    single: translating (i18n)
424
425 .. _performing_a_translation:
426
427 Performing a Translation
428 ~~~~~~~~~~~~~~~~~~~~~~~~
429
430 A :term:`localizer` has a ``translate`` method which accepts either a
d2b365 431 :term:`translation string` or a Unicode string and which returns a Unicode
SP 432 object representing the translation.  Generating a translation in a view
433 component of an application might look like so:
7534ba 434
CM 435 .. code-block:: python
436    :linenos:
437
fec0f0 438    from pyramid.i18n import TranslationString
7534ba 439
879bb5 440    ts = TranslationString('Add ${number}', mapping={'number':1},
fec0f0 441                           domain='pyramid')
7534ba 442
CM 443    def aview(request):
330164 444        localizer = request.localizer
7534ba 445        translated = localizer.translate(ts) # translation string
CM 446        # ... use translated ...
447
330164 448 The ``request.localizer`` attribute will be a :class:`pyramid.i18n.Localizer`
CM 449 object bound to the locale name represented by the request.  The translation
450 returned from its :meth:`pyramid.i18n.Localizer.translate` method will depend
451 on the ``domain`` attribute of the provided translation string as well as the
7534ba 452 locale of the localizer.
CM 453
012b97 454 .. note::
M 455
d2b365 456    If you're using :term:`Chameleon` templates, you don't need to pre-translate
SP 457    translation strings this way.  See :ref:`chameleon_translation_strings`.
7534ba 458
CM 459 .. index::
460    single: pluralizing (i18n)
461
462 .. _performing_a_pluralization:
463
464 Performing a Pluralization
465 ~~~~~~~~~~~~~~~~~~~~~~~~~~
466
d2b365 467 A :term:`localizer` has a ``pluralize`` method with the following signature:
7534ba 468
CM 469 .. code-block:: python
470    :linenos:
471
472    def pluralize(singular, plural, n, domain=None, mapping=None):
473        ...
474
221fff 475 The simplest case is the ``singular`` and ``plural`` arguments being passed as
d2b365 476 Unicode literals. This returns the appropriate literal according to the locale
221fff 477 pluralization rules for the number ``n``, and interpolates ``mapping``.
7534ba 478
CM 479 .. code-block:: python
480    :linenos:
481
482    def aview(request):
330164 483        localizer = request.localizer
7534ba 484        translated = localizer.pluralize('Item', 'Items', 1, 'mydomain')
CM 485        # ... use translated ...
486
d2b365 487 However, for support of other languages, the ``singular`` argument should be a
SP 488 Unicode value representing a :term:`message identifier`.  In this case the
489 ``plural`` value is ignored. ``domain`` should be a :term:`translation domain`,
490 and ``mapping`` should be a dictionary that is used for *replacement value*
491 interpolation of the translated string.
221fff 492
MW 493 The value of ``n`` will be used to find the appropriate plural form for the
d2b365 494 current language, and ``pluralize`` will return a Unicode translation for the
221fff 495 message id ``singular``. The message file must have defined ``singular`` as a
MW 496 translation with plural forms.
497
498 The argument provided as ``singular`` may be a :term:`translation string`
499 object, but the domain and mapping information attached is ignored.
500
501 .. code-block:: python
502    :linenos:
503
504    def aview(request):
330164 505        localizer = request.localizer
221fff 506        num = 1
543113 507        translated = localizer.pluralize('item_plural', '${number} items',
MW 508            num, 'mydomain', mapping={'number':num})
221fff 509
MW 510 The corresponding message catalog must have language plural definitions and
511 plural alternatives set.
512
513 .. code-block:: text
514     :linenos:
515     
516     "Plural-Forms: nplurals=3; plural=n==0 ? 0 : n==1 ? 1 : 2;"
517     
518     msgid "item_plural"
519     msgid_plural ""
520     msgstr[0] "No items"
521     msgstr[1] "${number} item"
522     msgstr[2] "${number} items"
523
524 More information on complex plurals can be found in the `gettext documentation
525 <https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/Plural-forms.html>`_.
526
7534ba 527 .. index::
CM 528    single: locale name
529    single: negotiate_locale_name
530
531 .. _obtaining_the_locale_name:
532
533 Obtaining the Locale Name for a Request
534 ---------------------------------------
535
536 You can obtain the locale name related to a request by using the
330164 537 :func:`pyramid.request.Request.locale_name` attribute of the request.
7534ba 538
CM 539 .. code-block:: python
540    :linenos:
541
542    def aview(request):
330164 543        locale_name = request.locale_name
7534ba 544
d2b365 545 The locale name of a request is dynamically computed; it will be the locale
SP 546 name negotiated by the currently active :term:`locale negotiator`, or the
547 :term:`default locale name` if the locale negotiator returns ``None``. You can
548 change the default locale name by changing the ``pyramid.default_locale_name``
549 setting. See :ref:`default_locale_name_setting`.
7534ba 550
d2b365 551 Once :func:`~pyramid.request.Request.locale_name` is first run, the locale name
SP 552 is stored on the request object.  Subsequent calls to
553 :func:`~pyramid.request.Request.locale_name` will return the stored locale name
554 without invoking the :term:`locale negotiator`.  To avoid this caching, you can
555 use the :func:`pyramid.i18n.negotiate_locale_name` function:
7534ba 556
CM 557 .. code-block:: python
558    :linenos:
559
fec0f0 560    from pyramid.i18n import negotiate_locale_name
7534ba 561
CM 562    def aview(request):
563        locale_name = negotiate_locale_name(request)
564
565 You can also obtain the locale name related to a request using the
566 ``locale_name`` attribute of a :term:`localizer`.
567
533849 568 .. code-block:: python
CM 569    :linenos:
570
7534ba 571    def aview(request):
330164 572        localizer = request.localizer
7534ba 573        locale_name = localizer.locale_name
CM 574
d2b365 575 Obtaining the locale name as an attribute of a localizer is equivalent to
SP 576 obtaining a locale name by asking for the
330164 577 :func:`~pyramid.request.Request.locale_name` attribute.
7534ba 578
CM 579 .. index::
580    single: date and currency formatting (i18n)
581    single: Babel
582
583 Performing Date Formatting and Currency Formatting
584 --------------------------------------------------
585
d2b365 586 :app:`Pyramid` does not itself perform date and currency formatting for
SP 587 different locales.  However, :term:`Babel` can help you do this via the
588 :class:`babel.core.Locale` class.  The `Babel documentation for this class
8d212a 589 <http://babel.pocoo.org/en/latest/api/core.html#basic-interface>`_ provides
SP 590 minimal information about how to perform date and currency related locale
591 operations. See :ref:`installing_babel` for information about how to install
592 Babel.
7534ba 593
d2b365 594 The :class:`babel.core.Locale` class requires a :term:`locale name` as an
SP 595 argument to its constructor. You can use :app:`Pyramid` APIs to obtain the
596 locale name for a request to pass to the :class:`babel.core.Locale`
597 constructor.  See :ref:`obtaining_the_locale_name`.  For example:
7534ba 598
CM 599 .. code-block:: python
600    :linenos:
601
602    from babel.core import Locale
603
604    def aview(request):
330164 605        locale_name = request.locale_name
7534ba 606        locale = Locale(locale_name)
CM 607
608 .. index::
609    pair: translation strings; Chameleon
610
611 .. _chameleon_translation_strings:
612
613 Chameleon Template Support for Translation Strings
614 --------------------------------------------------
615
d2b365 616 When a :term:`translation string` is used as the subject of textual rendering
SP 617 by a :term:`Chameleon` template renderer, it will automatically be translated
618 to the requesting user's language if a suitable translation exists. This is
619 true of both the ZPT and text variants of the Chameleon template renderers.
7534ba 620
d2b365 621 For example, in a Chameleon ZPT template, the translation string represented by
SP 622 "some_translation_string" in each example below will go through translation
623 before being rendered:
7534ba 624
CM 625 .. code-block:: xml
626    :linenos:
627
628    <span tal:content="some_translation_string"/>
629
630 .. code-block:: xml
631    :linenos:
632
633    <span tal:replace="some_translation_string"/>
634
635 .. code-block:: xml
636    :linenos:
637
638    <span>${some_translation_string}</span>
639
640 .. code-block:: xml
641    :linenos:
642
643    <a tal:attributes="href some_translation_string">Click here</a>
05d032 644
CM 645 .. XXX the last example above appears to not yet work as of Chameleon
646 .. 1.2.3
7534ba 647
d2b365 648 The features represented by attributes of the ``i18n`` namespace of Chameleon
SP 649 will also consult the :app:`Pyramid` translations. See
1cb30e 650 http://chameleon.readthedocs.org/en/latest/reference.html#translation-i18n.
7534ba 651
CM 652 .. note::
653
d2b365 654    Unlike when Chameleon is used outside of :app:`Pyramid`, when it is used
SP 655    *within* :app:`Pyramid`, it does not support use of the ``zope.i18n``
656    translation framework.  Applications which use :app:`Pyramid` should use the
657    features documented in this chapter rather than ``zope.i18n``.
7534ba 658
d2b365 659 Third party :app:`Pyramid` template renderers might not provide this support
SP 660 out of the box and may need special code to do an equivalent.  For those, you
661 can always use the more manual translation facility described in
662 :ref:`performing_a_translation`.
7534ba 663
6ce1e0 664 .. index::
CM 665    single: Mako i18n
666
d2b365 667 Mako Pyramid i18n Support
ddf07e 668 -------------------------
CM 669
34515f 670 There exists a recipe within the :term:`Pyramid Community Cookbook` named
SP 671 :ref:`Mako Internationalization <cookbook:mako_i18n>` which explains how to add
672 idiomatic i18n support to :term:`Mako` templates.
ddf07e 673
88c92b 674
SP 675 .. index::
676    single: Jinja2 i18n
677
678 Jinja2 Pyramid i18n Support
679 ---------------------------
680
681 The add-on `pyramid_jinja2 <https://github.com/Pylons/pyramid_jinja2>`_
682 provides a scaffold with an example of how to use internationalization with
683 Jinja2 in Pyramid. See the documentation sections `Internalization (i18n)
19d341 684 <https://docs.pylonsproject.org/projects/pyramid-jinja2/en/latest/#internalization-i18n>`_
88c92b 685 and `Paster Template I18N
19d341 686 <https://docs.pylonsproject.org/projects/pyramid-jinja2/en/latest/#paster-template-i18n>`_.
88c92b 687
SP 688
7534ba 689 .. index::
CM 690    single: localization deployment settings
691    single:  default_locale_name
692
693 .. _localization_deployment_settings:
694
695 Localization-Related Deployment Settings
696 ----------------------------------------
697
875ded 698 A :app:`Pyramid` application will have a ``pyramid.default_locale_name``
d2b365 699 setting.  This value represents the :term:`default locale name` used when the
SP 700 :term:`locale negotiator` returns ``None``.  Pass it to the
701 :mod:`~pyramid.config.Configurator` constructor at startup time:
7534ba 702
CM 703 .. code-block:: python
704    :linenos:
705
d7f259 706    from pyramid.config import Configurator
875ded 707    config = Configurator(settings={'pyramid.default_locale_name':'de'})
7534ba 708
875ded 709 You may alternately supply a ``pyramid.default_locale_name`` via an
f8869c 710 application's ``.ini`` file:
7534ba 711
CM 712 .. code-block:: ini
713    :linenos:
714
715    [app:main]
3d338e 716    use = egg:MyProject
875ded 717    pyramid.reload_templates = true
MM 718    pyramid.debug_authorization = false
719    pyramid.debug_notfound = false
720    pyramid.default_locale_name = de
7534ba 721
d2b365 722 If this value is not supplied via the Configurator constructor or via a config
SP 723 file, it will default to ``en``.
7534ba 724
d2b365 725 If this setting is supplied within the :app:`Pyramid` application ``.ini``
SP 726 file, it will be available as a settings key:
7534ba 727
CM 728 .. code-block:: python
729    :linenos:
730
b68aad 731    from pyramid.threadlocal import get_current_registry
CM 732    settings = get_current_registry().settings
875ded 733    default_locale_name = settings['pyramid.default_locale_name']
6ce1e0 734
CM 735 .. index::
00f9fe 736    single: detecting languages
7534ba 737
2f935c 738 "Detecting" Available Languages
CM 739 -------------------------------
740
d2b365 741 Other systems provide an API that returns the set of "available languages" as
SP 742 indicated by the union of all languages in all translation directories on disk
743 at the time of the call to the API.
2f935c 744
d2b365 745 It is by design that :app:`Pyramid` doesn't supply such an API. Instead the
SP 746 application itself is responsible for knowing the "available languages".  The
747 rationale is this: any particular application deployment must always know which
748 languages it should be translatable to anyway, regardless of which translation
749 files are on disk.
2f935c 750
d2b365 751 Here's why: it's not a given that because translations exist in a particular
SP 752 language within the registered set of translation directories that this
753 particular deployment wants to allow translation to that language.  For
754 example, some translations may exist but they may be incomplete or incorrect.
755 Or there may be translations to a language but not for all translation domains.
2f935c 756
CM 757 Any nontrivial application deployment will always need to be able to
d2b365 758 selectively choose to allow only some languages even if that set of languages
SP 759 is smaller than all those detected within registered translation directories.
760 The easiest way to allow for this is to make the application entirely
761 responsible for knowing which languages are allowed to be translated to instead
762 of relying on the framework to divine this information from translation
763 directory file info.
2f935c 764
d2b365 765 You can set up a system to allow a deployer to select available languages based
SP 766 on convention by using the :mod:`pyramid.settings` mechanism.
2f935c 767
f8869c 768 Allow a deployer to modify your application's ``.ini`` file:
2f935c 769
CM 770 .. code-block:: ini
23bfce 771    :linenos:
2f935c 772
CM 773    [app:main]
3d338e 774    use = egg:MyProject
23bfce 775    # ...
2f935c 776    available_languages = fr de en ru
CM 777
778 Then as a part of the code of a custom :term:`locale negotiator`:
779
23bfce 780 .. code-block:: python
BL 781    :linenos:
879bb5 782
ddc745 783    from pyramid.settings import aslist
TT 784
785    def my_locale_negotiator(request):
786        languages = aslist(request.registry.settings['available_languages'])
787        # ...
2f935c 788
d2b365 789 This is only a suggestion.  You can create your own "available languages"
SP 790 configuration scheme as necessary.
2f935c 791
7534ba 792 .. index::
CM 793    pair: translation; activating
794    pair: locale; negotiator
795    single: translation directory
796
6ce1e0 797 .. index::
CM 798    pair: activating; translation
799
7534ba 800 .. _activating_translation:
CM 801
802 Activating Translation
803 ----------------------
804
d2b365 805 By default, a :app:`Pyramid` application performs no translation. To turn
SP 806 translation on you must:
7534ba 807
12cb6d 808 - add at least one :term:`translation directory` to your application.
7534ba 809
b5dc7f 810 - ensure that your application sets the :term:`locale name` correctly.
6ce1e0 811
CM 812 .. index::
813    pair: translation directory; adding
12cb6d 814
f8ed00 815 .. _adding_a_translation_directory:
CM 816
12cb6d 817 Adding a Translation Directory
CM 818 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7534ba 819
d2b365 820 :term:`gettext` is the underlying machinery behind the :app:`Pyramid`
SP 821 translation machinery.  A translation directory is a directory organized to be
822 useful to :term:`gettext`.  A translation directory usually includes a listing
823 of language directories, each of which itself includes an ``LC_MESSAGES``
824 directory.  Each ``LC_MESSAGES`` directory should contain one or more ``.mo``
825 files. Each ``.mo`` file represents a :term:`message catalog`, which is used to
826 provide translations to your application.
7534ba 827
4d4173 828 Adding a :term:`translation directory` registers all of its constituent
d2b365 829 :term:`message catalog` files within your :app:`Pyramid` application to be
SP 830 available to use for translation services.  This includes all of the ``.mo``
831 files found within all ``LC_MESSAGES`` directories within each locale directory
832 in the translation directory.
7534ba 833
f8ed00 834 You can add a translation directory imperatively by using the
d2b365 835 :meth:`pyramid.config.Configurator.add_translation_dirs` during application
SP 836 startup.  For example:
7534ba 837
f8ed00 838 .. code-block:: python
CM 839    :linenos:
7534ba 840
d7f259 841    from pyramid.config import Configurator
879bb5 842    config.add_translation_dirs('my.application:locale/',
f8ed00 843                                'another.application:locale/')
7534ba 844
f8ed00 845 A message catalog in a translation directory added via
d2b365 846 :meth:`~pyramid.config.Configurator.add_translation_dirs` will be merged into
SP 847 translations from a message catalog added earlier if both translation
848 directories contain translations for the same locale and :term:`translation
849 domain`.
7534ba 850
6ce1e0 851 .. index::
CM 852    pair: setting; locale
853
12cb6d 854 Setting the Locale
CM 855 ~~~~~~~~~~~~~~~~~~
7534ba 856
d2b365 857 When the *default locale negotiator* (see :ref:`default_locale_negotiator`) is
SP 858 in use, you can inform :app:`Pyramid` of the current locale name by doing any
859 of these things before any translations need to be performed:
12cb6d 860
d2b365 861 - Set the ``_LOCALE_`` attribute of the request to a valid locale name (usually
SP 862   directly within view code), e.g., ``request._LOCALE_ = 'de'``.
12cb6d 863
d2b365 864 - Ensure that a valid locale name value is in the ``request.params`` dictionary
SP 865   under the key named ``_LOCALE_``.  This is usually the result of passing a
866   ``_LOCALE_`` value in the query string or in the body of a form post
867   associated with a request.  For example, visiting
868   ``http://my.application?_LOCALE_=de``.
12cb6d 869
CM 870 - Ensure that a valid locale name value is in the ``request.cookies``
d2b365 871   dictionary under the key named ``_LOCALE_``.  This is usually the result of
SP 872   setting a ``_LOCALE_`` cookie in a prior response, e.g.,
873   ``response.set_cookie('_LOCALE_', 'de')``.
12cb6d 874
CM 875 .. note::
876
877    If this locale negotiation scheme is inappropriate for a particular
d2b365 878    application, you can configure a custom :term:`locale negotiator` function
SP 879    into that application as required.  See :ref:`custom_locale_negotiator`.
12cb6d 880
6ce1e0 881 .. index::
CM 882    single: locale negotiator
883
12cb6d 884 .. _locale_negotiators:
CM 885
886 Locale Negotiators
887 ------------------
7534ba 888
d2b365 889 A :term:`locale negotiator` informs the operation of a :term:`localizer` by
SP 890 telling it what :term:`locale name` is related to a particular request.  A
891 locale negotiator is a bit of code which accepts a request and which returns a
892 :term:`locale name`.  It is consulted when
893 :meth:`pyramid.i18n.Localizer.translate` or
894 :meth:`pyramid.i18n.Localizer.pluralize` is invoked.  It is also consulted when
895 :func:`~pyramid.request.Request.locale_name` is accessed or when
896 :func:`~pyramid.i18n.negotiate_locale_name` is invoked.
7534ba 897
12cb6d 898 .. _default_locale_negotiator:
CM 899
900 The Default Locale Negotiator
901 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
902
d2b365 903 Most applications can make use of the default locale negotiator, which requires
SP 904 no additional coding or configuration.
12cb6d 905
CM 906 The default locale negotiator implementation named
d2b365 907 :class:`~pyramid.i18n.default_locale_negotiator` uses the following set of
SP 908 steps to determine the locale name.
12cb6d 909
d2b365 910 - First the negotiator looks for the ``_LOCALE_`` attribute of the request
SP 911   object (possibly set directly by view code or by a listener for an
912   :term:`event`).
12cb6d 913
CM 914 - Then it looks for the ``request.params['_LOCALE_']`` value.
915
916 - Then it looks for the ``request.cookies['_LOCALE_']`` value.
917
d2b365 918 - If no locale can be found via the request, it falls back to using the
SP 919   :term:`default locale name` (see :ref:`localization_deployment_settings`).
12cb6d 920
d2b365 921 - Finally if the default locale name is not explicitly set, it uses the locale
SP 922   name ``en``.
12cb6d 923
CM 924 .. _custom_locale_negotiator:
925
926 Using a Custom Locale Negotiator
927 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
928
d2b365 929 Locale negotiation is sometimes policy-laden and complex.  If the (simple)
SP 930 default locale negotiation scheme described in :ref:`activating_translation` is
931 inappropriate for your application, you may create a special :term:`locale
932 negotiator`.  Subsequently you may override the default locale negotiator by
933 adding your newly created locale negotiator to your application's
934 configuration.
12cb6d 935
d2b365 936 A locale negotiator is simply a callable which accepts a request and returns a
SP 937 single :term:`locale name` or ``None`` if no locale can be determined.
12cb6d 938
CM 939 Here's an implementation of a simple locale negotiator:
940
941 .. code-block:: python
392a6c 942     :linenos:
12cb6d 943
CM 944     def my_locale_negotiator(request):
945         locale_name = request.params.get('my_locale')
946         return locale_name
947
d2b365 948 If a locale negotiator returns ``None``, it signifies to :app:`Pyramid` that
SP 949 the default application locale name should be used.
12cb6d 950
CM 951 You may add your newly created locale negotiator to your application's
f8ed00 952 configuration by passing an object which can act as the negotiator (or a
CM 953 :term:`dotted Python name` referring to the object) as the
d2b365 954 ``locale_negotiator`` argument of the :class:`~pyramid.config.Configurator`
SP 955 instance during application startup.  For example:
7534ba 956
f8ed00 957 .. code-block:: python
CM 958    :linenos:
7534ba 959
d7f259 960    from pyramid.config import Configurator
f8ed00 961    config = Configurator(locale_negotiator=my_locale_negotiator)
7534ba 962
d2b365 963 Alternatively, use the
SP 964 :meth:`pyramid.config.Configurator.set_locale_negotiator` method.
7534ba 965
f8ed00 966 For example:
7534ba 967
f8ed00 968 .. code-block:: python
CM 969    :linenos:
7534ba 970
d7f259 971    from pyramid.config import Configurator
f8ed00 972    config = Configurator()
CM 973    config.set_locale_negotiator(my_locale_negotiator)