Logicky Blog

Logickyの開発ブログです

cakePHP2 - 多言語化

多言語化します。

cakephpマニュアルのこのページに説明が書いてあります。 あと、翻訳ファイルの作成については、ここが参考になりました。

翻訳したい文字列を指定する

翻訳対象にしたい文字列は、__()というのでくくります。

翻訳ファイルの作成

まず翻訳ファイルを作成します。下記のようなコマンドで作成できます。POTファイルというのをつくります。

$ cd app/Console
$ ./cake i18n

下記を実行すると、potファイルが作成されます。default.potというのが自分で__()でくくった部分の翻訳ファイルです。

[E]xtract POT file from sources

moファイルの作成

potファイルは、cakePHPが翻訳できないので、moファイルというのを作る必要があります。Poeditというソフトでmoファイルの作成が可能です。 Poeditを起動すると下記画面になるので、2番目の翻訳プロジェクトを新規作成するをクリックします。元になるPOTファイル(上記で作成したapp/Locale/default.pot)を選択すると、翻訳画面が表示されます。ここで翻訳を入力して、保存すると勝手にmoファイルも作成されます。保存場所とファイル名は、例えば英語の翻訳ファイルの場合、app/Locale/eng/LC_MESSAGES/default.poにします。

これでcakePHPはブラウザの言語環境に応じて勝手に翻訳を表示してくれます。

翻訳対象言語毎の保存先ディレクトリ名について

保存先ディレクトリ名となる、 3文字ロケールコードは、ISO 639-2 標準に準拠します。

日本以外ではデフォルトで英語表示にする場合

前提では、とりあえず__('ログイン')みたいな感じで、日本語でデフォルト文字列を作成していることとします。 その場合、翻訳ファイルがなければ日本語で表示されますが、日本以外の国で翻訳ファイルがない場合は、英語表示にしたいとします。

cakePHPでどの言語環境かを確認する方法

下記で確認できます。

Configure::read("Config.language")

言語環境を設定するには、下記でできます。

Configure::write('Config.language', 'fra');

デフォルト英語表示の方法

・何かで翻訳ファイルがある、言語のリストを作成しておき ・言語環境を確認して、翻訳ファイルがない場合 ・言語環境をengに設定する

Viewファイル自体を言語環境ごとに切り替える方法

・言語毎のviewファイルを用意する ・言語環境を確認する ・言語環境に応じたViewファイルを読み込ませる

基本的には上記のはずですが、Configure::read('Config.language')で取得できる値が、en-usとかになり、engなどの3文字ではないです。よって、en-us等を翻訳ファイルの3文字ロケールコードに変換する処理が必要だと思います。最悪っす。cakePHPでは、en-usからうまいことengであることを判別しているはずなので、そのコードを利用することでできるのかなと思います。lib/Cake/i18n/L10n.phpに対応する配列定義がありました。ちなみに、en-usというのは英語圏のどの地域かまで指定するためのやつらしくて、3文字ロケールコードっていうのは英語とかざっくりした感じのやつっぽい。今回の翻訳でイギリスとアメリカで英語をわけるようなことはしないので、細かいやつを何しろ3文字ロケールコードに直すことにした。

下記にAPIリファレンスがあります。この辺のを使うことで変換できるのかなと思います。 https://api.cakephp.org/2.9/class-L10n.html

Configure::write('Config.language', 'en-us');
$lang = Configure::read('Config.language');
$L10n = new L10n();
$catalog = $L10n->catalog($lang);
$this->log($catalog['localeFallback']);

上記をやると、ログにengと出力される。jaならjpn。fr-frなら、fra。 でも、なんかbeforeFilter内だと、Configure::readで何にも返ってこない。下記のような関数をコンポーネントとして作って、PagesControllerのdisplayアクションとかで使えばできる。

L10nComponent

public function getLocale3()
{
    $lang = Configure::read('Config.language');
    $L10n = new L10n();
    $catalog = $L10n->catalog($lang);
    if(!empty($catalog['localeFallback'])){
        return $catalog['localeFallback'];
    }else{
        return null;
    }
}

PagesController - display()

$locale = $this->L10n->getLocale3();
$viewPath = $locale.'/'.implode('/', $path);
$this->render($viewPath);

これは、app/View/Pagesの中に、engとかjpnとかのフォルダを作って、それぞれの言語用の静的Viewファイルを格納している場合です。