1.2系の多言語対応メモ(2)
前回の記事の続きです。
指定した言語の翻訳が存在しない場合は引数の値(msgid)がそのまま表示される
指定した言語のlocaleのフォルダやpoファイルがない、対訳が存在しない等の場合、__()関数の第1引数の値(msgid)そのものが表示されます。
なので、引数のメッセージには意味の通る文章を必ず入れるのがベストです。
__()関数以外にも翻訳関数が存在する
cake\basics.phpを覗くと、__()関数以外にも
- __d()
- __c()
- __n()
- __dn()
- __dc()
- __dcn()
といった翻訳関数が存在します。
これらの関数名には意味があり、関数名にdが含まれる関数は「ドメインの指定」、cが含まれる関数は「カテゴリーの指定」、nが含まれる関数は「複数形への対処の指定」が出来るようになっています。
例えば、__d()は「ドメインの指定が出来る翻訳関数」、__dc()は「ドメインとカテゴリの指定が出来る翻訳関数」といったようにd,c,nの組み合わせで関数名が作られています。
ドメインの指定とは
ドメインとはファイル名のdefault.poの拡張子を除いた値に該当します。
例として、
__d('sample', 'This is a message');
とすると、指定言語のフォルダのsample.poファイルからmsgidが'This is a message'の対訳を取得します。
カテゴリの指定とは
カテゴリーとはpoファイルまでのパスがapp\locale\jpn\LC_MESSAGES\default.poだとすると、"LC_MESSAGES"部分の値に該当します。
カテゴリーは0〜6の値で指定することが出来、それぞれは
LC_CTYPE 0 LC_NUMERIC 1 LC_TIME 2 LC_COLLATE 3 LC_MONETARY 4 LC_MESSAGES 5 ←デフォルト値 LC_ALL 6
という意味になります。
例として、
__c('xxx', 1);
とすると、指定言語のフォルダの"LC_NUMERIC"フォルダから対訳を取得するようになります。
ただ、実際にメッセージ(LC_MESSAGES)以外のカテゴリーを指定した場合、日付の形式や通貨の表示などをどのように実装するのか、どうすればちゃんと動作するのかまでは検証できていません。
複数形への対処の指定とは
日本語ではあまり意識しない単数形と複数形の違い、例えば日本語で「〜個のファイルが削除されました。」というのは個数に関係なく同じ表現ですが、英語では「1 files was removed.」「2 files were removed.」と単数形と複数形では表現が異なります。
例として、英語のpoファイルの中に
"Plural-Forms: nplurals=2; plural=(n!=1);" msgid '%d file was removed.' msgid_plural '%d files were removed.' msgstr[0] '%d file was removed.' msgstr[1] '%d files were removed.'
という設定をして
__n('%d file was removed.', '%d files were removed.', n);
とした場合、第3引数のnの値が1の場合はmsgstr[0]の'%d file was removed.'、1以外の場合はmsgstr[1]の'%d files were removed.'が使われます。
細かい説明は省略しますが、参考にしたサイトのリンクを貼っておきます。参考サイトはRubyでのgettextの話ですが、Plural-Formsの設定内容等は同じ考えなので参考になります。
翻訳リソースはバイナリ形式のmoファイルでもいける
通常、国際化といえばgettextを使用してpoファイルの作成⇒バイナリ形式のmoファイルの作成⇒プログラムからはmoファイルを使用といった手順が標準のようですが、CakePHPではpoファイルからの翻訳が可能です。
では、CakePHPではmoファイルが使えないのかというとそうではないようで、moファイルがあればmoファイルの翻訳を見にいくようになっています。
例えば
__('hoge');
としたとき、default.moが存在すれば、default.poではなくdefault.moから翻訳を取り出します。
moファイルはバイナリ形式なので、テキスト形式のpoファイルに比べてパフォーマンスが良さそうですね。
気が向いた時にベンチマークでも取ってみようと思います。