酒と泪とRubyとRailsと

Ruby on Rails と Objective-C は酒の肴です!

Railsの多言語化対応 I18nのやり方を整理してみた!【国際化/英語化】

RailsのWebアプリを英語化(多言語化)をサポートしてくれるGem、i18nの紹介です。今回はi18n対応のノウハウをまとめてみました。

(1) i18nのベーシックな使い方
(2) GitHubから辞書ファイルをダウンロード
(3) 辞書ファイルを分割して管理をしやすくする
(4) locale別のHTMLテンプレート
(5) localeの動的判定
(6) DBに格納されている文字列の多言語化
(7) モデル名やモデルの属性名の多言語化
(8) Javascriptのi18n対応

Included file ‘custom/google_ads_yoko_naga.html’ not found in _includes directory

おすすめ記事

I18n.tでHTMLを出力するのにrawを使ってはいけない
Rails で構築された多言語対応のサイトで翻訳メッセージに HTML を含みたい場合の対処法。

目次

(1) i18nのベーシックな使い方
(2) GitHubから辞書ファイルをダウンロード
(3) 辞書ファイルを分割して管理をしやすくする
(4) locale別のHTMLテンプレート
(5) localeの動的判定
(6) DBに格納されている文字列の多言語化
(7) モデル名やモデルの属性名の多言語化
(8) Javascriptのi18n対応

(1) i18nのベーシックな使い方

Railsでは特に設定しなければconfig/application.rbの34行目付近に設定したlocaleの言語を表示するようになっています。 (初期状態ではコメントアウトされているかも)
これを日本語に設定する場合は次のようにします。

1
config.i18n.default_locale = :ja

次にi18nの多言語化ファイルを設定します。config/locales/ja.ymlを作成して以下の様に入力して下さい。

1
2
3
ja:
    view:
        hello: "あろは〜、世界"

次にviewに以下の様に入力します。

1
<%= t('view.hello') %>

ブラウザでviewを見るとあろは〜、世界となっていると思います。 これが、i18nのベーシックな使い方です。

ちなみに次のように書くこともできます。

en.yml
1
2
3
book
  author: John Due
  title: The book(%{published})
1
2
3
I18n.t "book.author"
I18n.t("book.title", {published: 2012/10/10})
I18n.l Time.now

ちなみにI18n.tと、I18n.lの使い方は次の通りです。

  • I18n.t(I18n.translate)メソッドは、設定されているlocaleの辞書ファイルlocale/xx.ymlからキーを探しだして値を表示してくます

  • I18l.l(I18n.localize)メソッドは、日付や時刻の変換をしてくれます

(2) GitHubから辞書ファイルをダウンロード

辞書ファイルを一から全て書き出すと大量になってしまうので、svenfuchs/rails-i18n · GitHubからテンプレートをダウンロードすることをおすすめします。コンソールでプロジェクトの直下に移動して、以下のコマンドを実行して下さい。

1
2
3
4
5
# 英語のテンプレートをDL
wget https://raw.github.com/svenfuchs/rails-i18n/master/rails/locale/en.yml -P config/locales/

# 日本語のテンプレートをDL
wget https://raw.github.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml -P config/locales/

これで、config/locales/en.ymlconfig/locales/ja.ymlには一般的な設定が記述された状態からスタートできます。

(3) 辞書ファイルを分割して管理をしやすくする

辞書ファイルはプロジェクトの規模が大きくなると1つのymlファイルで管理するのが困難になります。そこで、辞書ファイルをmodel/view単位といった具合で分割してみます。

まず、複数ファイルを読み込めるようにするために、config/application.rbに以下のコードを追加します。

1
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]

これで今後は、以下のようなフォルダ/ファイル構成で辞書ファイルを管理することができるようになります。

├── defaults
│   ├── en.yml
│   └── ja.yml
├── models
│   ├── default
│   │   ├── en.yml
│   │   └── ja.yml
│   └── user
│       ├── en.yml
│       └── ja.yml
└── views
    └── user
        ├── en.yml
        └── ja.yml

(4) locale別のHTMLテンプレート

locale毎にHTMLの構造が大きく異なる場合には、locale毎のテンプレートを作ることができます。

app/views/users/
  ├── index.en.html.erb
  ├── index.ja.html.erb
  └── index.de.html.erb

(5) localeの動的判定

config/application.rbに書かれたlocaleだけで言語を判定すると1つの言語にしか対応できません。ここからはlocaleを動的に判定して表示する言語を変更する方法について書いていきます。

まず、Google Webマスターツールの多言語化のセッションに多言語化のノウハウが書かれています。日本語でとてもわかりやすい文章ですし、SEOを考える上でも必読の資料だと思います。

