Okinawa.rb Advent Calendar 2016 15日目。
最近はまったくと言っていいほど meet up に参加できていません。来年からはちょいちょい参加するつもりです。
Rails の config/locales 配下の扱い方を備忘録がてらまとめてみました。
rails new 直後 (en.yml)
rails new hoge
すると以下のファイルがあるだけです。
en:
hello: "Hello world"
gemの導入 (translation_ja.yml)
次に i18n_generators の導入が王道だと思います。
gem 'i18n_generators'
して、 rails g i18n ja
を実行すると
config/locales/ja.yml
と
config/locales/translation_ja.yml
が生成されます。後者はモデルに対応したファイルで、モデルに変更があった場合、こちらもメンテすることになると思います。
ちなみに私はこのファイルはドキュメントを作る上で用語集として参考として利用してたりします。
普通に開発していくと config/locales/translation_ja.yml を常にメンテする状態が続くと思います。
ja.yml の方はほとんどいじったことがありません。
ギュッと詰め
以下は色々な書き方を詰め込んでみました。
I18n.locale = :ja
していることを前提に各々を解説します。
尚、色々な要素を詰め込んでいるのでわざとファイル名は hoge としています。
1 ja:
2 date:
3 abbr_day_names:
4 - 日
5 - 月
6 - 火
7 - 水
8 - 木
9 - 金
10 - 土
11 hello: 'こんにちは'
12 world_html: '<b>世界</b>' # HTML 書きたいなら key名に _html の suffix を付与すれば良い
13 title: The book(%{published}) # 変数渡したいならこう書く
14 activerecord:
15 models:
16 user: '会員'
17 blog: 'ブログ'
18 attributes:
19 user:
20 id: '会員番号'
21 blog:
22 user: :activerecord.models.user
23 user_id: :activerecord.attributes.user.id
3行目~10行目: 配列
普通の配列です。これは rails ではなく yaml の話ですね。
一応、基本ということで。
irb> I18n.t('date.abbr_day_names')
=> ["日", "月", "火", "水", "木", "金", "土"]
irb> I18n.t('date.abbr_day_names').class
=> Array
11行目は基本なので割愛。
12行目: HTML
HTML 書きたいなら key名に _html の suffix を付与すれば良いです。
以下の例では単なる文字列ですが、view で使うとよしなにエスケープしてくれます。
view helper 側の機能だそうです。
irb> I18n.t(:world_html)
=> "<b>世界</b>"
13行目: 式展開
13 title: The book(%{published}) # 変数渡したいならこう書く
tメソッドに引数で渡せばOKです。
irb> I18n.t(:title, published: 'hoge') # hash 渡すよ
=> "The book(hoge)"
irb> I18n.t(:title)
=> "The book(%{published})" # 引数渡さないとこうなっちゃう
14行目~20行目: ActiveRecord
14 activerecord:
15 models:
16 user: '会員'
17 blog: 'ブログ'
18 attributes:
19 user:
20 id: '会員番号'
普通に i18n_generators で transration_ja.yml が生成されるのと同じです。
ActiveRecord の User モデルや Blog モデルが存在すれば以下のように参照することも可能です。
irb> User.model_name.human
=> "会員"
irb> User.human_attribute_name(:id)
=> "会員番号"
もちろんモデルが無くても
irb> I18n.t('activerecord.models.user')
=> "会員"
irb> I18n.t('activerecord.attributes.user.id')
=> "会員番号"
で参照できます。
22行目~23行目
21 blog:
22 user: :activerecord.models.user
23 user_id: :activerecord.attributes.user.id
yml ファイル内で参照したい場合は以下のように記述して DRY にできます。
irb> I18n.t('activerecord.attributes.blog.user')
=> "会員"
irb> I18n.t('activerecord.attributes.blog.user_id')
=> "会員番号"
view との連携
モデルではなくビューを翻訳してみましょう。
t メソッドに長ったらしい key を書くのは面倒なので省略できます。
<h1><%= t('.title') %></h1> <%# 冗長な書き方だと右記になる。 t('projects.index.title') %>
上記のように view のファイル内にて .title
と記述します。
翻訳ファイルは以下のようにします。ファイルの階層と yaml の階層が一致している事に着目してください。
ja:
projects: # app/views/projectsを表す
index: # app/views/projects/index.html.erb
title: "プロジェクト一覧"
ちなみに rails console では以下のようになります。
irb> I18n.t '.title' # エラー
=> "translation missing: ja.title"
irb> I18n.t 'projects.index.title' # 絶対パス指定
=> "プロジェクト一覧"
irb> I18n.t '.title', scope: 'projects.index' # カラクリは scope オプションだったのだ
=> "プロジェクト一覧"
ルールとしては**「階層はファイル名と対応」**と覚えるようにしています。
partial ファイルの場合
**「階層はファイル名と対応」**と覚えていれば大丈夫。
<h1><%= t('.title') %></h1> <%# 冗長な書き方だと右記になる。 t('projects.index.title') %>
<%= render partial: "hoge" %>
<h2><%= t('.fuga') %></h2>
上記のビューに対し...
ja:
projects: # app/views/projectsを表す
index: # app/views/projects/index.html.erb
title: "プロジェクト一覧"
hoge:
fuga: 'ふがーーーー'
partialファイル名の先頭のアンダーバーは無視して構いません。
参考
最後に
rails4.2 や rails5 で動作確認しました。
このページを見て理解が深まったり、気づきがあったり、チートシート的に見てもらえれば幸いです。