CakePHP ローカライゼーション i18nで多言語対応にする

静的テキストの自動翻訳機能の実装

仕組み

作業的には2つ。

1. ビューテンプレート内の静的テキストを「__(‘テキスト’)」の形式で記述
2. 翻訳ファイルを作成

ビューテンプレート内の静的テキストの記述

ビューテンプレート内の静的テキストを「__(‘テキスト’)」の形式で記述します。

<?php echo __('テキスト'); ?>

※半角アンダーバーは2連続っすッ

翻訳ファイルの素を作る

CakePHP に用意されている i18nスクリプト を使います。
※「i18n」とは、国際化(Internationalization)の略です。

1. コマンドプロンプトを起動

xampp を使って sample フォルダ内に CakePHP をインストールした前提で話を進めます。

2. phpのある場所に移動

cd c:¥xampp¥php

※XAMPPの場合です。それぞれの環境に合わせて PHP.EXE のある場所に移動してください。

3. PATH変数に追加

set path=%path%;%cd%

4. cake ディレクトリ内にある console ディレクトリに移動

cd c:¥xampp¥htdocs¥sample¥cake¥console

5. 再び、PATH変数に追加

set path=%path%;%cd%

6. CakePHP の app ディレクトリに移動

cd c:¥xampp¥htdocs¥sample¥app

7. i18n 起動

cake i18n

以下のように表示されたら、i18nスクリプトの起動成功です。
そしてこれが i18nスクリプトのメインメニューです。

8. POTファイルの作成

POTファイルが翻訳ファイルの素です。

[E]xtract POT file from sources を実行しますので、「e」を入力してEnter。

Exsample: C:¥xampp¥htdocs¥sample¥myapp
[Q]uite [D]one
[C:¥xampp¥htdocs¥sample¥app] >

「パスは?」

「app」フォルダが指定されているはずですので、そのままEnter。

Exsample: C:¥xampp¥htdocs¥sample¥myapp
[Q]uite [D]one
[D] >

「本当に?」

そのままEnter。[D]

What is the full path you would like to output?
Exsample: C:¥xampp¥htdocs¥sample¥app¥locale
[Q]uite
[C:¥xampp¥htdocs¥sample¥app¥locale] >

「POTファイルの出力先は?」

「locale」フォルダが指定されているはずですので、そのままEnter。

Would you like to merge all domains strings into the default.pot file? (y/n)
[y] >

「翻訳ファイルをマージしちゃっていいかな~?」

「y」を入力してEnter。

Extracting…

「抽出中… 抽出中…」

だーっと「__(‘テキスト’)」の形式で記述された静的テキストの抽出がはじまります。
終わったら i18nのメインメニューに戻ります。

これで app/locale フォルダ内に、「default.pot」という翻訳ファイルの素が作成されました。

中身を見てみましょう。

> app/local/default.pot

# LANGUAGE translation of CakePHP Application
# Copyright YEAR NAME <EMAIL@ADDRESS>
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"POT-Creation-Date: 2012-02-24 17:38+0900\n"
"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
"Last-Translator: NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"

#: \views\groups\index.ctp:25
#: \views\users\index.ctp:31
msgid "View"
msgstr ""

#: \views\groups\index.ctp:26
#: \views\users\index.ctp:32
msgid "Edit"
msgstr ""

#: \views\groups\edit.ctp:16
#: \views\groups\index.ctp:27
#: \views\users\edit.ctp:18
#: \views\users\index.ctp:33
msgid "Delete"
msgstr ""

// 省略

翻訳データは以下の部分です。

msgid "View"
msgstr ""

msgid – __()で記述したテキスト
msgstr – 翻訳テキスト

このファイルをもとに、各言語の翻訳ファイルを作成していくことになります。

各言語の翻訳ファイルの作成

1. app/locale フォルダ内に、各言語のフォルダを作成
  ※ディフォルトでは「eng」(英語)というフォルダがあるはず
2. その中に、LC_MESSAGES というフォルダを作成
3. その中に、さきほど作った default.potdefault.po にリネームしてコピー
4. 各言語の翻訳データを作成

では、CakePHP bakeによる高速開発 で作ったアプリケーションを日本語にローカライズしてみましょう。

とりあえず、赤丸で囲った部分を日本語にローカライズしてみることにします。

該当部分のソースコードはこうなっています。
bake で作成したので、ビューテンプレート内の静的テキストは「__(‘テキスト’)」の形式で記述されています。

<td class="actions">
	<?php echo $this->Html->link(__('View', true), array('action' => 'view', $user['User']['id'])); ?>
	<?php echo $this->Html->link(__('Edit', true), array('action' => 'edit', $user['User']['id'])); ?>
	<?php echo $this->Html->link(__('Delete', true), array('action' => 'delete', $user['User']['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $user['User']['id'])); ?>
</td>

日本語の翻訳テキストを埋めていきます。

> 日本語の翻訳ファイル(app/locale/jpn/LC_MESSAGES/default.po)

#: \views\groups\index.ctp:25
#: \views\users\index.ctp:31
msgid "View"
msgstr "表示"

#: \views\groups\index.ctp:26
#: \views\users\index.ctp:32
msgid "Edit"
msgstr "編集"

#: \views\groups\edit.ctp:16
#: \views\groups\index.ctp:27
#: \views\users\edit.ctp:18
#: \views\users\index.ctp:33
msgid "Delete"
msgstr "削除"

じゃん!

日本語にローカライズされました!

同様の手順ですべての翻訳テキストを埋めていけば完璧です。

言語の切り替え

自動翻訳はシステム言語に依存しますので、日本語以外の翻訳ファイルを用意しても、ほとんどの人のPCでは日本語でしか表示されません。それが普通です。

でも一応、システム言語に関係なく、半強制的に切り替えることもできます。

> users_controller.php

function index() {
	Configure::write('Config.language', 'en');
	$this->User->recursive = 0;
	$this->set('users', $this->paginate());
}

ちなみに

静的テキストの他に、データベースに登録したデータを自動翻訳する機能もあります。
これは、モデルの拡張、ビヘイビアで組み込むことになります。
これについてはまたの機会に。(もしくは他の人にお任せします。。

Comments

コメントを残す