.. Internationalization and Localization

.. _i18n:

=====================================
国際化とローカライズ
=====================================

.. Introduction

はじめに
============

.. Internationalization and localization are means of adapting
.. software for non-native environments, especially for other nations
.. and cultures.

国際化とローカライズは、ソフトウェアを非ネイティブの環境、特に他の国や
文化のために適合させる手段です。


.. Parts of an application which might need to be localized might
.. include:

ローカライズが必要なアプリケーションの部分は以下のようなものがあります:


.. * Language
.. * Date/time format
.. * Formatting of numbers e.g. decimal points, positioning of separators, character used as separator
.. * Time zones (UTC in internationalized environments)
.. * Currency
.. * Weights and measures

* 言語
* 日付/時間の形式
* 数の形式、例えば小数点やセパレータの位置、セパレータとして使用される文字
* タイムゾーン (国際化環境では UTC)
* 通貨
* 重さと長さ


.. The distinction between internationalization and localization is
.. subtle but important. Internationalization is the adaptation of
.. products for potential use virtually everywhere, while localization
.. is the addition of special features for use in a specific locale.

国際化とローカライズの区別は微妙ですが、重要です。国際化とは潜在的にあ
らゆる場所で使用できるように製品を適合させることです。一方、ローカライ
ズは特定のロケールで使用するための特別な機能追加です。


.. For example, in terms of language used in software,
.. internationalization is the process of marking up all strings that
.. might need to be translated whilst localization is the process of
.. producing translations for a particular locale.

例えば、ソフトウェアで使用される言語に関して、国際化は翻訳が必要になる
可能性のあるすべての文字列に印をつけるプロセスであり、ローカライズは特
定のロケールのための翻訳を行うプロセスです。


.. Pylons provides built-in support to enable you to internationalize
.. language but leaves you to handle any other aspects of
.. internationalization which might be appropriate to your
.. application.

Pylons は言語を国際化することを可能にする標準サポートを提供しますが、ア
プリケーションに特有の国際化の他の側面はすべてあなたに任されています。


.. note::

    .. Internationalization is often abbreviated as I18N (or i18n or
    .. I18n) where the number 18 refers to the number of letters
    .. omitted.  Localization is often abbreviated L10n or l10n in the
    .. same manner. These abbreviations also avoid picking one
    .. spelling (internationalisation vs. internationalization, etc.)
    .. over the other.

    国際化はしばしば I18N (または i18n, I18n) と省略されます。ここで
    18 という数字は、省略された文字の数を表しています。同様に、ローカラ
    イズはしばしば L10n または l10n と省略されます。これらの略語はまた、
    2つのスペル (internationalisation か internationalization か) から
    1 つを選ぶことを回避します。


.. In order to represent characters from multiple languages, you will
.. need to utilize Unicode. This document assumes you have read the
.. :ref:`unicode`.

複数の言語の文字を表現するためにはユニコードを使用する必要があります。
この文書では、読者がすでに :ref:`unicode` を読んでいることを前提として
います。


.. By now you should have a good idea of what Unicode is, how to use
.. it in Python and which areas of you application need to pay
.. specific attention to decoding and encoding Unicode data.

あなたはすでに、ユニコードが何であるか、 Python でそれをどのように使用
するか、そしてアプリケーションのどの領域でユニコードデータのデコーディ
ングとエンコーディングに特別な注意を向ける必要があるかについて、よく理
解していることでしょう。


.. This final section will look at the issue of making your
.. application work with multiple languages.

この最終章では、アプリケーションを複数の言語で動かす際の問題について見
ていきます。


.. Pylons uses the `Python gettext module
.. <http://docs.python.org/lib/module-gettext.html>`_ for
.. internationalization.  It is based off the `GNU gettext API
.. <http://www.gnu.org/software/gettext/>`_.

Pylons は国際化のために `Python gettext モジュール
<http://docs.python.org/lib/module-gettext.html>`_ を使用します。それは
`GNU gettext API <http://www.gnu.org/software/gettext/>`_ に基づいてい
ます。


Getting Started
===============

.. Everywhere in your code where you want strings to be available in
.. different languages you wrap them in the ``_()`` function. There
.. are also a number of other translation functions which are
.. documented in the API reference at
.. http://pylonshq.com/docs/module-pylons.i18n.translation.html

コードのあらゆる場所で、異なる言語で利用できるようにしたい文字列を
``_()`` 関数で囲みます。その他にも多数の翻訳関数があり、それらは
http://pylonshq.com/docs/module-pylons.i18n.translation.html の API リ
ファレンスに記載されています。


.. note::

    .. The ``_()`` function is a reference to the ``ugettext()``
    .. function. ``_()`` is a convention for marking text to be
    .. translated and saves on keystrokes. ``ugettext()`` is the
    .. Unicode version of ``gettext()``; it returns unicode strings.

    ``_()`` 関数は ``ugettext()`` 関数への参照です。 ``_()`` は、翻訳す
    べきテキストに印をつけるための規約であり、キーストロークを節約しま
    す。 ``ugettext()`` は ``gettext()`` のユニコードバージョンです; そ
    れはユニコード文字列を返します。


