言語ネゴシエーション
このページの内容は非常に古いです(Rails 1.x.x)。最新の Rails では洗練された国際化の機構が標準で入っているため、下記は読むだけ無駄な内容になっています。
>>>> Rails4 向けの内容はこちら
Rails で言語ネゴシエーション(Language Negotiation)†
を見ながら、ブラウザの Language Negotiation の機能を使って rails アプリケーションの多言語化する方法を調べてみた。
元々の情報が古いもので、結局かなりの部分を1から書いたので、 ここにメモしておく。
やりたいこと†
- views/*/*.html.ja.erb とか views/*/*.html.en.erb とか、言語ごとに テンプレートファイルを作っておき、閲覧者の環境設定、手動選択に合わせて 自動的に言語別テンプレートを切り替えて使う
- キャッシュされたページも apache のネゴシエーション機能を使って 自動で言語を切り替えて送信できるようにする
- エラーメッセージなど、テンプレートファイルの切換で対応しきれない部分は I18n.t を使って多言語化できるようにする
の3点。
rails アプリケーションには、通常通り
http://rails.server/controller
http://rails.server/controller/action
http://rails.server/controller/action/id
http://rails.server/controller/action/id.html
などの他、
http://rails.server/controller.ja
http://rails.server/controller/action.ja
http://rails.server/controller/action/id.ja
http://rails.server/controller/action/id.html.ja
のように言語を指定した形でもアクセス可能とする。
言語指定の無いアドレスでアクセスされたときには ブラウザとのネゴシエーションによって使うテンプレートを決める。
言語の優先順位†
使用する言語の優先順位を決めるための情報源としては、
- ユーザーが手動で選んだ言語を使う prams[:rails_language]
- ユーザーが以前に手動で選んだ言語を使う cookie[:rails_language]
- ブラウザの言語設定にある優先順位を使う header['Accept-Language']
- アプリケーションのデフォルトの優先順位を使う ENV['RAILS_ACCEPTABLE_LANGUAGES']
キャッシュに対する apache2 の言語ネゴシエーション†
rails のページキャッシュ機能は、表示内容を .html ファイルとして保存する事で、 次回からは rails を通さず、apache で直接処理させるというもの。
rails を通らないので、行うこととしては、
適切な名前でキャッシュファイルを作成する事と、
apache2 にキャッシュファイルを正しく認識させる事と、
の2つになる。
その他の多言語化方法†
rails アプリの多言語化については、これまで Ruby-GetText, I18n, ActiveHeart など、 開発者ごとに異なる方法で行われてきた。
そんな中、rails 2.2 から、rails 本体の推奨する多言語化手法が I18n に決まったようなので、 今後は I18n を用いるアプリケーションが増えると考えられる。
多言語化の方法には大きく分けて次の2つがある。
- 言語ごとに別のテンプレートファイルを用いる方法
- テンプレートファイルは共通にして、中で現れる文言を1つずつその都度翻訳する
Ruby-GetText はこの両方の機能を持っているが、
I18n は 2. のみを行うもの。
1. は 2. に比べて「国際化対応というのは異なる文化慣習への対応でもあるから、 単なる文言の修正では済まないこともある。テンプレートごと差し替えてしまえば そういうケースでも対応が楽。」という利点があると言われる。
逆に 1. は 2. に比べて、アプリケーションの手直しでテンプレートに変更が 必要になったとき、アプリケーション開発者が翻訳済みのテンプレートに手を 入れられずに、テンプレートがメンテナンス不可能になる事態が生じる。
というような欠点もあると言われている。参照
開発者が翻訳者を兼ねている、
ページキャッシュを行う、
あたりを考慮すると 2. も良い物だと思うので、実装したのがこの記事。
試行錯誤の経過†
- 開発&テスト用環境の構築
- negotiation という名前のアプリケーションの作成
- 開発用サーバーの起動と環境の確認
- test コントローラとビューの作成
- routesの設定と言語選択の優先順位
- 多言語化したビューの作成
- config/routes.rb の設定
- 言語が指定されていない時を含めた言語選択の優先順位]]
- 言語別テンプレートの選択
- 言語の優先順位を元に利用するテンプレートを選択する]]
- memoize について
- テンプレートファイルの拡張子を正しく認識させる
- 言語の優先順位を元に利用するテンプレートを選択する]]
- キャッシュの多言語対応
- ページキャッシュの多言語対応
- ページキャッシュの多言語化に対応させるための apache の設定
- アクションキャッシュの多言語対応
- フラグメントキャッシュの多言語対応
- プラグイン化と公開準備
- プラグイン化
- テストケース
- fcgi 化
- github を使った公開
- git リポジトリ(ローカル)の作成
- プロジェクトを github に登録
- git を使った編集作業例
プラグインのダウンロード†
github からどうぞ。
http://github.com/osamutake/RailsLanguageNegotiationPlugin/tree/master
プラグインの使い方†
TODO†
ページキャッシュ上での言語切換(Cookie 書き換え)†
http://rails.server/controller.ja
などの、言語指定の付いたアドレスで参照してページキャッシュが返される場合、
Cookie の書き換えが起きないので、表示言語の切換ができない。
ページに JavaScript を埋め込んで、location.href に言語指定が含まれている時に Cookie を書き換える事で対応できるはず。
<%= link_to "link text", { :rails_language=>:ja }, { :on_click="document.cookie='rails_language=ja'" } %>
のような感じ。
もちろん、ブラウザ側で javascript や cookie を off にされていれば 動作しないが、それは仕方のないところ。
noscript> タグで javascript を on にするよう書いておくべき。
ActionMailer のネゴシエーション†
こちらもしないと片手落ちか。
参照 > http://d.hatena.ne.jp/kusakari/20090226/1235616295
と思ったら、何もしなくても上記で対応しているみたい。
テストケースを追加すべき。
コメント†
気づいた点など、ぜひ突っ込みを入れて下さい。