言語ネゴシエーション のバックアップの現在との差分(No.1)

更新


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

~

>>>> [[Rails4 向けの内容はこちら>ソフトウェア/rails/国際化]]

~

----

[[公開メモ]]

#contents

* Rails で言語ネゴシエーション(Language Negotiation) [#h05f99dd]

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

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

やりたい内容としては
- views/*/*.html.ja.erb と views/*/*.html.en.erb とを両方作っておき、
自動的に切り替えて読み込む
- appache のネゴシエーション機能を使ってキャッシュされたページも
自動で切り替わるようにする
元々の情報が古いもので、結局かなりの部分を1から書いたので、
ここにメモしておく。

rails アプリの多言語化については他にも、
** やりたいこと [#w57d45b9]

-- ネゴシエーションっぽいもの
- [[ロケールによるテンプレート切り替え>http://www.yotabanana.com/lab/?date=20060224#p01]]
- ネゴシエーションではなく Ruby-GetText を使った方法やネゴシエーションとの比較
-- [[Railsで日本語を使う時に必須のパッケージ Ruby-GetText>http://blog.masuidrive.jp/articles/2006/07/03/gettext]]
-- [[Ruby on RailsでRuby-GetText-Packageを使う>http://www.yotabanana.com/hiki/ja/ruby-gettext-howto-ror.html]]
-- [[ruby-gettext>http://tech.feedforce.jp/ruby-gettext.html]]
-- [[Rails で行こう! - Ruby on Rails を学ぶ>http://d.hatena.ne.jp/elm200/20070719/1184856941]]
-- [[Rails のためのものぐさな Web アプリケーションの国際化手法>http://d.hatena.ne.jp/secondlife/20070207/1170835130]]
- rails エラーメッセージの日本語化
-- [[RubyOnRails を使ってみる 【第 5 回】 ActiveHeart>http://jp.rubyist.net/magazine/?0012-RubyOnRails]]
+ views/*/*.html.ja.erb とか views/*/*.html.en.erb とか、言語ごとに
テンプレートファイルを作っておき、閲覧者の環境設定、手動選択に合わせて
自動的に言語別テンプレートを切り替えて使う
+ キャッシュされたページも apache のネゴシエーション機能を使って
自動で言語を切り替えて送信できるようにする
+ エラーメッセージなど、テンプレートファイルの切換で対応しきれない部分は
I18n.t を使って多言語化できるようにする

などがあるみたい。
の3点。

以下手順。
rails アプリケーションには、通常通り

* negotiation という名前のアプリケーションの作成 [#vb4e8dd6]
http://rails.server/controller~
http://rails.server/controller/action~
http://rails.server/controller/action/id~
http://rails.server/controller/action/id.html~

 LANG:console
 $ rails negotiation
 $ cd negotiation
などの他、

* 開発用サーバーの起動と環境の確認 [#s35cbbb4]
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~

 LANG:console
 $ script/server &
 $ wget -qO- http://localhost:3000/ | html2text
  ...
  
  ****** Welcome aboard ******
  ***** You’re riding Ruby on Rails! *****
  **** About_your_application’s_environment ****
  ...
  
 $ wget -qO- http://localhost:3000/rails/info/properties | html2text
  Ruby version            1.8.7 (i486-linux)
  RubyGems version        1.3.2
  Rails version           2.2.2
  Active Record version   2.2.2
  Action Pack version     2.2.2
  Active Resource version 2.2.2
  Action Mailer version   2.2.2
  Active Support version  2.2.2
  Edge Rails revision     unknown
  Application root        /home/samba/www/rails/negotiation
  Environment             development
  Database adapter        sqlite3
  Database schema version 0
 
* test コントローラとビューの作成 [#k0a5e25a]
のように言語を指定した形でもアクセス可能とする。

 LANG:console
 $ script/generate controller Test
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/test
      exists  test/functional/
      create  app/controllers/test_controller.rb
      create  test/functional/test_controller_test.rb
      create  app/helpers/test_helper.rb
 $ jed app/controllers/test_controller.rb
  class TestController < ApplicationController
    def index
    end
  end
 $ echo "Test" > app/views/test/index.html.erb
 $ wget -qO- http://localhost:3000/test
  Test
言語指定の無いアドレスでアクセスされたときには
ブラウザとのネゴシエーションによって使うテンプレートを決める。

* 多言語化したビューの作成 [#b2db2fc3]
** 言語の優先順位 [#w3484f9d]

今作ったビューを削除して、日本語版と英語版を作成。
使用する言語の優先順位を決めるための情報源としては、

まだ rails に手を入れていないので、そのままではエラーになる。
+ ユーザーが手動で選んだ言語を使う prams[:rails_language]
+ ユーザーが以前に手動で選んだ言語を使う cookie[:rails_language]
+ ブラウザの言語設定にある優先順位を使う header['Accept-Language']
+ アプリケーションのデフォルトの優先順位を使う ENV['RAILS_ACCEPTABLE_LANGUAGES']

 LANG:console
 $ rm app/views/test/index.html.erb
 $ echo "Test" > app/views/test/index.html.en.erb
 $ echo "テスト" > app/views/test/index.html.ja.erb
 $ wget -O- http://localhost:3000/test
  500 Internal Server Error
** キャッシュに対する apache2 の言語ネゴシエーション [#w6b05fcf]

これを正しく表示できるようにするのが目標。
rails のページキャッシュ機能は、表示内容を .html ファイルとして保存する事で、
次回からは rails を通さず、apache で直接処理させるというもの。

* [#w47da434]
rails を通らないので、行うこととしては、~
適切な名前でキャッシュファイルを作成する事と、~
apache2 にキャッシュファイルを正しく認識させる事と、~
の2つになる。

** その他の多言語化方法 [#f2bd1cf6]

rails アプリの多言語化については、これまで Ruby-GetText, I18n, ActiveHeart など、
開発者ごとに異なる方法で行われてきた。

そんな中、rails 2.2 から、rails 本体の推奨する多言語化手法が I18n に決まったようなので、
今後は I18n を用いるアプリケーションが増えると考えられる。

多言語化の方法には大きく分けて次の2つがある。
+ 言語ごとに別のテンプレートファイルを用いる方法
+ テンプレートファイルは共通にして、中で現れる文言を1つずつその都度翻訳する

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

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

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

というような欠点もあると言われている。[[参照>http://www.yotabanana.com/lab/?date=20060224#p01]]

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

* 試行錯誤の経過 [#e232eb64]

+ [[開発&テスト用環境の構築>ソフトウェア/rails/言語ネゴシエーション/開発用&テスト用環境の構築]]
-- negotiation という名前のアプリケーションの作成
-- 開発用サーバーの起動と環境の確認
-- test コントローラとビューの作成
+ [[routesの設定と言語選択の優先順位>ソフトウェア/rails/言語ネゴシエーション/routesの設定と言語選択の優先順位]]
-- 多言語化したビューの作成
-- config/routes.rb の設定
-- 言語が指定されていない時を含めた言語選択の優先順位]]
+ [[言語別テンプレートの選択>ソフトウェア/rails/言語ネゴシエーション/言語別テンプレートの選択]]
-- 言語の優先順位を元に利用するテンプレートを選択する]]
--- memoize について
-- テンプレートファイルの拡張子を正しく認識させる
+ [[キャッシュの多言語対応>ソフトウェア/rails/言語ネゴシエーション/キャッシュの多言語対応]]
-- ページキャッシュの多言語対応
-- ページキャッシュの多言語化に対応させるための apache の設定
-- アクションキャッシュの多言語対応
-- フラグメントキャッシュの多言語対応
+ [[プラグイン化と公開準備>ソフトウェア/rails/言語ネゴシエーション/プラグイン化と公開準備]]
-- プラグイン化
-- テストケース
-- fcgi 化
+ [[github を使った公開>ソフトウェア/rails/言語ネゴシエーション/github を使った公開]]
-- git リポジトリ(ローカル)の作成
-- プロジェクトを github に登録
-- git を使った編集作業例

* プラグインのダウンロード [#l2dd967e]

github からどうぞ。

http://github.com/osamutake/RailsLanguageNegotiationPlugin/tree/master

* プラグインの使い方 [#sb57c7b2]



* TODO [#ye7b917c]

** ページキャッシュ上での言語切換(Cookie 書き換え) [#o28ad6fc]

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 のネゴシエーション [#c283a97a]

こちらもしないと片手落ちか。

参照 > http://d.hatena.ne.jp/kusakari/20090226/1235616295

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

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

* コメント [#kfcbe2ab]

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

#article_kcaptcha


Counter: 9578 (from 2010/06/03), today: 1, yesterday: 4