.. In our example we want the string ``'Hello'`` to appear in three
.. different languages: English, French and Spanish. We also want to
.. display the word ``'Hello'`` in the default language. We'll then go
.. on to use some plural words too.

ここでの例では、文字列 ``'Hello'`` を英語、フランス語、スペイン語という
異なる 3 つの言語で表示したいとします。 また、デフォルトの言語で
``'Hello'`` という言葉を表示したいと思います。 さらに、いくつかの複数形
の単語も使用します。


.. Lets call our project ``translate_demo``:

プロジェクト名を ``translate_demo`` としましょう:


.. code-block:: bash

    $ paster create -t pylons translate_demo


.. Now lets add a friendly controller that says hello:

次に hello と挨拶するフレンドリーなコントローラを追加します。


.. code-block:: bash

    $ cd translate_demo
    $ paster controller hello


.. Edit ``controllers/hello.py`` to make use of the ``_()`` function
.. everywhere where the string ``Hello`` appears:

``controllers/hello.py`` を編集して、文字列 ``Hello`` が現れるすべての
場所で ``_()`` 関数を使うようにします:


.. code-block:: python

    import logging

    from pylons.i18n import get_lang, set_lang

    from translate_demo.lib.base import *

    log = logging.getLogger(__name__)

    class HelloController(BaseController):

        def index(self):
            response.write('Default: %s<br />' % _('Hello'))
            for lang in ['fr','en','es']:
                set_lang(lang)
            response.write("%s: %s<br />" % (get_lang(), _('Hello')))


.. When writing wrapping strings in the gettext functions, it is
.. important not to piece sentences together manually; certain
.. languages might need to invert the grammars. Don't do this:

gettext 関数で囲まれた文字列を書くとき、文の断片を手動で連結しないこと
が重要です; ある言語では文法を逆にする必要があるかもしれません。 これを
しないでください:


.. code-block:: python

    # BAD!
    msg = _("He told her ")
    msg += _("not to go outside.")


.. but this is perfectly acceptable:

かわりにこれなら何の問題もありません:


.. code-block:: python

    # GOOD
    msg = _("He told her not to go outside")


.. The controller has now been internationalized, but it will raise a
.. ``LanguageError`` until we have setup the alternative language catalogs.

これでコントローラは国際化されましたが、代替の言語カタログをセットアッ
プするまで ``LanguageError`` 例外が raise されます。


.. GNU gettext use three types of files in the translation framework.

GNU gettext は、翻訳フレームワークの中で 3 種類のファイルを使用します。


.. POT (Portable Object Template) files

POT (Portable Object Template) ファイル
----------------------------------------

.. The first step in the localization process. A program is used to
.. search through your project's source code and pick out every string
.. passed to one of the translation functions, such as ``_()``. This
.. list is put together in a specially-formatted template file that
.. will form the basis of all translations. This is the ``.pot`` file.

ローカライズプロセスの第一歩。プログラムを使用して、プロジェクトのソー
スコード全体から ``_()`` のような翻訳関数に渡されたあらゆる文字列を検索
します。このリストは、すべての翻訳の元になる、特別にフォーマットされた
テンプレートファイルの中にまとめられます。これが ``.pot`` ファイルです。


.. PO (Portable Object) files

PO (Portable Object) ファイル
-----------------------------

.. The second step in the localization process. Using the POT file as
.. a template, the list of messages are translated and saved as a
.. ``.po`` file.

ローカライズプロセスにおける第 2 ステップ。 POT ファイルをテンプレート
として使用して、メッセージのリストが翻訳されて ``.po`` ファイルとして保
存されます。


.. MO (Machine Object) files

MO (Machine Object) ファイル
-----------------------------

.. The final step in the localization process. The PO file is run
.. through a program that turns it into an optimized machine-readable
.. binary file, which is the ``.mo`` file. Compiling the translations
.. to machine code makes the localized program much faster in
.. retrieving the translations while it is running.

ローカライズプロセスの最終的なステップ。 PO ファイルをプログラムで処理
することによって、最適化された機械可読なバイナリーファイルに変換します。
それが ``.mo`` ファイルです。翻訳を機械コードにコンパイルするので、ロー
カライズされたプログラムは実行中に翻訳を検索するのに比べてはるかに速く
なります。


.. GNU gettext provides a suite of command line programs for
.. extracting messages from source code and working with the
.. associated gettext catalogs. The `Babel
.. <http://babel.edgewall.org/>`_ project provides pure Python
.. alternative versions of these tools. Unlike the GNU gettext tool
.. `xgettext`, Babel supports extracting translatable strings from
.. Python templating languages (currently Mako and Genshi).

GNU gettext は、ソースコードからメッセージを抽出したり、関連する
gettext カタログを処理したりするための、コマンドラインプログラム一式を
提供します。 `Babel <http://babel.edgewall.org/>`_ プロジェクトはこれら
のツールの pure Python による代替実装を提供します。 GNU gettext ツール
`xgettext` と比較すると、 Babel は Python テンプレート言語 (現在は
Mako と Genshi) からの翻訳可能な文字列の抽出をサポートしています。


