国際化 (I18N)

国際化 (I18N) はプログラムの変更なしで、各言語、各地域に適合できるように、 ソフトウェアアプリケーションを設計する過程を指します。 ウェブアプリケーションでは、ユーザーになる可能性のある人が世界中から訪れるため、 特に重要です。

Yii は I18N のサポートをいくつかの面から提供します。

  • 各可能な言語と変形のためのロケール(地域・言語)データの提供
  • メッセージとファイルの翻訳機能の提供
  • ロケール(地域・言語)に依存する日時フォーマットの提供
  • ロケール(地域・言語)に依存する数値フォーマットの提供

以下のサブセクションで上記について詳しく説明します。

1. ロケールと言語

ロケールはユーザー言語の定義、国、ユーザーがユーザーインターフェースに期待する、 その他特別な優先傾向のパラメータのセットです。 これは、通常、言語 ID と地域 ID から成る ID により確認されます。 たとえば、ID en_US は、英語とアメリカのロケールを表します。 整合性のため、Yii の全てのロケール ID は、小文字で LanguageIDLanguageID_RegionID のフォーマットで標準化されています。(例:en, en_us

ロケールデータは、CLocale のインスタンスとして表されます。 これは、通貨記号、数値記号、通貨フォーマット、数値フォーマット、 日時フォーマット、日付に関する名称を含むロケールに依存する情報を提供します。 言語情報はロケール ID に含まれるため、CLocale では提供されません。 同様に、多くの場合、ロケールと言語は同じ意味として使用します。

ロケール ID を与えると、CLocale::getInstance($localeID) もしくは CApplication::getLocale($localeID) により、 それに一致する CLocale インタンスを取得できます。

情報: Yii にはほとんど全ての言語と地域のためのロケールデータを含まれます。 データは 共通ロケールデータリポジトリ (CLDR) より取得されています。 各ロケールは、CLDR により提供されたオリジナルデータに含まれるうちの 主要な情報のサブセットになります。

Yii アプリケーションのために、ソース言語ターゲット言語 を区別します。ターゲット言語は、 アプリケーションが対象とするユーザーの言語(ロケール)で、一方、 ソース言語はアプリケーションソースファイルに書かれている言語(ロケール)を 示します。 国際化は 2 つの言語が異なる場合のみで起こります。

ターゲット言語 は、 アプリケーション初期構成 か、 それを国際化が起こる前に動的に変更することで、設定を行えます。

ヒント: ユーザー(ブラウザの設定で定められている)により優先された言語により、 ターゲット言語を設定したいかもしれません。その場合、CHttpRequest::preferredLanguage を使ってユーザーの優先言語 ID を読み出せます。

2. 翻訳

I18N でもっとも必要なのは、おそらくメッセージ翻訳やビューの翻訳などの 翻訳です。前者はテキストメッセージの目標言語への翻訳、 後者はファイル全体の目標言語への翻訳です。

翻訳リクエストは翻訳対象(メッセージ、ビュー)、 対象(メッセージ、ビュー)のあるソース言語、 対象(メッセージ、ビュー)が翻訳される必要のあるターゲット言語から構成されます。 Yii では、ソース言語はデフォルトの アプリケーションソース言語 になり、ターゲット言語はデフォルトの アプリケーション言語 になります。 ソースとターゲット言語が同じ場合、翻訳されません。

メッセージ翻訳

メッセージ翻訳は、Yii::t() をコールすることで行われます。 メソッドは指定されたメッセージを、ソース言語 から ターゲット言語 へと翻訳します。

メッセージを翻訳するときには、メッセージが異なるカテゴリ(文脈)の下で 異なる翻訳が行われる可能性があるため、カテゴリを指定すべきです。 カテゴリ yii は Yii フレームワークのコアコードによって使用されるメッセージのために 予約済みです。

メッセージは、Yii::t() を呼び出す際に、実際のパラメータ値によって置き換えられる パラメータプレースホルダを含められます。 例えば、以下のメッセージ翻訳リクエストは、オリジナルメッセージの {alias} プレースホルダを、実際の alias 値で置き換えます。

Yii::t('yii', 'Path alias "{alias}" is redefined.',
    array('{alias}'=>$alias))

注意: 翻訳されるメッセージは一定の文字列です。それらにはメッセージ内容を 変える変数("Invalid {$message} content." のような)を含めるべきではありません。 メッセージがいくつかの要素により変化する必要がある場合、 パラメータプレースホルダを使用してください。

翻訳されたメッセージは、メッセージソース と呼ばれるリポジトリに保存されます。 メッセージソースは、CMessageSource か、その子クラスのインスタンスに相当します。 Yii::t() が呼び出された際に、メッセージソースのメッセージを探し、 翻訳されたバージョンを返します。

Yii は下記メッセージソースのタイプを備えています。 CMessageSource を継承して、オリジナルのメッセージソースタイプを 作成することも可能です。

  • CPhpMessageSource: メッセージ翻訳は、PHP 配列の キーと値の組み合わせで 格納されます。オリジナルメッセージはキーに、翻訳されたメッセージは値になります。 各配列はメッセージの個々のカテゴリ内の翻訳を表し、 カテゴリ名で名づけられた PHP スクリプトファイルに分けて保存されます。 同じ言語のPHP 翻訳ファイルはロケール ID を名前とした同じディレクトリ下に 保存されます。 そして、それら全てのディレクトリは、basePath により特定のディレクトリ下に位置します。

  • CGettextMessageSource: メッセージ翻訳は、GNU Gettext ファイルとして保存されます。

  • CDbMessageSource: メッセージ翻訳は、データベーステーブルとして 保存されます。詳細は、API ドキュメンテーション CDbMessageSource を参照してください。

メッセージソースは、 アプリケーションコンポーネント として読み込まれます。 Yii は、messages という名前のアプリケーションコンポーネントが ユーザーアプリケーションで使用されるメッセージを格納するとあらかじめ宣言します。 デフォルトでは、メッセージソースのタイプは CPhpMessageSource で、 protected/messages が PHP 翻訳ファイルのベースパスとなります。

要約すると、メッセージ翻訳を使用するためには、下記のステップが必要です:

  1. 適切な箇所で Yii::t() をコールします。

  2. protected/messages/LocaleID/CategoryName.php に PHP 翻訳ファイルを作成します。各ファイルは、単にメッセージ翻訳の配列を返します。 注:あなたが翻訳メッセージを保存するのにデフォルトmp CPhpMessageSource を使用すると仮定しています。

  3. CApplication::sourceLanguageCApplication::language の設定を行います。

ヒント: CPhpMessageSource をメッセージソースとして使用する場合、 メッセージ翻訳を管理するために、Yii の yiic ツールを利用できます。 message コマンドでは、自動的に選択されたソースファイルから 翻訳されるべきメッセージを抽出し、必要なら、既存の翻訳にそれらをマージできます。

バージョン 1.0.2 以降、Yii は choice format のサポートが追加されました。 choice format は、与えられた数値に従い翻訳を選択します。 たとえば、'book' という単語は、英語では、本の数によって単数形か複数形のどちらかを取りますし、 また、他の言語では、(中国語のような)異なる形を持たない場合、 (ロシア語などのように)より複雑な複数形の規則がある場合があります。 choice format はこの問題を簡単かつ効果的な方法で解決します。

choice format を使用するには、翻訳メッセージが下記のように | によって分けられた、式-メッセージの組の列で構成されている必要があります:

'expr1#message1|expr2#message2|expr3#message3'

exprN は、返されるべき対応したメッセージかどうかを表す boolean 値に評価される 有効な PHP 式です。最初に true に評価された式に一致したメッセージのみが返されます。 式には、最初のメッセージパラメータとして渡された数値を表す n(注意:$n ではありません)という名前の特別な変数を含められます。 たとえば、翻訳されたメッセージを

'n==1#one book|n>1#many books'

と仮定し、Yii::t() を呼び出す際、メッセージのパラメータ配列に 数値 2 を渡した場合、最終的に翻訳メッセージには many books が返されます。

略記法として、式が数値のみの場合、n==数値 と解釈されます。 そのため、上記の翻訳メッセージは下記のように記述することも可能です。

'1#one book|n>1#many books'

ファイル翻訳

ファイル翻訳は、CApplication::findLocalizedFile() を呼び出すことで行われます。 翻訳を行うために、ファイルのパスを与えると、メソッドは LocaleID サブディレクトリ下にある 同じ名前のファイルを探します。ファイルが見つかれば、ファイルパスを返します。 見つからない場合、オリジナルのファイルパスを返します。

ファイル翻訳は、主にビューの描画で使用されます。 コントローラかウィジェット内でレンダーメソッドの一つを呼び出した際、 ビューファイルは自動的に翻訳されます。 たとえば、ターゲット言語zh_cn で、 ソース言語en_us の場合、 edit という名前のビューの描画では、ビューファイル protected/views/ControllerID/zh_cn/edit.php を検索します。 ファイルが見つかれば、この翻訳された版が描画に使用されます。 見つからない場合、代わりに protected/views/ControllerID/edit.php によって描画されます。

また、ファイル翻訳は、たとえば、翻訳された画像やロケール依存のデータファイルをロードし、 表示するためなど、他の目的のために使用されるかもしれません。

3. 日付と時刻フォーマット

日付と時刻は、国や地域によって異なる書式がしばしば利用されます。 日付と時刻フォーマットの目的は、ロケールに基づき、そのロケールに適した 日付や時刻の文字列を生成することです。 Yii は、この問題のために、CDateFormatter を提供します

CDateFormatter インスタンスは、ターゲットロケールと結びついています。 アプリケーション全体のターゲットロケールに結びついたフォーマッタの取得は、 アプリケーションの dateFormatter プロパティを使い、 簡単にアクセスできます。

CDateFormatter クラスは主に UNIX タイムスタンプをフォーマットする 2 つのメソッドを提供します。

  • format: このメソッドは、カスタムパターンに基づき、 UNIX タイムスタンプを文字列にフォーマットします。(たとえば、 $dateFormatter->format('yyyy-MM-dd',$timestamp)

  • formatDateTime: このメソッドは、 ターゲットロケールデータに定義されているパターンに基づき、 UNIX タイムスタンプを文字列にフォーマットします。(たとえば、日付の short フォーマット、時刻の long フォーマット)

4. 数値フォーマット

日付と時刻のように、数値も国や地域によって異なる書式が利用されます。 数値委フォーマットは、小数フォーマット、通貨フォーマット、パーセンテージフォーマットを 含みます。Yii は、これらのために CNumberFormatter を提供します。

アプリケーション全体のターゲットロケールに結びついた数値フォーマッタの取得は、 アプリケーションの numberFormatter プロパティを使い、 アクセスできます。

下記メソッドが、integer、double 値のフォーマットのために、 CNumberFormatter によって提供されています。

  • format: このメソッドは、 カスタムパターンに基づき、数値を文字列にフォーマットします。(たとえば、 $numberFormatter->format('#,##0.00',$number)

  • formatDecimal: このメソッドは、 ターゲットロケールデータに定義されている小数パターンに基づき、 数値を文字列にフォーマットします。

  • formatCurrency: このメソッドは、 ターゲットロケールデータに定義されている通貨パターンに基づき、 数値と通貨記号を文字列にフォーマットします。

  • formatPercentage: このメソッドは、 ターゲットロケールデータに定義されているパーセンテージパターンに基づき、 数値を文字列にフォーマットします。

$Id: topics.i18n.txt 772 2009-02-28 18:23:17Z qiang.xue $

Be the first person to leave a comment

Please to leave your comment.