2.0.0p247 :010 > I18n.l Time.now
=> "Tue, 03 Dec 2013 17:19:04 +0000"
2.0.0p247 :022 > I18n.t "hello"
=> "こんにちわ世界"
どのLocaleを利用するかはI18n.localeに格納されています。
2.0.0p247 :026 > I18n.locale
=> :jp
2.0.0p247 :027 > I18n.default_locale
=> :en
言語リソースはymlで用意する。config/locales/*.ymlというファイルを作るとRailsが自動的に読み込んでくれる。
en:
hello: "Hello world"
jp:
hello: "こんにちわ世界"
ちなみに階層化できるので、きれいにまとめましょう。
en:
greeting:
hi:
world: "Hi World"
ippei: "Hi Ippei"
.(ドット)でつなぎます。
2.0.0p247 :004 > I18n.t("greeting")
=> {:hi=>{:world=>"Hi World", :ippei=>"Hi Ippei"}}
2.0.0p247 :005 > I18n.t("greeting.hi.world")
=> "Hi World"
2.0.0p247 :006 > I18n.t("greeting.hi.ippei")
=> "Hi Ippei"
若干ハマったのが、なぜかjp.ymlという言語リソースファイルを追加したのに読んでくれていない。Railsがconfig/locales/から自動的にロードしてくれるのだが、残念ながらファイルを追加した時には動的に呼んでないらしい。ファイルに新しいKeyをアペンドした時は読んでくれるんだけど。たぶんこのパラメータが起動時に作られるのだと思われる。
2.0.0p247 :001 > I18n.load_path
=> ["/Users/ippei/RubymineProjects/eneberg/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.1/lib/active_support/locale/en.yml", "/Users/ippei/Rubymine.....
また、application.rbからdefault_localeの変更やload_pathの追加をすることもできる。少なくともrails4.0.1では以下のようなComment OutされたエントリーがあるのでComment Inして任意の言語またはディレクトリを追加するだけ。
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
問題はI18n.localeにどうやって任意の言語を入れてあげるか。つまりどうやって言語を判別するか。 大まかに以下の方法があると思います。組み合わせて使ったりもします。グリーはAccept-Languageだったはず。
- ドメインで識別
- jp.example.com
- example.jp
- Query Stringで渡す
- example.com?locale=jp
- Pathに追加する
- example.com/jp
- Accept-Languageを見る
- Accept-Language:en-US,en;q=0.8,ja;q=0.6
- GeoIP
- ユーザ毎に設定を持たせる
今回はお手軽にQuery StringとAccept-Languageで実装しました。
まずはQuery Stringから。ApplicationController.rbに下記を追加してQuery Stringで渡されたパラメーターをI18n.localeに設定するようにします。
before_action :set_locale
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
これだけだと画面遷移時にlocaleが引き継がれないので、以下のmethodをoverrideして常にlocaleパラメータを渡すようにします。
def default_url_options(options={})
{ locale: I18n.locale }
end
お次はAccept-Languageの実装です。残念ながらRails自体にはAccept-LanguageをParseする機能はないようなので、http_accept_languageというGemを使いました。
Gemfileに以下を追加します。
gem "http_accept_language", "~> 2.0.0"
そうするとこんな感じで準備したLocaleに対応する言語を返してくれます。
http_accept_language.compatible_language_from(I18n.available_locales)
Query Stringを優先させるので、終わってみるとApplication Controllerはこんな感じになりました。
before_action :set_locale
def default_url_options(options={})
{:locale => I18n.locale}
end
def set_locale
I18n.locale = extract_locale_from_params ||
extract_locale_from_accept_language_header ||
I18n.default_locale
end
private
def extract_locale_from_params
if params[:locale] and I18n.available_locales.index(params[:locale].to_sym)
params[:locale]
end
end
def extract_locale_from_accept_language_header
http_accept_language.compatible_language_from(I18n.available_locales)
end
後はja.ymlとen.ymlにひたすらリソースを追加して、Templateにせこせこと以下の文字を馬鹿みたいに埋め込み続けるだけの簡単なお仕事です。
<%= t('KEY') %>