.. Using Babel

Babel を使う
============

.. image:: _static/babel_logo.png


.. To use Babel, you must first install it via easy_install. Run the
.. command:

Babel を使用するためには、最初に easy_install でインストールしなければ
なりません。次のコマンドを実行してください:


.. code-block:: bash

    $ easy_install Babel


.. Pylons (as of 0.9.6) includes some sane defaults for Babel's
.. distutils commands in the setup.cfg file.

Pylons (0.9.6 以降) では、 setup.cfg ファイルに Babel distutils コマン
ドのための適切なデフォルト値が含まれています。


.. It also includes an extraction method mapping in the setup.py
.. file. It is commented out by default, to avoid distutils warning
.. about it being an unrecognized option when Babel is not
.. installed. These lines should be uncommented before proceeding with
.. the rest of this walk through:

setup.py ファイルには抽出方法マッピングも含まれています。それはデフォル
トではコメントアウトされていて、 Babel がインストールされていないときに
distutils が認識できないオプションに対して警告を出さないようになってい
ます。この文書の続きを行うために、これらの行のコメントを外して有効にし
なければなりません:


.. code-block:: python

    message_extractors = {'translate_demo': [
            ('**.py', 'python', None),
            ('templates/**.mako', 'mako', None),
            ('public/**', 'ignore', None)]},


.. We'll use Babel to extract messages to a ``.pot`` file in your
.. project's ``i18n`` directory. First, the directory needs to be
.. created. Don't forget to add it to your revision control system if
.. one is in use:

Babel を使って、プロジェクトの ``i18n`` ディレクトリの中の ``.pot`` ファ
イルにメッセージを抽出します。最初にディレクトリは作成しておく必要があ
ります。リビジョンコントロールシステムを使用しているなら、それにもディ
レクトリを追加するのを忘れないでください:


.. code-block:: bash

    $ cd translate_demo
    $ mkdir translate_demo/i18n
    $ svn add translate_demo/i18n


.. Next we can extract all messages from the project with the
.. following command:

次に、以下のコマンドですべてのメッセージをプロジェクトから抽出すること
ができます:


.. code-block:: bash

    $ python setup.py extract_messages
    running extract_messages
    extracting messages from translate_demo/__init__.py
    extracting messages from translate_demo/websetup.py
    ...
    extracting messages from translate_demo/tests/functional/test_hello.py
    writing PO template file to translate_demo/i18n/translate_demo.pot


.. This will create a ``.pot`` file in the ``i18n`` directory that
.. looks something like this:

これは ``i18n`` ディレクトリに次のような ``.pot`` ファイルを作成します:


.. code-block:: pot

    # Translations template for translate_demo.
    # Copyright (C) 2007 ORGANIZATION
    # This file is distributed under the same license as the translate_demo project.
    # FIRST AUTHOR <EMAIL@ADDRESS>, 2007.
    #
    #, fuzzy
    msgid ""
    msgstr ""
    "Project-Id-Version: translate_demo 0.0.0\n"
    "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
    "POT-Creation-Date: 2007-08-02 18:01-0700\n"
    "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
    "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
    "Language-Team: LANGUAGE <LL@li.org>\n"
    "MIME-Version: 1.0\n"
    "Content-Type: text/plain; charset=utf-8\n"
    "Content-Transfer-Encoding: 8bit\n"
    "Generated-By: Babel 0.9dev-r215\n"

    #: translate_demo/controllers/hello.py:10 translate_demo/controllers/hello.py:13
    msgid "Hello"
    msgstr ""


.. The ``.pot`` details that appear here can be customized via the
.. ``extract_messages`` configuration in your project's ``setup.cfg``
.. (See the `Babel Command-Line Interface Documentation
.. <http://babel.edgewall.org/wiki/Documentation/cmdline.html#extract>`_
.. for all configuration options).

ここで生成される ``.pot`` の詳細は、プロジェクトの ``setup.cfg`` の
``extract_messages`` 設定を通してカスタマイズすることができます (すべて
の設定オプションについては、 `Babel コマンドラインインタフェースのドキュ
メンテーション
<http://babel.edgewall.org/wiki/Documentation/cmdline.html#extract>`_
を見てください)。


.. Next, we'll initialize a catalog (``.po`` file) for the Spanish
.. language:

次に、スペイン語のためのカタログ (``.po`` ファイル) を初期化します:


.. code-block:: bash

    $ python setup.py init_catalog -l es
    running init_catalog
    creating catalog 'translate_demo/i18n/es/LC_MESSAGES/translate_demo.po' based on
    'translate_demo/i18n/translate_demo.pot'


.. Then we can edit the last line of the new Spanish ``.po`` file to
.. add a translation of ``"Hello"``:

そうすると、 ``"Hello"`` の翻訳を加えるために、新しいスペイン語の
``.po`` ファイルの最後の行を編集することができます:


