Documentation

You are viewing the documentation for Play 1. The documentation for Play 2 is here.

国際化

国際化 (I18N) とは、アプリケーションを異なる言語に適応させ、地域の差異を吸収することを意味します。アプリケーションを国際化対応可能にするためには、以下の手順に従ってください。

使用するのは UTF-8 だけ!

Play はたったひとつの文字エンコーディングをサポートします: UTF-8 です。文字エンコーディングの問題は異様で扱いが難しいので、Play は、ただひとつの文字エンコーディングをサポートすることを選択しました。UTF-8 では、すべての言語のすべての文字を表示することができます。

アプリケーション全体を通して、一貫して UTF-8 を使用するよう気を付けてください:

注意

UTF-8 エンコーディングに関する問題は、Play の設定ファイルのほとんどが、それらが Java プロパティファイルであるにも関わらず、 *.properties と名付けられていない理由です。Java は、プロパティファイルは ISO-8859-1 でエンコーディングしなければならないという制約を課します。Play の設定ファイルは UTF-8 でエンコーディングしなければなりません。これ以上なにか言う必要はありますか?

メッセージの外部化

I18N をサポートするには、アプリケーション中のすべてのメッセージを外部化しなければなりません。

アプリケーションの conf/ ディレクトリに messages という名前のファイルを作成してください。このファイルは本当にただの Java プロパティファイルです。

hello=Hello!
back=Back

その後、アプリケーションで使用する言語ごとに、特別な message ファイルを定義することができます。単純に、ISO 言語コードをファイルの拡張子として追加してください。

例えば、対応するフランス語の訳語を含むメッセージファイルは conf/messages.fr です:

hello=Bonjour!
back=Retour

アプリケーションがサポートする言語の定義

サポートする言語のリストを application.langs 設定 に定義してください。

新しいユーザからの最初のリクエストの際は、Play は使用するデフォルトの言語を推測します。これは HTTP Accept-language ヘッダを解析して行います。その後、選択した言語を PLAY_LANG クッキーに保存します。このため、次のリクエストは選択した言語を使用します。

en_US と en_GB や zh_CN と zh_TW のようなバリアントを区別するために、言語/国のペアを使うこともできます。しかし、あるユーザは Accept-language において言語のみを提示し、国を提示しないかもしれないことに注意してください。このような理由から、常に (例えば en のような) “生の” 言語を提供すべきです。

例えば、ユーザのほとんどが US からやってくるけれど、イギリス英語もサポートしたい場合、アメリカ英語には単に “en” を使い、イギリス英語に “en_GB” を使うことをお勧めします。

play.i18n.Lang オブジェクトにアクセスすることで、アプリケーションからこのユーザの現在の言語情報を検索することができます:

String lang = Lang.get();

このユーザの言語情報を恒久的に変更したい場合は、change() メソッドを使用します:

Lang.change("ja");

新しい値は、このユーザの言語クッキーに保存し直されます。

ロケールに沿った日付データフォーマット

date.format を設定して、使用するデフォルトの日付フォーマットを指定します。

ローカライズされたメッセージの検索

メッセージ引数

メッセージファイルに定義したメッセージをアプリケーションコードから検索することができます。Java からは、 play.i18n.Messages オブジェクトを使用します。

public static void hello() {
    renderText(Messages.get("hello"));
}

標準的な java.util.Formatter の‘フォーマット文字列構文’をサポートしています。メッセージ中に動的な内容を定義することもできます:

hello=Hello %s!

%sString として出力されるメッセージ引数を表しています。メッセージ引数は、 Messages.get の (可変長) 引数に追加することで提供されます:

public static void hello(String user) {
    renderText(Messages.get("hello", user));
}

テンプレート出力

テンプレートでは、特別な &{…} 構文を使ってローカライズされたメッセージを表示することができます:

<h1>&{'hello'}</h1>

メッセージ引数に動的なコンテンツを使うこともできます:

<h1>&{'hello', params.user}</h1>

複数の引数

以下の二つの ‘10 進数’ の引数を参照するメッセージのように、複数のメッセージ引数を定義することができます:

guess=Please pick a number between %d and %d

メッセージ引数は表示する順序通りに指定します:

<p>&{'guess', low, high}</p>

引数インデックス

明示的に順序を指定したメッセージ引数を使うこともできます。例えば、二つの引数を持つ英語のメッセージがあるとします:

guess.characteristic=Guess %s’s %s.

以下のようにして出力します:

<p>&{'guess.characteristic', person.name, 'age'}</p>

フランス語版メッセージの二つの引数は順序が逆なので、フランス語版メッセージでは引数インデックスを指定します:

guess.characteristic=Devinez %2$s de %1$s.

%2$s には 二番目の 引数が 10 進数として出力されます。

最後に、特徴的な名称である ‘age’ も国際化したいので、以下のように変更したメッセージ定義と、メッセージキー person.age を使って、出力を変更したいと思います:

guess.characteristic=Guess %s’s &{%s}.
person.age = age

フランス語版メッセージ定義は以下のように変更します。

guess.characteristic=Devinez &{%2$s} de %1$s.
person.age = l’age

&{%s} は、それ自身が引数の値をメッセージキーとして、メッセージを引き当てます。

考察を続けます

次: キャッシュ