前述のドキュメントも含めて総合的に考えると、URLでlocaleを判定できるようにしておいたほうが良いと思います。理由は、Googleのクローラー対応が簡単なことと、他人にURLを伝えるときにlocaleを明示できるからです。

サブドメインでlocaleを判定する

日本語のサイトはhttp://ja.xxxx.com、英語のサイトはhttp://en.xxxx.comというようにサブドメインを分けて多言語するパターンのRails側の対応方法です。これは言語毎にサーバを分けて管理したい時などに有効です。

app/controllers/application_controller.rbに以下を追加すれば、サブドメインからlocaleを判定してくれるようになります。

1
2
3
4
5
6
7
8
9
before_filter :set_locale
def set_locale
  I18n.locale = extract_locale_from_subdomain
end

def extract_locale_from_subdomain
  parsed_locale = request.subdomains.first
  I18n.available_locales.include?(parsed_locale.to_sym) ? parsed_locale : I18n.default_locale
end

URLのパラメータ(一部)でlocaleを判定する

日本語のサイトは、http://xxxx.com/ja/、英語のサイトはhttp://xxxx.com/en/というようにURLの一部にlocaleをセットするパターンの対応方法です。このパターンは、一つのサーバ(バーチャルホスト)内で複数言語に対応する場合に有効です。

app/controllers/application_controller.rbに以下を追加すれば、パラメータからlocaleを判定することが出来るようになります。

1
2
3
4
5
6
7
8
9
10
11
before_filter :set_locale

# 全リンクにlocale情報をセットする
def default_url_options(options={})
  { :locale => I18n.locale }
end

# リンクの多言語化に対応する
def set_locale
  I18n.locale = params[:locale] || I18n.default_locale
end

(6) DBに格納されている文字列の多言語化

テーブル内のあるカラムを英語化する方法は2つ考えられます。

(A) locale毎にカラムを分ける

+------+-------------+---------------+
|  id  | message_en  |  message_ja   |
+------+-------------+---------------+
|   1  | Hello World | こんにちは、世界 |
+------+-------------+---------------+

(B) 1つのカラムをシリアライズする

1
2
3
4
5
6
7
# app/models/greeting.rb
class Greeting < ActiveRecord::Base
  serialize :message, Hash
end

# データを登録
@greeting.message = {:en => "Hello World", :ja => "こんにちは、世界"}

(7) モデル名やモデルの属性名の多言語化

モデル名やモデル除く姓名は、config/locale/ja(en).ymlを以下の様に書きます。

1
2
3
4
5
6
7
8
9
10
11
12
# モデル名
ja:
  activerecord:
    models:
      product: 製品

# モデルの属性名
ja:
  activerecord:
    attributes:
      product:
        name: 名前

viewなどで表示する場合には次のように記述します。

1
2
3
4
5
# モデル名
t('activerecord.models.product')

# モデルの属性名
t('activerecord.attributes.product.name')

(8) Javascriptのi18n対応

Gemfileに以下を追加して、bundle installを実行。

1
2
# javascriptのi18n対応
gem "i18n-js"

app/assets/javascripts/application.jsに以下を追記。

1
2
//= require i18n
//= require i18n/translations

コンソールから以下を実行して、設定ファイルconfig/i18n-js.ymlを生成。

1
rake i18n:js:setup

app/views/layouts/application.html.erbにjavascript側へlocalesを通知するための設定を追記。

1
2
3
4
<script type="text/javascript">
  I18n.defaultLocale = "<%= I18n.default_locale %>";
  I18n.locale = "<%= I18n.locale %>";
</script>

これで設定は完了です。次にjavascript側でのi18nの使い方です。
まず、config/i18n-js.ymlにコードを書きます。

1
2
ja:
  hello: "こんちゃー"

次にjavascript側でi18nを表示したい場所で次のように書きます。

1
I18n.t("hello");

これでjavasript側にこんちゃーが表示されます。

実際にはかなりいろんなことができそうなので、よかったらi18n-jsGitHubも覗いてみて下さい。

fnando/i18n-js · GitHub

Included file ‘custom/google_ads_yoko_naga.html’ not found in _includes directory

Special Thanks

RailsのI18n APIの使い方の基本と辞書ファイルの整理方針: Modelごと、Viewごとに分けて管理する - memo.yomukaku.net

Rails 3 の I18n について - おもしろWEBサービス開発日記

Railsでi18n-jsを使ってJavaScriptの国際化 - Startup Reality

Rails3 事始め: [Rails3] 国際化 I18n のまとめ(その3:辞書ファイルの使い方)

気にすんな - 国際化対応

変更来歴

(13/01/26 10:30) 新規作成
(13/06/13 17:30) ダウンロード/日本語テンプレートのURLが間違っていたので修正
(14/04/25 23:35) モデル名やモデルの属性名の多言語化の項目を追加

おすすめの書籍