.. code-block:: bash

    msgid "Hello"
    msgstr "¡Hola!"


.. Finally, to utilize these translations in our application, we need
.. to compile the ``.po`` file to a ``.mo`` file:

最後に、アプリケーションでこれらの翻訳を利用するために ``.po`` ファイル
を ``.mo`` ファイルにコンパイルする必要があります:


.. code-block:: bash

    $ python setup.py compile_catalog
    running compile_catalog
    1 of 1 messages (100%) translated in 'translate_demo/i18n/es/LC_MESSAGES/translate_demo.po'
    compiling catalog 'translate_demo/i18n/es/LC_MESSAGES/translate_demo.po' to
    'translate_demo/i18n/es/LC_MESSAGES/translate_demo.mo'


.. We can also use the ``update_catalog`` command to merge new
.. messages from the ``.pot`` to the ``.po`` files. For example, if we
.. later added the following line of code to the end of
.. HelloController's index method:

``.pot`` ファイルから ``.po`` ファイルに新しいメッセージをマージするた
めに ``update_catalog`` コマンドを使うこともできます。たとえば、後で
HelloController の index メソッドの最後に以下のコードを加えたなら:


.. code-block:: python

    response.write('Goodbye: %s' % _('Goodbye'))


.. We'd then need to re-extract the messages from the project, then
.. run the ``update_catalog`` command:

プロジェクトからメッセージを再抽出する必要があり、そのため
``update_catalog`` コマンドを実行します:


.. code-block:: bash

    $ python setup.py extract_messages
    running extract_messages
    extracting messages from translate_demo/__init__.py
    extracting messages from translate_demo/websetup.py
    ...
    extracting messages from translate_demo/tests/functional/test_hello.py
    writing PO template file to translate_demo/i18n/translate_demo.pot
    $ python setup.py update_catalog
    running update_catalog
    updating catalog 'translate_demo/i18n/es/LC_MESSAGES/translate_demo.po' based on
    'translate_demo/i18n/translate_demo.pot'


.. We'd then edit our catalog to add a translation for "Goodbye", and
.. recompile the ``.po`` file as we did above.

それから、カタログを編集して "Goodbye" の翻訳を追加して、先ほどしたよう
に ``.po`` ファイルを再コンパイルします。


.. For more information, see the `Babel documentation
.. <http://babel.edgewall.org/wiki/Documentation/index.html>`_ and the
.. `GNU Gettext Manual
.. <http://www.gnu.org/software/gettext/manual/gettext.html>`_.

詳細については `Babel ドキュメンテーション
<http://babel.edgewall.org/wiki/Documentation/index.html>`_ と `GNU
Gettext マニュアル
<http://www.gnu.org/software/gettext/manual/gettext.html>`_ を見てくだ
さい。


.. Back To Work

作業に戻る
============

.. Next we'll need to repeat the process of creating a ``.mo`` file
.. for the ``en`` and ``fr`` locales:

次に、 ``en`` ロケールと ``fr`` ロケールのために ``.mo`` ファイルを作成
するプロセスを繰り返す必要があります:


.. code-block:: bash

    $ python setup.py init_catalog -l en
    running init_catalog
    creating catalog 'translate_demo/i18n/en/LC_MESSAGES/translate_demo.po' based on
    'translate_demo/i18n/translate_demo.pot'
    $ python setup.py init_catalog -l fr
    running init_catalog
    creating catalog 'translate_demo/i18n/fr/LC_MESSAGES/translate_demo.po' based on
    'translate_demo/i18n/translate_demo.pot'


.. Modify the last line of the ``fr`` catalog to look like this:

``fr`` カタログの最後の行をこのように修正してください:


.. code-block:: po

    #: translate_demo/controllers/hello.py:10 translate_demo/controllers/hello.py:13
    msgid "Hello"
    msgstr "Bonjour"


.. Since our original messages are already in English, the ``en``
.. catalog can stay blank; gettext will fallback to the original.

オリジナルのメッセージはもともと英語なので、 ``en`` カタログは空白のま
まにすることができます; gettext はオリジナルへ fallback します。


.. Once you've edited these new ``.po`` files and compiled them to
.. ``.mo`` files, you'll end up with an ``i18n`` directory containing:

これらの新しい ``.po`` ファイルを編集して、それらを ``.mo`` ファイルに
コンパイルしたら、 ``i18n`` ディレクトリには以下のファイルが含まれてい
るでしょう:


.. code-block:: text

    i18n/translate_demo.pot
    i18n/en/LC_MESSAGES/translate_demo.po
    i18n/en/LC_MESSAGES/translate_demo.mo
    i18n/es/LC_MESSAGES/translate_demo.po
    i18n/es/LC_MESSAGES/translate_demo.mo
    i18n/fr/LC_MESSAGES/translate_demo.po
    i18n/fr/LC_MESSAGES/translate_demo.mo


.. Testing the Application

アプリケーションをテストする
============================

.. Start the server with the following command:

次のコマンドでサーバを動かしてください:


