gettext/rails のロケール決定方法を変える
require 'gettext/rails' を使う場合、gettext のロケール情報は「ブラウザからのアクセスとCookieへの情報格納」にあるように params[:lang], cookies[:lang], HTTP_ACCEPT_LANGAUGE, "en" の順番に参照され決定されます。
これを params[:lang], cookies[:lang] を使用せず session["language"], HTTP_ACCEPT_LANGUAGE のみによりロケールを決定するように実装したくなり、いろいろ悩んだあげく次のようなコードで解決させました。
class ApplicationController < ActionController::Base init_gettext "test" private def init_gettext_main(cgi) set_cgi(gettext_dummy_cgi) set_locale_all(nil) end def gettext_dummy_cgi gettext_dummy_cgi_class.new(session["language"], request.env["HTTP_ACCEPT_LANGUAGE"], request.env["HTTP_ACCEPT_CHARSET"]) end @@gettext_dummy_cgi_class = nil def gettext_dummy_cgi_class unless @@gettext_dummy_cgi_class klass = Class.new klass.class_eval do attr_reader :params, :cookies, :accept_language, :accept_charset define_method :initialize do |lang,accept_language,accept_charset| @params = { "lang" => lang } @cookies = Hash.new { |k,v| [] } @accept_language = accept_language @accept_charset = accept_charset end define_method :[] do |index| @params[index] end end @@gettext_dummy_cgi_class = klass end @@gettext_dummy_cgi_class end end
いまのところ gettext-1.8.0 でしか動作しません。
gettext/rails は request.cgi を用いてロケールを決定しようとするので、その cgi の代わりになるオブジェクトをでっちあげてそれを渡すことで実現しています。(かなり強引ですが)