Fuelphpを国際化(多国語対応)で使うため、調査したメモです。
(Fuelphp version 1.1-RC1の記事です。)
まず、言語設定はapp/config/config.phpで設定されています。
'language' => 'en', // デフォルト言語 '
language_fallback' => 'en', // デフォルトの言語が見つからない時のフォールバック
'locale' => 'en_US', // PHP set_locale() の設定
言語は後から設定してもいいのですが、ややこしくなり、またその言語を指定して言語ファイルを読み直さなくてはならなくなり、オーバーヘッドも増えるため、ここで設定してみました。(段々Fuelを理解するにつれ、理解が深まりました。自前の言語設定ファイルは、自分でロードを指定するので、オーバーヘッドは増えませんね。ここで設定する利点があるとすれば、後で言語の設定を考えなくて良い点です。ユーザー登録があるサイトで、ユーザーが使いたい言語を選択できるようにするならば、ユーザー情報としてDBに保存しておき、後ほどConfig::setを利用して、設定言語を変更してあげれば済むようです。その処理はここではありません。このようなconfigファイルの処理は、フレームワークとしての動作の前処理です。DBの操作などの準備がこの時点では整っていません。)
まず、このファイル中は、一つのreturn文で配列を返して、その中で項目が設定されています。最初はなるべくシステムを汚染しないようにしようと思いました。3項演算子を使って書いてもいいのですが、面倒なので、一つ長めの名前の関数を作成し、その名前が何かとバッテングしないように願うという、古典的な解決策を取ることにしました。ベストな方法を探すために、長々とコアのコードを読むのは、避けたいのです。
return文の前に追加しました。
// 多国語化対応
function local_from_http_for_i18n()
{
// IEは設定言語を指定しないこともでき、その場合はHTTP_ACCEPT_LANGUAGEが存在しない
if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
{
return 'en-US';
}
else
{
return Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);
};
}
function local_form_http_and_os()
{
// set_localウィンドウズでは''でシステムの持っている
// 全言語が割り付けられる
if (PHP_OS === 'WINNT' or PHP_OS === 'WIN32')
{
return '';
}
else
{
return local_from_http_for_i18n();
}
}
次に、languageとlocalを設定します。language_fallbackは英語のままで良いでしょう。
'language' => substr(local_from_http_for_i18n(), 0, 2), // デフォルト言語
'language_fallback' => 'en', // デフォルトの言語が見つからない時のフォールバック
'locale' => local_form_http_and_os(), // PHP set_locale() の設定
タイムゾーンの設定もconfig.phpの中にありますね。これもどうにか設定できると便利なのですが、同一言語は同一タイムゾーンでは無いため、後で考えることにしました。
言語の設定ファイルの構成はapp/langの下に、翻訳したい言語、例えば日本語なら、jaというディレクトリーを作成し、その下にカテゴリー名.phpというファイルを作成します。
実例がないと、試せないので、前回投稿した、ブログチュートリアルを例にします。
まず、手始めにバリデーションのエラーを日本語化してみましょう。core/lang/en/validation.phpをapp/lang/ja/の下にコピーします。app/languの下にまだ作っていない方はjaディレクトリーを作成してから、コピーします。
では、バリデーションエラーを日本語化しましょう。お好きな日本語に翻訳してみてください。私は次のように訳しました。
<?php
return array(
'required' => ':label 項目を必ず指定してください',
'min_length' => ':label に :param:1 文字以上、入力してください',
'max_length' => ':label は :param:1 文字以下で、指定してください',
);
:に続く項目は、他の文字列に置き換えられる部分です。:labelは入力項目名です。:param:1は文字列数ですね。
保存したら、ブラウザからアクセスしてテストしてみましょう。新しい記事を投稿するときに、エラーを起こすと、メッセージが日本語されていると思います。もちろん、ブラウザの設定が日本語をデフォルトとしているならです。英語に変えると、エラーメッセージも英語に変わります。
前回のブログチュートリアルで、バリデーションを仕込んだ部分のコードは、次のものです。
public function action_create($id = null)
{
if (Input::method() == 'POST')
{
// バリデーションの開始、引数省略で'default'
// もし複数のパリディーションパターンが必要なら、引数に名前を渡せる
$val = Validation::forge(); // titleはエラーメッセジでタイトルと表示される用に設定
// 必須項目
$val->add('title', 'タイトル')
->add_rule('required'); // summaryはサマリーと表示
// 必須、最低10文字、最長250文字をチェック
$val->add('summary', 'サマリー')
->add_rule('required')
->add_rule('min_length', 10)
->add_rule('max_length', 250); // bodyは記事と表示
// 必須項目
$val->add('body', '記事')
->add_rule('required'); // バリデーションの実行
// エラーがなければ、TRUEが返る
if ($val->run())
{
// バリデーション成功、エラー無し
// $val->validated()はバリデーションに成功した項目名と値の配列
// Post::forge(array())でPOSTクラスのインスタンスを作り、配列の内容をプロパティとして取り込む
// Postはcrudモデルを拡張している。crud機能の実現のため複雑な処理をしているらしい
// このあとのsave()への前処理のようなもの、決め打ちのコードとして利用することに
$post = Post::forge($val->validated()); // 保存処理
if ($post->save())
{
Session::set_flash('notice', 'ポスト番号' . $post->id . 'を追加しました');
Response::redirect('posts');
}
else
{
Session::set_flash('notice', 'ポストの保存に失敗しました');
}
}
else
{
// バリデーション失敗、入力にエラー有り
// $val->errors()はバリデーションに失敗した項目名とエラーの配列
Session::set_flash('notice', $val->errors());
}
} $this->template->title = "Posts";
$this->template->content = View::forge('posts/create');
}
バリデーションを通ったあと、ポストの成功と失敗を知らせるメッセージがハードコードされています。これを英語と日本語で表示するようにします。
まずはメッセージのファイルを作成しましょう。/app/lang/enの下にblog.phpを作成しましょう。
<?php
return array(
'create_successfully' => 'Added post # :post_id.',
'create_faild' => 'Could not save post.',
);
次に/app/lang/jaの下にもblog.phpを作成します。
<?php
return array(
'create_successfully' => 'ポスト番号 :post_id を追加しました',
'create_faild' => '新しいポストの投稿に失敗しました',
);
キーと値の配列です。簡単ですね。
マニュアルを読み、コードをチェクしたら、Kohanaフレームワークと同様な手法が取れるようです。というより、様々なフレームワークやCMSではお馴染みの__()関数が用意されています。置き換え関数です。
置き換える文字列がない場合、__('キー名')で設定した言語の文字列が返ります。
今、作成した言語ファイル中なら、作成に失敗した時のメッセージですね。__('create_faild')と呼び出します。
置き換える文字列がある場合は、2つ目の引数に配列で指定します。作成した言語ファイルの場合、ポスト成功時にpost IDも表示します。__('create_successfully', array('post_id' => $post->id))です。
これでハードコードされている部分を置き換えます。細かい部分も全部、多国語化可能ですが、とりあえず2つのメッセージだけ、対応して見ました。
__()を使用する前に、blog.phpを読み込みましょう。
Lang::load('blog');です。config.php中で、アクセスしてくるブラウザの設定がデフォルト言語としてFuelphpに設定しました。langディレクトリー下にその言語のディレクトリーが存在すれば、さらにその中にblog.phpを探します。存在すれば、読み込みますが、読み込めなければ、フォールバック言語に指定した英語のen/blog.phpが読み込まれます。
今回は英語と日本語だけしか用意していないので、ブラウザの設定が日本語であれば日本語で、それ以外の言語では英語で表示されます。
最後にこれまでの修正を取り込んだコードをのせておきます。
public function action_create($id = null)
{
if (Input::method() == 'POST')
{
// バリデーションの開始、引数省略で'default'
// もし複数のパリディーションパターンが必要なら、引数に名前を渡せる
$val = Validation::forge();
// titleはエラーメッセジでタイトルと表示される用に設定
// 必須項目
$val->add('title', 'タイトル')
->add_rule('required');
<br > // summaryはサマリーと表示
// 必須、最低10文字、最長250文字をチェック
$val->add('summary', 'サマリー')
->add_rule('required')
->add_rule('min_length', 10)
->add_rule('max_length', 250);
// bodyは記事と表示
// 必須項目
$val->add('body', '記事')
->add_rule('required');
// バリデーションの実行
// エラーがなければ、TRUEが返る
if ($val->run())
{
// バリデーション成功、エラー無し
// $val->validated()はバリデーションに成功した項目名と値の配列
// Post::forge(array())で配列の内容をPostクラスのメンバ変数として取り込む
// Postはcrudモデルを拡張している。crud機能の実現のため複雑な処理をしているらしい
// このあとのsave()への前処理のようなもの、決め打ちのコードとして利用することに
$post = Post::forge($val->validated());
// post言語ファイルの読み込み
Lang::load('blog');
// 保存処理
if ($post->save())
{
Session::set_flash('notice', __('create_successfully', array('post_id' => $post->id)));
Response::redirect('posts');
}
else
{
Session::set_flash('notice', __('create_faild'));
}
}
else
{
// バリデーション失敗、入力にエラー有り
// $val->errors()はバリデーションに失敗した項目名とエラーの配列
Session::set_flash('notice', $val->errors());
}
}
$this->template->title = "Posts";
$this->template->content = View::forge('posts/create');
}
言語ファイルの配列を多重にした場合、その構造をピリオドで分けて、表現することで、アクセスできます。
例えば次のような言語ファイルがあったとしましょう。ファイル名はtest.phpとします。
return array(
'love' => '愛',
'life' => array(
'good' => '人生楽あり',
'bad' => '人生苦あり',
),
);
言語ファイルを読み込んだら、__('life.good')は'人生楽あり'へ、__('life.bad')は、'人生苦あり'へ変換されます。
| Fuelphpをwindowsでもgitしやすくする< 前 | 次 >Fuelphp、ブログチュートリアル |
|---|
| < 前 | 次 > |
|---|