.. code-block:: bash

    $ paster serve --reload development.ini


.. Test your controller by visiting http://localhost:5000/hello. You
.. should see the following output:

http://localhost:5000/hello を訪問してコントローラをテストしてください。
以下の出力が見られるはずです:


.. code-block:: text

    Default: Hello
    fr: Bonjour
    en: Hello
    es: ¡Hola!


.. You can now set the language used in a controller on the fly.

コントローラで使用される言語を on the fly でセットすることができます。


.. For example this could be used to allow a user to set which
.. language they wanted your application to work in. You could save
.. the value to the session object:

たとえば、ユーザーがアプリケーションに対してどの言語で動作するかを設定
できるようにするためにこれを用いることができます。セッションオブジェク
トに値を保存することができます:


.. code-block:: python

    session['lang'] = 'en'
    session.save()


.. then on each controller call the language to be used could be read
.. from the session and set in your controller's ``__before__()``
.. method so that the pages remained in the same language that was
.. previously set:

そして、コントローラが呼び出される毎に使用する言語をセッションから読み
こみ、コントローラの ``__before__()`` メソッドでそれを設定することによっ
て、他のページでも以前設定されたのと同じ言語を維持するようにできます。


.. code-block:: python

    def __before__(self):
        if 'lang' in session:
            set_lang(session['lang'])


.. Pylons also supports defining the default language to be used in
.. the configuration file. Set a ``lang`` variable to the desired
.. default language in your ``development.ini`` file, and Pylons will
.. automatically call ``set_lang`` with that language at the beginning
.. of every request.

また、 Pylons は使用するデフォルト言語を設定ファイルで定義することもサ
ポートしています。 ``development.ini`` ファイルで ``lang`` 変数を望まし
いデフォルト言語に設定してください。すると、 Pylons はあらゆるリクエス
トの始めにその言語で ``set_lang`` を自動的に呼び出します。


.. E.g. to set the default language to Spanish, you would add ``lang =
.. es`` to your ``development.ini``:

例えば、デフォルト言語をスペイン語に設定するためには、
``development.ini`` に ``lang = es`` を加えます:


.. code-block:: ini

    [app:main]
    use = egg:translate_demo
    lang = es


.. If you are running the server with the ``--reload`` option the
.. server will automatically restart if you change the
.. ``development.ini`` file. Otherwise restart the server manually and
.. the output would this time be as follows:

サーバーを ``--reload`` オプションで動かしているなら、
``development.ini`` ファイルを変更するとサーバーは自動的に再起動します。
そうでなければ、手動でサーバーを再起動してください。そして、今度は出力
は以下のようになります:


.. code-block:: text

    Default: ¡Hola!
    fr: Bonjour
    en: Hello
    es: ¡Hola!


.. Fallback Languages

fallback 言語
==================

.. If your code calls ``_()`` with a string that doesn't exist at all
.. in your language catalog, the string passed to ``_()`` is returned
.. instead.

言語カタログの中に存在しない文字列で ``_()`` が呼ばれた場合、代わりに
``_()`` に渡された文字列が返されます。


.. Modify the last line of the hello controller to look like this:

hello コントローラの最後の行を、このように修正してください:


.. code-block:: python

    response.write("%s %s, %s" % (_('Hello'), _('World'), _('Hi!')))


.. warning::

    .. Of course, in real life breaking up sentences in this way is
    .. very dangerous because some grammars might require the order of
    .. the words to be different.

    もちろん、現実の世界においてこのように文を分割することは非常に危険
    です。いくつかの文法では異なる語順を要求するかもしれないからです。


.. If you run the example again the output will be:

例を再び実行すると、出力はこのようになります:


.. code-block:: text

    Default: ¡Hola!
    fr: Bonjour World!
    en: Hello World!
    es: ¡Hola! World!


.. This is because we never provided a translation for the string
.. ``'World!'`` so the string itself is used.

これは文字列 ``'World!'`` に対して翻訳を用意しなかったからで、そのため
文字列自体が使われています。


.. Pylons also provides a mechanism for fallback languages, so that
.. you can specify other languages to be used if the word is omitted
.. from the main language's catalog.

Pylons も fallback 言語のためのメカニズムを提供しています。これは、ある
単語がメインの言語カタログで省略されていた場合に使われる他の言語を指定
することができるようにします。


.. In this example we choose ``fr`` as the main language but ``es`` as
.. a fallback:

この例では、メインの言語として ``fr`` を、fallback として ``es`` を選択
しています。


.. code-block:: python

    import logging

    from pylons.i18n import set_lang

    from translate_demo.lib.base import *

    log = logging.getLogger(__name__)

    class HelloController(BaseController):

        def index(self):
            set_lang(['fr', 'es'])
            return "%s %s, %s" % (_('Hello'), _('World'), _('Hi!'))


.. If ``Hello`` is in the ``fr`` ``.mo`` file as ``Bonjour``,
.. ``World`` is only in ``es`` as ``Mundo`` and none of the catalogs
.. contain ``Hi!``, you'll get the multilingual message: ``Bonjour
.. Mundo, Hi!``. This is a combination of the French, Spanish and
.. original (English in this case, as defined in our source code)
.. words.

