5分でわかる PHP で書かれた Web サービスの国際化(その2)に続き、今回はメッセージの切替えの例を紹介したいと思います。これらはフォト蔵とその英語版PhotoZou.comで実際におこなっている例です。(厳密に言うとフォト蔵では、gettext ではなく独自の仕組みを使っていますが、基本的な考え方は全く同じなので、以下同じ事例を gettext に引きなおして説明しています。)
まずはメッセージの内容の一部を変数にして自由に入れ変えたいという場合。
エラーメッセージで「○○は△△文字以上です。」と表示したいとき、
msgid "%1$s has exceeded the limited capacity of %2$s characters." msgstr "%1$sが%2$s文字以上です。" msgid "Your Comment" msgstr "コメント"
という日本語のメッセージファイルを用意し、実際に表示するときは、プログラムで
$message = gettext('%1$s has exceeded the limited capacity of %2$s characters.'); $item = gettext('Your Comment') printf($message, $item, 200);
というように printf を使います。printf の第1引数 $item が言語が日本語なら「コメント」になり、$format の %1$s に入るわけです。第2引数の200は %2$s に代入されるので、結果として日本語では、「コメントが200文字以上です。」と表示されます。
gettext では msgid に対応するその言語の msgstr が呼びだされますが、もし対応するメッセージファイルがない場合、あるいは msgstr が定義されていないときには、msgid がそのまま表示されます。ですから、msgid は万一表示されてしまっても構わないように、きちんと意味の通じる英語にしておくべきです。たとえば、
Add favorite msg1
といった無意味な msgid は避けるべきでしょう。
次に、良く問題となる名前の表示部分。姓と名がどちらが先かという順番は国ごとに異なるので、表示部分をメッセージファイルで以下のように定義します。
# # 英語メッセージファイル # msgid "%1$s %2$s" msgstr "%1$s %2$s"
# # 日本語メッセージファイル # msgid "%1$s %2$s" msgstr "%2$s %1$s"
プログラム中では
$name = gettext('%1$s %2$s') printf($name, $first_name, $last_name);
のように呼びだします。
$first_name、$last_name にそれぞれ代入される名前と苗字は英語ではそのまま表示され、日本語では反転します。
ただ、この仕様は、真に国際化されたアプリケーション向きではありません。
国・言語によっては、そもそも名前と苗字という概念がないところもあるので、名前全体をひとくくりで扱うほうがよいのかもしれません。
その場合は、名前の入力を促すフォームでは一つのテキストフィールドで扱い、データベースに保存するときも name というフィールドを一つだけ用意します。上記で説明したように順番を入れ替える必要もなくなり、シンプルな作りとなります。