diff options
| author | Chris McDonough <chrism@agendaless.com> | 2010-04-27 18:20:27 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2010-04-27 18:20:27 +0000 |
| commit | b5dc7fbf22caf34d6ce85b2165e8bd3f908bc9e3 (patch) | |
| tree | 06724076f2ed60271d9575f84f8933bcd044a123 /docs | |
| parent | 12cb6df7728c8321905a08b0864b3ff0386c62cf (diff) | |
| download | pyramid-b5dc7fbf22caf34d6ce85b2165e8bd3f908bc9e3.tar.gz pyramid-b5dc7fbf22caf34d6ce85b2165e8bd3f908bc9e3.tar.bz2 pyramid-b5dc7fbf22caf34d6ce85b2165e8bd3f908bc9e3.zip | |
- Expanded portion of i18n narrative chapter docs which discuss
working with gettext files.
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/glossary.rst | 4 | ||||
| -rw-r--r-- | docs/narr/i18n.rst | 172 |
2 files changed, 152 insertions, 24 deletions
diff --git a/docs/glossary.rst b/docs/glossary.rst index 05a6c1479..a1adec50b 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -710,6 +710,10 @@ Glossary A string like ``en``, ``en_US``, ``de``, or ``de_AT`` which uniquely identifies a particular locale. + Default Locale Name + The :term:`locale name` used by an application when no explicit + locale name is set. See :ref:`localization_deployment_settings`. + Locale Negotiator An object supplying a policy determining which :term:`locale name` best represents a given :term:`request`. It is used by the diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index c5c77f971..0a9b5c283 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -210,8 +210,10 @@ method. Working With ``gettext`` Translation Files ------------------------------------------ -Once your application source code files and templates are marked up -with translation markers, you can work on translations. +The basis of :mod:`repoze.bfg` translation services is +GNU :term:`gettext`. Once your application source code files and templates +are marked up with translation markers, you can work on translations +by creating various kinds of gettext files. .. note:: @@ -223,6 +225,32 @@ with translation markers, you can work on translations. <http://wiki.pylonshq.com/display/pylonsdocs/Internationalization+and+Localization>`_ for more information. +GNU gettext use three types of files in the translation framework, +``.pot`` files, ``.po`` files and ``.mo`` files. + +``.pot`` (Portable Object Template) files + + A ``.pot`` file is created by a program which searches through your + project's source code and which picks out every :term:`message + identifier` passed to one of the '``_()`` functions + (eg. :term:`translation string` constructions). The list of all + message identifiers is placed into a ``.pot`` file, which serves as + a template for creating ``.po`` files. + +``.po`` (Portable Object) files + + The list of messages in a ``.pot`` file are translated by a human to + a particular language; the result is saved as a ``.po`` file. + +``.mo`` (Machine Object) files + + A ``.po`` file is turned into a machine-readable binary file, which + is the ``.mo`` file. Compiling the translations to machine code + makes the localized program run faster. + +The tool for working with :term:`gettext` translation files related to +a :mod:`repoze.bfg` application is :term:`Babel`. + .. index:: single: Babel @@ -268,10 +296,13 @@ Changing the ``setup.py`` You need some "hair" to your application's ``setup.py`` file (see :ref:`project_narr` for information about the composition of an -application's ``setup.py`` file). In particular, add the ``Babel`` -distribution to your application's ``install_requires`` list and -insert a set of references to :term:`Babel` *message extractors* -within the call to :func:`setuptools.setup`: +application's ``setup.py`` file) in order to properly generate +:term:`gettext` files from your application. + +In particular, add the ``Babel`` distribution to your application's +``install_requires`` list and insert a set of references to +:term:`Babel` *message extractors* within the call to +:func:`setuptools.setup`: .. code-block:: python :linenos: @@ -280,11 +311,11 @@ within the call to :func:`setuptools.setup`: ... install_requires = [ .... - "Babel", + 'Babel', ], - message_extractors = { ".": [ - ("**.py", "chameleon_python", None ), - ("**.pt", "chameleon_xml", None ), + message_extractors = { '.': [ + ('**.py', 'chameleon_python', None ), + ('**.pt', 'chameleon_xml', None ), ]}, ) @@ -295,6 +326,8 @@ consider ``**.pt`` files when doing message id extraction. .. index:: pair: extracting; messages +.. _extracting_messages: + Extracting Messages from Code and Templates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -311,25 +344,103 @@ which reside in your :mod:`repoze.bfg` application. You run a $ mkdir -p myapplication/locale $ python setup.py extract_messages -The message catalog template will end up in +The message catalog ``.pot`` template will end up in ``myapplication/locale/myapplication.pot``. +Translation Domains ++++++++++++++++++++ + +The name ``myapplication`` above in the filename ``myapplication.pot`` +denotes the :term:`translation domain` of the translations that must +be performed to localize your application. By default, the +translation domain is the :term:`project` name of your +:mod:`repoze.bfg` application. + +To change the translation domain of the extracted messages in your +project, edit the ``setup.cfg`` file of your application, The default +``setup.cfg`` file of a Paster-generated :mod:`repoze.bfg` application +has stanzas in it that look something like the following: + +.. code-block:: ini + :linenos: + + [compile_catalog] + directory = myproject/locale + domain = MyProject + statistics = true + + [extract_messages] + add_comments = TRANSLATORS: + output_file = myproject/locale/MyProject.pot + width = 80 + + [init_catalog] + domain = MyProject + input_file = myproject/locale/MyProject.pot + output_dir = myproject/locale + + [update_catalog] + domain = MyProject + input_file = myproject/locale/MyProject.pot + output_dir = myproject/locale + previous = true + +In the above example, the project name is ``MyProject``. To indicate +that you'd like the domain of your translations to be ``mydomain`` +instead, change the ``setup.cfg`` file stanzas to look like so: + +.. code-block:: ini + :linenos: + + [compile_catalog] + directory = myproject/locale + domain = mydomain + statistics = true + + [extract_messages] + add_comments = TRANSLATORS: + output_file = myproject/locale/mydomain.pot + width = 80 + + [init_catalog] + domain = mydomain + input_file = myproject/locale/mydomain.pot + output_dir = myproject/locale + + [update_catalog] + domain = mydomain + input_file = myproject/locale/mydomain.pot + output_dir = myproject/locale + previous = true + .. index:: pair: initializing; message catalog Initializing a Message Catalog File ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Initialize a message catalog for a specific locale from a -pre-generated ``.pot`` template:: +Once you've extracted messages into a ``.pot`` file (see +:ref:`extracting_messages`), to begin localizing the messages present +in the ``.pot`` file, you need to generate at least one ``.po`` file. +A ``.po`` file represents translations of a particular set of messages +to a particular locale. Initialize a ``.po`` file for a specific +locale from a pre-generated ``.pot`` template by using the ``setup.py +init_catalog`` command:: $ cd /place/where/myapplication/setup.py/lives $ python setup.py init_catalog -l es -The message catalog ``.po`` file will end up in +By default, the message catalog ``.po`` file will end up in ``myapplication/locale/es/LC_MESSAGES/myapplication.po``. -.. XXX finish +Once the file is there, it can be worked on by a human translator. +One tool which may help with this is `Poedit +<http://www.poedit.net/>`_. + +Note that :mod:`repoze.bfg` itself ignores the existence of all +``.po`` files. For a running application to have translations +available, a ``.mo`` file must exist. See +:ref:`compiling_message_catalog`. .. index:: pair: updating; message catalog @@ -337,25 +448,37 @@ The message catalog ``.po`` file will end up in Updating a Catalog File ~~~~~~~~~~~~~~~~~~~~~~~ -Update ``.po`` files based on changes to the ``.pot`` file:: +If more translation strings are added to your application, or +translation strings change, you will need to update existing ``.po`` +files based on changes to the ``.pot`` file, so that the new and +changed messages can also be translated or re-translated. + +First, regenerate the ``.pot`` file as per :ref:`extracting_messages`. +Then use the ``setup.py update_catalog`` command. + +.. code-block:: bash $ cd /place/where/myapplication/setup.py/lives $ python setup.py update_catalog -.. XXX finish - .. index:: pair: compiling; message catalog +.. _compiling_message_catalog: + Compiling a Message Catalog File ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Compile ``.po`` files to ``.mo`` files:: +Finally, to prepare an application for performing actual runtime +translations, compile ``.po`` files to ``.mo`` files:: $ cd /place/where/myapplication/setup.py/lives $ python setup.py compile_catalog -.. XXX finish +This will create a ``.mo`` file for each ``.po`` file in your +application. As long as the :term:`translation directory` in which +the ``.mo`` file ends up in is configured into your application, these +translations will be available to :mod:`repoze.bfg`. .. index:: single: localizer @@ -669,7 +792,7 @@ To turn translation on, you must: - add at least one :term:`translation directory` to your application. -- ensure that your application sets the :term:`locale` correctly. +- ensure that your application sets the :term:`locale name` correctly. Adding a Translation Directory ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -788,8 +911,9 @@ The default locale negotiator implementation named :class:`repoze.bfg.i18n.default_locale_negotiator` uses the following set of steps to dermine the locale name. -- First, the negotiator looks for the ``_LOCALE_`` attribute of - the request object (possibly set by an :term:`event listener`). +- First, the negotiator looks for the ``_LOCALE_`` attribute of the + request object (possibly set directly by view code or by a listener + for an :term:`event`). - Then it looks for the ``request.params['_LOCALE_']`` value. @@ -809,7 +933,7 @@ Using a Custom Locale Negotiator Locale negotiation is sometimes policy-laden and complex. If the (simple) default locale negotiation scheme described in -:ref:`activating translation` is inappropriate for your application, +:ref:`activating_translation` is inappropriate for your application, you may create and a special :term:`locale negotiator`. Subsequently you may override the default locale negotiator by adding your newly created locale negotiator to your application's configuration. |