もし ``Hello`` が ``fr`` ``.mo`` ファイルの中に ``Bonjour`` として存在
し、 ``World`` が ``es`` の中にだけ ``Mundo`` として存在し、そして、カ
タログのどれも ``Hi!`` を含まないなら、多国語メッセージを得ます:
``Bonjour Mundo, Hi!`` 。これは、フランス語とスペイン語と原語 (このケー
スでは英語がソースコードの中で定義されています) の組合せです。


.. You can also add fallback languages after calling ``set_lang`` via
.. the ``pylons.i18n.add_fallback`` function. Translations will be
.. tested in the order you add them.

``set_lang`` を呼んだ後で ``pylons.i18n.add_fallback`` 関数によって
fallback 言語を追加することもできます。翻訳は追加された順番でテストされ
ます。


.. note::

   .. Fallbacks are reset after calling ``set_lang(lang)`` -- that is,
   .. fallbacks are associated with the currently selected language.

   fallback は ``set_lang(lang)`` を呼んだ後でリセットされます -- すな
   わち、 fallback は現在選択されている言語に関連付けられます。


.. One case where using fallbacks in this way is particularly useful
.. is when you wish to display content based on the languages
.. requested by the browser in the ``HTTP_ACCEPT_LANGUAGE``
.. header. Typically the browser may submit a number of languages so
.. it is useful to be add fallbacks in the order specified by the
.. browser so that you always try to display words in the language of
.. preference and search the other languages in order if a translation
.. cannot be found. The languages defined in the
.. ``HTTP_ACCEPT_LANGUAGE`` header are available in Pylons as
.. ``request.languages`` and can be used like this:

このように fallback 使うことが特に役に立つ 1 つのケースは、
``HTTP_ACCEPT_LANGUAGE`` ヘッダによってブラウザからリクエストされた言語
に基づいてコンテンツを表示したい場合です。一般に、ブラウザは多くの言語
を送信するので、ブラウザによって指定された順番で fallback を追加するこ
とは有用です。それによって、常に望ましい言語で単語を表示しようとし、も
し翻訳が見つけられない場合には順番に他の言語を探すことができます。
``HTTP_ACCEPT_LANGUAGE`` ヘッダで宣言された言語は、 Pylons では
``request.languages`` オブジェクトとして利用でき、このように使うことが
できます:


.. code-block:: python

    for lang in request.languages:
        add_fallback(lang)


.. Translations Within Templates

テンプレートの翻訳
=============================

.. You can also use the ``_()`` function within templates in exactly
.. the same way you do in code. For example, in a Mako template:

テンプレートの中でも、コードの中で行うのとまったく同じ方法で ``_()`` 関
数を使用することができます。たとえば Mako テンプレートで:


.. code-block:: mako

    ${_('Hello')}


.. would produce the string ``'Hello'`` in the language you had set.

これは設定された言語で文字列 ``'Hello'`` を表示します。


.. Babel currently supports extracting gettext messages from Mako and
.. Genshi templates. The Mako extractor also provides support for
.. translator comments.  Babel can be extended to extract messages
.. from other sources via a `custom extraction method plugin
.. <http://babel.edgewall.org/wiki/Documentation/messages.html#writing-extraction-methods>`_.

Babel は現在、 Mako と Genshi テンプレートからの gettext メッセージの抽
出をサポートしています。 Mako の抽出では、翻訳者コメントのサポートも提
供しています。 Babel は、 `カスタム抽出方法プラグイン
<http://babel.edgewall.org/wiki/Documentation/messages.html#writing-extraction-methods>`_
によって他のソースからメッセージを抽出するように拡張することができます。


.. Pylons (as of 0.9.6) automatically configures a Babel extraction
.. mapping for your Python source code and Mako templates. This is
.. defined in your project's setup.py file:

Pylons (0.9.6 以降) は、 Python ソースコードと Mako テンプレートのため
の Babel 抽出マッピングを自動的に設定します。これはプロジェクトの
setup.py ファイルで定義されます:


.. code-block:: python

    message_extractors = {'translate_demo': [
            ('**.py', 'python', None),
            ('templates/**.mako', 'mako', None),
            ('public/**', 'ignore', None)]},


.. For a project using Genshi instead of Mako, the Mako line might be
.. replaced with:

Mako の代わりに Genshi を使用しているプロジェクトでは、 Mako の行は次の
ように置き換えられるでしょう:


