Photo by Michael Kappel | Flickr - Photo Sharing!
Railsでの国際化(i18n: Internationalization)の方法をまとめています。
デフォルトのlocale設定、基本的な翻訳の流れ、翻訳ファイルの作成、localeを動的に変更する方法を説明します。
目次
2. i18nの翻訳の基本
3. 翻訳ファイルの作成
3.1. 翻訳ファイルのディレクトリ構成
3.2. 各言語の基本的な翻訳テンプレートファイル
3.3. 遅延参照(lazy lookup)
3.4. 式展開
3.5. 翻訳ファイル内でのHTMLの使用
3.6. ActiveRecordの翻訳
4. URLによるlocaleの設定方法
4.1. サブドメイン名からlocaleを設定
4.2. URLのサブディレクトリからlocaleを取得
4.3. URLパラメータからlocaleを取得
1. デフォルトのlocaleの設定と翻訳ファイルの読み込み
デフォルトのlocaleは暗黙的に:en
です。他のlocaleを設定したい場合は、明示的に指定する必要があります。また、翻訳ファイルは
config/locales/*.rb,yml
に配置し、自動的にロードされるようになっています。デフォルトのlocaleの設定や翻訳ファイルのディレクトリの追加をしたい場合、application.rb
を修正します。
# config/application.rb # デフォルトのlocaleを日本語(:ja)にする config.i18n.default_locale = :ja # 翻訳ファイルのディレクトを追加する場合は、次の行のコメントを外しパスを追加してください。 # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
設定できるlocaleは次のメソッドで確認できます。
I18n.available_locales #=> [:en, :"de-AT", :"de-CH", :de, :"en-au-ocker", :"en-AU", :"en-BORK", :"en-CA", :"en-GB", ...]
I18n.load_path
メソッドで現在ロードしている翻訳ファイルの一覧を表示することができます。
I18n.load_path #=> #[ # "/.../gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/locale/en.yml", # "/.../gems/activemodel-4.2.0/lib/active_model/locale/en.yml", # "/.../gems/activerecord-4.2.0/lib/active_record/locale/en.yml", # "/.../gems/actionview-4.2.0/lib/action_view/locale/en.yml", # "/.../gems/faker-1.4.3/lib/locales/de-AT.yml", # "/.../gems/faker-1.4.3/lib/locales/de-CH.yml", # "/.../gems/faker-1.4.3/lib/locales/de.yml", # "/.../gems/faker-1.4.3/lib/locales/en-au-ocker.yml", # "/.../gems/faker-1.4.3/lib/locales/en-AU.yml", # "/.../gems/faker-1.4.3/lib/locales/en-BORK.yml", # ... #]
2. i18nの翻訳の基本
i18nは、現在のlocaleに応じて、読み込んだ翻訳ファイルから適切な翻訳文を取得し、表示します。翻訳ファイルは次のようになっています。
# config/locales/ja.yml ja: hello: "こんにちは" time: formats: default: ! '%Y/%m/%d %H:%M:%S' # config/locales/es.yml es: hello: "hola mundo" time: formats: default: ! '%A, %d de %B de %Y %H:%M:%S %z'
変換には「翻訳(translate)を行うt
メソッド」と「DateやTimeをlocalizeするl
メソッド」を使います。
$ rails c # localeを日本語(:ja)に設定し、翻訳した文字を表示する I18n.locale = :ja I18n.t :hello # => "こんにちは" I18n.l Time.now # => "2015/02/24 14:53:03" # localeをスペイン語(:es)に設定し、翻訳した文字を表示する I18n.locale = :es I18n.t :hello # => "hola mundo" I18n.l Time.now # => "martes, 24 de febrero de 2015 14:57:17 +0900" # localeを指定して、設定されていない文字を表示できる I18n.locale # => :es I18n.t :hello, locale: :ja # => "こんにちは"
3. 翻訳ファイルの作成
3.1. 翻訳ファイルのディレクトリ構成
1つの翻訳に管理するのが難しくなってしまうので、プロジェクト規模に応じて、次のようにconfig/locales/
配下のディレクトリ構成を行うとよいです。
config/locales/ ├─ defaults │ ├─ ja.rb │ └─ en.rb ├── models │ └─ product │ ├─ ja.rb │ └─ en.rb └─ views ├─ defaults │ ├─ ja.rb │ └─ en.rb ├─ products │ ├─ ja.rb │ └─ en.rb └─ navigation ├─ ja.rb └─ en.rb
3.2. 各言語の基本的な翻訳テンプレートファイル
各言語の基本的な翻訳ファイルは「https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale」から取得できます。日付、時刻、ActiveRecordのバリデーションエラー文言、数字などの基本的な翻訳が記載されていまので、上記でいう、
config/locales/defaults/
配下に配置するようなファイルを取得できます。3.3. 遅延参照(lazy lookup)
Railsのビューファイルのディレクトリ構造と翻訳ファイルの階層構造を合わせることで、ビューに長ったらしくを書かなくてもよくなります。ja: projects: # app/views/projectsを表す index: # app/views/projects/index.html.erb title: "プロジェクト一覧" deadlines: # app/views/_deadlines.html.erb due_date: "期限"
<!-- app/views/projects/index.html.erb --> <!-- t 'projects.index.title' を t '.title' と短くかける --> <%= t '.title' %> # => "プロジェクト一覧" <!-- app/views/projects/_deadlines.html.erb --> <!-- t 'projects.deadlines.due_date' を t '.due_date' と短くかける --> <%= t '.due_date' %> # => "期限"
3.4. 式展開
翻訳文内で式展開を行うことができます。翻訳ファイル内で%{}
で変数名を定義します。
ja: hello: 'こんにちは %{name}'
そして、t
メソッドでKey-Valueで変数に値を設定します。
<%= t :hello, name: '太郎' %> # => "こんにちは 太郎"
3.5. 翻訳ファイル内でのHTMLの使用
翻訳ファイル内でHTMLを使用するには、キーに「_html
で終わる」か「html
というキー名」の場合、HTMLはエスケープされません。そのため、記載したHTMLが解釈されて表示されます。翻訳ファイル内で_html
で終わるキー名にします。
ja: hello_html: '<b>こんにちは %{name}</b>'
そして、t
メソッドで表示します。
<%= t :hello_html, name: '太郎' %> #=> 太字になった「こんにち 太郎」が表示される
次のようにhello_html
の値にHTMLセーフでない文字を入力するとそれが表示されてしまうので注意してください。
ja: hello_html: 'こんにちは %{name} <script>alert("alertが表示される");</script>'
逆に、式展開の%{}
のHTMLはエスケープされます。
<%= t :hello_html, name: '<script>alert("太郎");</script>' %> #=> "こんにちは <script>alert("太郎");</script>"と表示される
3.6. ActiveRecord/ActiveModelの翻訳
activerecord/activemodel.models
とactiverecord/activemodel.attributes
を使うことでActiveRecordの翻訳を行えます。次の翻訳ファイルは、Product
モデルの翻訳例です。
ja: activerecord: &activerecord models: product: "商品" search_form: "検索フォーム" attributes: product: name: "商品名" price: "値段" released_on: "発売日" search_form: q: "検索フィールド" # activemodelの翻訳もactiverecordに記載している activemodel: <<: activerecord
YAMLを開いて適切な設定になっているか確認できます。
YAML.load_file(Rails.root.join("config/locales/ja.yml"))
モジュールなどで階層構造の翻訳ファイルを書くときには、`/`で区切って階層構造を表します。
次のようなモジュールが入れ子の構造の場合、
module Forms class ProductForm attr_accessor :name end end
attributesの下位階層でモジュールを/で区切って表す(`forms/product_form`)
ja: activemodel: attributes: forms/product_form: name: '商品名'
次のようにして、ビューファイル内で利用します。
<!-- tメソッドでアクセスできます --> <%= t 'activerecord.models.product' %> #=> "商品" <%= t 'activerecord.attributes.product.name' %> #=> "商品名" <!-- 次のようにしてもアクセスできます --> <%= Product.model_name.human %> #=> "商品" <%= Product.human_attribute_name('name') %> #=> "商品名" <%= Forms::ProductForm.human_attribute_name('name') %> #=> "商品名"
4. URLによるlocaleの設定方法
他言語のサイト(複数のlocaleのサイト)を作成するには、「URLからlocaleを取得する方法」が推奨です。「URLからlocaleを取得する方法」は次のとおりです。

詳細は、多地域、多言語のサイト - Search Console ヘルプを参照してください。
他地域、他言語のサイトを作成するときに、SEO的にどうすれば良いかといったヒントが書かれています。
4.1. サブドメイン名からlocaleを設定
次のようにサブドメイン名からlocaleを設定するようにしてみます。Googleの他地域、他言語のサイトでは「gTLD を使用したサブドメイン」に対応します。
example.com # => デフォルトのlocale ja.example.com # => 日本のlocale en.example.com # => 英語のlocale
まず、applicaiton_controller.rb
にlocaleを設定するメソッドを追記します。
# app/controllers/application_controller.rb class ApplicationController < ActionController::Base ... before_action :set_locale def set_locale I18n.locale = extract_locale_from_tld || I18n.default_locale end # サブドメインからlocaleを取得する # 有効なlocaleが見つからない場合は、nilを返す def extract_locale_from_tld parsed_locale = request.subdomains.first I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil end end
そして、application.html.erb
などのビューファイルで次のように言語を変更するリンクを追加することで、言語を変更できます。
<%= link_to_if request.subdomains.first != 'ja', '日本語', "http://ja.example.com:3000#{request.path}"%> | <%= link_to_if request.subdomains.first != 'en', 'English', "http://en.example.com:3000#{request.path}" %>
URL部分は簡易的に直書きをしていますが、設定ファイルからの値を取得することをお勧めします。
http://ja.example.com:3000/...
にアクセスすると、Railsのlocaleは、ja(日本語)になるので、日本語で画面に表示されています。
http://en.example.com:3000/...
にアクセスすると、Railsのlocaleは、en(英語)になるので、英語で画面に表示されています。
4.2. URLのサブディレクトリからlocaleを取得
Googleの他地域、他言語のサイトでは「gTLD を使用したサブディレクトリ」に対応します。次のようにサブディレクトリ名からlocaleを設定するようにしてみます。
example.com/ # => デフォルトのlocale example.com/ja/ # => 日本のlocale example.com/en/ # => 英語のlocale
まず、ルートにscoope
で:locale
を追加します。かっこがあることで、存在しない場合は、デフォルトのlocaleが使われます。
# config/routes.rb scope "(:locale)" do resources :products end
URLのlocale
は、parmas[:locale]
で取得できるので次のようにします。
また、default_url_options
をオーバーライドすることで、すべてのリンクに現在のlocaleを設定することができます。
# app/controllers/application_controller.rb class ApplicationController < ActionController::Base ... before_action :set_locale def set_locale I18n.locale = params[:locale] || I18n.default_locale end def default_url_options(options = {}) { locale: I18n.locale }.merge options end end
そして、application.html.erb
などのビューファイルで次のように言語を変更するリンクを追加することで、言語を変更できます。
<%= link_to_if params[:locale].present?, '日本語', url_for(controller: controller.controller_name, action: controller.action_name, locale: '') %> | <%= link_to_if params[:locale] != 'en', 'English', url_for(controller: controller.controller_name, action: controller.action_name, locale: 'en') %>
URLにlocale
がない場合は、Railsのlocaleは、デフォルトのlocaleの日本語なので、日本語で表示されています。
「English」リンクを押すことで、URLにen
が追加され、Railsのlocaleが英語になるので、英語表示になります。
4.3. URLパラメータからlocaleを取得
次のようにURLパタメータにlocaleを設定することでlocaleを設定するようにします。example.com #=> デフォルトのlocale example.com?locale=ja #=> 日本語(ja)のlocale example.com?locale=es #=> スペイン語(es)のlocale
Googleの他地域、他言語のサイトによると、非推奨の方法です。
まず、applicaiton_controller.rb
にlocaleを設定するメソッドを追記します。
# app/controllers/application_controller.rb class ApplicationController < ActionController::Base ... before_action :set_locale def set_locale I18n.locale = params[:locale] || I18n.default_locale end # link_toなどのすべてのURLにlocaleパラメータを設定するようにする def default_url_options(options = {}) { locale: I18n.locale }.merge options end end
そして、application.html.erb
などのビューファイルで次のように言語を変更するリンクを追加することで、言語を変更できます。
<%= link_to_if params[:locale].present?, '日本語', "#{request.path}" %> | <%= link_to_if params[:locale] != 'en', 'English', "#{request.path}?locale=en" %>
URLにlocale
がない場合は、Railsのlocaleは、デフォルトのlocaleの日本語なので、日本語で表示されています。
「English」リンクを押すことで、locale=en
がURLに追加され、Railsのlocaleが英語になるので、英語表示になります。