言語ネゴシエーション

(1548d) 更新

このページの内容は非常に古いです(Rails 1.x.x)。最新の Rails では洗練された国際化の機構が標準で入っているため、下記は読むだけ無駄な内容になっています。


>>>> Rails4 向けの内容はこちら



公開メモ

Rails で言語ネゴシエーション(Language Negotiation)

http://blog.omdb-beta.org/

を見ながら、ブラウザの Language Negotiation の機能を使って rails アプリケーションの多言語化する方法を調べてみた。

元々の情報が古いもので、結局かなりの部分を1から書いたので、 ここにメモしておく。

やりたいこと

  1. views/*/*.html.ja.erb とか views/*/*.html.en.erb とか、言語ごとに テンプレートファイルを作っておき、閲覧者の環境設定、手動選択に合わせて 自動的に言語別テンプレートを切り替えて使う
  2. キャッシュされたページも apache のネゴシエーション機能を使って 自動で言語を切り替えて送信できるようにする
  3. エラーメッセージなど、テンプレートファイルの切換で対応しきれない部分は 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

のように言語を指定した形でもアクセス可能とする。

言語指定の無いアドレスでアクセスされたときには ブラウザとのネゴシエーションによって使うテンプレートを決める。

言語の優先順位

使用する言語の優先順位を決めるための情報源としては、

  1. ユーザーが手動で選んだ言語を使う prams[:rails_language]
  2. ユーザーが以前に手動で選んだ言語を使う cookie[:rails_language]
  3. ブラウザの言語設定にある優先順位を使う header['Accept-Language']
  4. アプリケーションのデフォルトの優先順位を使う 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. 言語ごとに別のテンプレートファイルを用いる方法
  2. テンプレートファイルは共通にして、中で現れる文言を1つずつその都度翻訳する

Ruby-GetText はこの両方の機能を持っているが、
I18n は 2. のみを行うもの。

1. は 2. に比べて「国際化対応というのは異なる文化慣習への対応でもあるから、 単なる文言の修正では済まないこともある。テンプレートごと差し替えてしまえば そういうケースでも対応が楽。」という利点があると言われる。

逆に 1. は 2. に比べて、アプリケーションの手直しでテンプレートに変更が 必要になったとき、アプリケーション開発者が翻訳済みのテンプレートに手を 入れられずに、テンプレートがメンテナンス不可能になる事態が生じる。

というような欠点もあると言われている。参照

開発者が翻訳者を兼ねている、
ページキャッシュを行う、
あたりを考慮すると 2. も良い物だと思うので、実装したのがこの記事。

試行錯誤の経過

  1. 開発&テスト用環境の構築
    • negotiation という名前のアプリケーションの作成
    • 開発用サーバーの起動と環境の確認
    • test コントローラとビューの作成
  2. routesの設定と言語選択の優先順位
    • 多言語化したビューの作成
    • config/routes.rb の設定
    • 言語が指定されていない時を含めた言語選択の優先順位]]
  3. 言語別テンプレートの選択
    • 言語の優先順位を元に利用するテンプレートを選択する]]
      • memoize について
    • テンプレートファイルの拡張子を正しく認識させる
  4. キャッシュの多言語対応
    • ページキャッシュの多言語対応
    • ページキャッシュの多言語化に対応させるための apache の設定
    • アクションキャッシュの多言語対応
    • フラグメントキャッシュの多言語対応
  5. プラグイン化と公開準備
    • プラグイン化
    • テストケース
    • fcgi 化
  6. 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

と思ったら、何もしなくても上記で対応しているみたい。

テストケースを追加すべき。

コメント

気づいた点など、ぜひ突っ込みを入れて下さい。





Counter: 5077 (from 2010/06/03), today: 5, yesterday: 0