.. code-block:: python

    ('templates/**.html, 'genshi', None),


.. See `Babel's documentation on Message Extraction
.. <http://babel.edgewall.org/wiki/Documentation/messages.html#message-extraction>`_
.. for more information.

詳細は、 `メッセージ抽出に関する Babel の ドキュメンテーション
<http://babel.edgewall.org/wiki/Documentation/messages.html#message-extraction>`_
を参照してください。


.. Lazy Translations

遅延翻訳
=================

.. Occasionally you might come across a situation when you need to
.. translate a string when it is accessed, not when the ``_()`` or
.. other functions are called.

時々、 ``_()`` または他の関数が呼ばれるときでなく、文字列にアクセスされ
たときに翻訳を行う必要があるような状況に出くわすかもしれません。


.. Consider this example:

この例を見てください:


.. code-block:: python

    import logging

    from pylons.i18n import get_lang, set_lang

    from translate_demo.lib.base import *

    log = logging.getLogger(__name__)

    text = _('Hello')

    class HelloController(BaseController):

        def index(self):
            response.write('Default: %s<br />' % _('Hello'))
            for lang in ['fr','en','es']:
                set_lang(lang)
            response.write("%s: %s<br />" % (get_lang(), _('Hello')))
            response.write('Text: %s<br />' % text)


.. If we run this we get the following output:

これを実行すると、以下の出力を得ます:


.. code-block:: text

    Default: Hello
    ['fr']: Bonjour
    ['en']: Good morning
    ['es']: Hola
    Text: Hello


.. This is because the function ``_('Hello')`` just after the imports
.. is called when the default language is ``en`` so the variable
.. ``text`` gets the value of the English translation even though when
.. the string was used the default language was Spanish.

これは、 import の直後の関数 ``_('Hello')`` が、デフォルト言語が
``en`` のときに呼ばれたためで、文字列が使われたときのデフォルト言語がス
ペイン語であったとしても、変数 ``text`` の値は英語の翻訳になります。


.. The rule of thumb in these situations is to try to avoid using the
.. translation functions in situations where they are not executed on
.. each request. For situations where this isn't possible, perhaps
.. because you are working with legacy code or with a library which
.. doesn't support internationalization, you need to use lazy
.. translations.

これらの状況の経験則は、リクエスト毎に実行されない状況では、翻訳関数を
使わないように努めるということです。これが可能でない状況 (おそらくレガ
シーコードや国際化をサポートしないライブラリを扱っているような場合) で
は、遅延翻訳を使う必要があります。


.. If we modify the above example so that the import statements and
.. assignment to ``text`` look like this:

上の例で import 文と ``text`` への代入をこんな風に修正すれば:


.. code-block:: python

    from pylons.i18n import get_lang, lazy_gettext, set_lang

    from helloworld.lib.base import *

    log = logging.getLogger(__name__)

    text = lazy_gettext('Hello')


.. then we get the output we expected:

期待する出力が得られます:


.. code-block:: text

    Default: Hello
    ['fr']: Bonjour
    ['en']: Good morning
    ['es']: Hola
    Text: Hola


.. There are lazy versions of all the standard Pylons `translation
.. functions
.. <http://pylonshq.com/docs/module-pylons.i18n.translation.html>`_.

すべての標準的な Pylons `翻訳関数
<http://pylonshq.com/docs/module-pylons.i18n.translation.html>`_ に遅延
バージョンが存在します。


.. There is one drawback to be aware of when using the lazy
.. translation functions: they are not actually strings. This means
.. that if our example had used the following code it would have
.. failed with an error ``cannot concatenate 'str' and 'LazyString'
.. objects``:

遅延翻訳を使う場合に気をつけなければならない欠点が 1 つあります: それは
実際には文字列でありません。つまり、先ほどの例で以下のコードを使用して
いたら、エラー ``cannot concatenate 'str' and 'LazyString' objects`` で
失敗したでしょう。


.. code-block:: python

    response.write('Text: ' + text + '<br />')


.. For this reason you should only use the lazy translations where
.. absolutely necessary and should always ensure they are converted to
.. strings by calling ``str()`` or ``repr()`` before they are used in
.. operations with real strings.

この理由から、絶対に必要な場所でだけ遅延翻訳を使用すべきであり、本物の
文字列との操作に使用される前に ``str()`` または ``repr()`` を呼ぶことに
よって、それらが確実に文字列に変換されるようにすべきです。


.. Producing a Python Egg

Python Egg の生成
======================

.. Finally you can produce an egg of your project which includes the
.. translation files like this:

最後に、翻訳ファイルを含むプロジェクトの egg をこのように生成することが
できます:


.. code-block:: bash

    $ python setup.py bdist_egg


.. The ``setup.py`` automatically includes the ``.mo`` language
.. catalogs your application needs so that your application can be
.. distributed as an egg. This is done with the following line in your
.. ``setup.py`` file:

``setup.py`` は、アプリケーションを egg として配布することができるよう
に、アプリケーションが必要とする ``.mo`` 言語カタログを自動的に含めます。
これは、 ``setup.py`` ファイルの中の以下の行で行われます:


.. code-block:: python

    package_data={'translate_demo': ['i18n/*/LC_MESSAGES/*.mo']},


.. Plural Forms

複数形
============

.. Pylons also provides the ``ungettext()`` function. It's designed
.. for internationalizing plural words, and can be used as follows:

Pylons は、 ``ungettext()`` 関数も提供しています。それは複数形の単語を
国際化するために設計されており、以下のように使用することができます:


.. code-block:: python

    ungettext('There is %(num)d file here', 'There are %(num)d files here',
              n) % {'num': n}


.. Plural forms have a different type of entry in ``.pot``/``.po``
.. files, as described in `The Format of PO Files
.. <http://www.gnu.org/software/gettext/manual/html_chapter/gettext_10.html#PO-Files>`_
.. in `GNU Gettext's Manual
.. <http://www.gnu.org/software/gettext/manual/gettext.html>`_:

`GNU Gettext マニュアル
<http://www.gnu.org/software/gettext/manual/gettext.html>`_ の `PO ファ
イルフォーマット
<http://www.gnu.org/software/gettext/manual/html_chapter/gettext_10.html#PO-Files>`_
で説明されるように、複数形は ``.pot``/``.po`` ファイルにおいて異なった種類
のエントリーを持っています:


.. code-block:: pot

    #: translate_demo/controllers/hello.py:12
    #, python-format
    msgid "There is %(num)d file here"
    msgid_plural "There are %(num)d files here"
    msgstr[0] ""
    msgstr[1] ""


.. One thing to keep in mind is that other languages don't have the
.. same plural forms as English. While English only has 2 plural
.. forms, singular and plural, Slovenian has 4! That means that you
.. *must* use ugettext for proper pluralization. Specifically, the
.. following will not work:

気をつけるべきことの 1 つは、他の言語の複数形は英語と同じではないという
ことです。英語には 2 種類の複数形、単数と複数しかありませんが、スロベニ
ア語には 4 つの複数形があります! これは、複数形を適切に扱うためには
ugettext を使用し *なければならない* ということを意味します。特に、以下
は正しく動かないでしょう:


.. code-block:: python

    # BAD!
    if n == 1:
        msg = _("There was no dog.")
    else:
        msg = _("There were no dogs.")


.. Summary

まとめ
=======

.. This document only covers the basics of internationalizing and
.. localizing a web application.

このドキュメントは、ウェブアプリケーションの国際化とローカライズのため
のほんの基礎的な部分だけをカバーしています。


.. GNU Gettext is an extensive library, and the GNU Gettext Manual is
.. highly recommended for more information.

GNU Gettext は大規模なライブラリであり、詳しい情報を得るために GNU
Gettext マニュアルは非常に推奨されます。


.. Babel also provides support for interfacing to the CLDR (Common
.. Locale Data Repository), providing access to various locale display
.. names, localized number and date formatting, etc.

Babel は CLDR (Common Locale Data Repository) へのインターフェースのサ
ポートも提供します。 CLDR は、様々なロケール表示名やローカライズされた
数、日付の形式などへのアクセスを提供しています。


.. You should also be able to internationalize and then localize your
.. application using Pylons' support for GNU gettext.

Pylons の GNU gettext サポートを使用することで、アプリケーションを国際
化して、さらにローカライズすることができるでしょう。


.. Further Reading

さらに詳しく知るために
=======================

http://en.wikipedia.org/wiki/Internationalization

.. Please feel free to report any mistakes to the Pylons mailing list
.. or to the author. Any corrections or clarifications would be
.. gratefully received.

あらゆる誤りは遠慮なく Pylons メーリングリスト、または、著者に報告して
ください。どんな修正または明確化も感謝して受けつけます。


.. note::

    .. This is a work in progress. We hope the internationalization,
    .. localization and Unicode support in Pylons is now robust and
    .. flexible but we would appreciate hearing about any issues we
    .. have. Just drop a line to the pylons-discuss mailing list on
    .. Google Groups.

    この文書はまだ未完成です。 Pylons における国際化、ローカライズ、お
    よびユニコードサポートが現在、頑健かつ柔軟であることを願っています
    が、何か問題があれば喜んで聞きたいと思います。 Google Groupsの
    pylons-discuss メーリングリストにメールを出して下さい。


:mod:`babel.core` -- Babel core classes
===================================================

.. module:: babel.core

.. automodule:: babel

Module Contents
---------------

.. autoclass:: Locale
    :members:

.. autofunction:: default_locale
.. autofunction:: negotiate_locale
.. autofunction:: parse_locale

:mod:`babel.localedata` --- Babel locale data
====================================================

.. automodule:: babel.localedata

.. autofunction:: exists
.. autofunction:: exists

:mod:`babel.dates` -- Babel date classes
===================================================

.. automodule:: babel.dates

Module Contents
---------------

.. autoclass:: DateTimeFormat
    :members:
.. autoclass:: DateTimePattern
    :members:

:mod:`babel.numbers` -- Babel number classes
===================================================

.. automodule:: babel.numbers

Module Contents
---------------

.. autoclass:: NumberFormatError
    :members:

.. autoclass:: NumberPattern
    :members: __init__, apply

.. autofunction:: format_number
.. autofunction:: format_decimal
.. autofunction:: format_percent
.. autofunction:: format_scientific
.. autofunction:: parse_number
.. autofunction:: parse_decimal


.. autofunction: format_currency
