目的
- 日本語化対応した時のメモ
- 今後、railsを学ぶ方に向けての参考に役立てる。
条件
- ruby 2.5.1
- Rails 5.0.7
リスト
- デフォルトの言語を日本語に設定する
- gem 'rails-i18n'をインストール
- 複数のロケールファイルが読み込まれるようpathを通す
-
config/locales
以下にロケールファイルを配置 - ja.ymlに日本語を設定する
- 設定した日本を表示させる
- 様々な記述方法
1. デフォルトの言語を日本語に設定する
config/application.rb
require_relative 'boot'
require 'rails/all'
Bundler.require(*Rails.groups)
module BoardApp
class Application < Rails::Application
config.time_zone = 'Tokyo'
config.active_record.default_timezone = :local
# 以下の記述を追記する(設定必須)
# デフォルトのlocaleを日本語(:ja)にする
config.i18n.default_locale = :ja
end
end
2. gem 'rails-i18n'をインストール
Gemfile
# rails5系なら以下を記述
# For 5.0.x, 5.1.x and 5.2.x
gem 'rails-i18n', '~> 5.1'
# rails4系なら以下を記述
# For 4.0.x
gem 'rails-i18n', '~> 4.0'
上記のgemを導入することによって、
Railsを日本語で使う場合のデフォルトのロケールファイルを「svenfuchs/rails-i18n」をダウンロードしなくても使えるようになります。
gemを使わない場合は下記コマンドを実行
config/locales/ja.ymlにダウンロード
curl -s https://raw.githubusercontent.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml -o config/locales/ja.yml
1 の作業config.i18n.default_locale = :ja
を設定しないと反映されないので設定必須!
3. i18nの複数ロケールファイルが読み込まれるようpathを通す
config/application.rb
require_relative 'boot'
require 'rails/all'
Bundler.require(*Rails.groups)
module BoardApp
class Application < Rails::Application
config.time_zone = 'Tokyo'
config.active_record.default_timezone = :local
config.i18n.default_locale = :ja # デフォルトのlocaleを日本語(:ja)にする
# # 以下の記述を追記する(設定必須)
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
end
end
上記を記述することによって、複数のローケルファイルが読み込まれるようになった
4. config/locales
以下にロケールファイルを配置
次に、views / modelによってロケールファイルを分けます。(今回controllerは省略)
ファイル構造(例)
config
└── locales
├── model.ja.yml # modelは1つのファイルで管理します。
└── views # views関連のファイルはここで管理する
├── admin
│ ├── dashboards
│ │ └── ja.yml
│ ├── ja.yml
│ ├── user_sessions
│ │ └── ja.yml
│ └── users
│ └── ja.yml
├── boards
│ └── ja.yml
├── dashboards
│ └── ja.yml
├── password_resets
│ └── ja.yml
├── shared
│ └── ja.yml
├── user_sessions
│ └── ja.yml
└── users
└── ja.yml
5. ja.ymlに日本語を設定する
viewsの日本語化を設定する
# app/views/users/index.html.erb
<%= t ".title" %>
# app/views/users/show.html.erb
<%= t ".title", user_name: current_user.full_name %>
# app/views/users/edit.html.erb
<%= t ".title", user_name: current_user.full_name %>
config/locales/views/users/ja.yml
# ビューはビューを格納しているフォルダ名を起点にし、ビュー名毎に記述する。
# インデント(2space)でpathを制御している
ja:
users:
index:
title: 'ユーザ一覧'
show:
# 引数の指定もできる。
title: '%{user_name}さんのユーザ情報'
edit:
# view側で t(.titile), user_name: @user.name みたいな感じで設定できる
title: '%{user_name}さんのユーザ情報を編集'
modelの日本語化を設定する
config/locales/model.ja.yml
# モデルは全て activerecord 以下に記述する。
# これにより、User.model_name.human / User.human_attribute_name({attr_name})で使用可能。
ja:
activerecord:
models:
# view側: User.model_name.human => "ユーザ" / t("activerecord.models.user")と同じ
user: ユーザー
board: 掲示板
# model毎に定義したいattributesを記述
attributes:
user:
id: ID
# view側: User.human_attribute_name :name => "名前" / t("activerecord.attributes.user.name")と同じ
first_name: 名前
last_name: 姓
email: メールアドレス
file: プロフィール画像
crypted_password: パスワード
# 全てのmodelで共通して使用するattributesを定義
attributes:
created_at: 作成日
updated_at: 更新日
Controllers の日本語化を設定する
app/controllers/messages_controller.rb
# app/controllers/messages_controller.rb
MessagesController < BaseController
def update
# Some business logic
return redirect_to:index, notice: t(".notice") if @resource.save
render :edit, alert: t(".alert")
end
end
config/locales/model.ja.yml
ja:
messages:
update:
notice: "メッセージの更新に成功しました。"
alert: "メッセージの更新ができません。"
6. 設定した日本を表示させる
app/views/users/index.html.erb
#### viewで使う場合
# 対応するビューの中ではツリーを省略できる。
# 「ユーザ一覧」が表示される(users.index.titleを参照。)
# 「users.index.html.erb」に記述されているので
# ja.ymlの
# users:
index:
部分を自動的に読み込んでいるから省略できる
<%= t '.title' %>
# 省略しない記述は以下のようになる。
# 「ユーザ一覧」が表示される
<%= t 'users.index.title' %>
# 日付・時刻(DateオブジェクトやTimeオブジェクト)変換するする場合
<%= l Time.now %>
# 翻訳対象がnilになる(変数とか)場合、defaultを設定しておく
<%= l nil %>
=> I18n::ArgumentError: Object must be a Date, DateTime or Time object. nil given.
↓
↓ nil対策
↓
<%= l nil, default: '' %>
=> ""
# t = translate (config/locales配下の訳文(ja.yml)を参照する)(I18n.t)
# l = localize (DateオブジェクトやTimeオブジェクトを現地のフォーマットに変換する)(I18n.l)
-----------------------------------------------
#### modelで使う場合
# 「ユーザー」が表示される。(activerecord.models.userを参照)
<li><%= User.model_name.human %></li>
# 「ID」が表示される。(activerecord.attributes.user.idを参照)
<li><%= User.human_attribute_name(:id) %></li>
# 「メールアドレス」が表示される。(activerecord.attributes.user.emailを参照)
<li><%= User.human_attribute_name(:email) %></li>
7. 様々な記述方法 (加えてYAMLの記法を学ぶと良い)
ja.yml
# サンプルコード
# 全ファイル共通の使いまわす可能性のあるワードは dictionary を起点にする。
ja:
dictionary:
messages:
# 呼び出し方
# ■ 階層を.でつなげた文字列を渡す
# I18n.t("dictionary.messages.hello_user", user_name: "ヤマダ")で呼び出す
# ■ scopeで階層を区切り(文字列でも配列でも可能)、対象のkeyを渡す
# I18n.t(:hello_user, scope: "dictionary.messages", user_name: "ヤマダ")
# I18n.t(:hello_user, scope: [:dictionary, :messages], user_name: "ヤマダ")
hello_user: 'こんにちは%{user_name}さん'
words:
user: &user 'ユーザ情報' # &user はエイリアスで *user で参照できる。(同一ファイル内のみ有効)
user_copy: *user # 'ユーザ情報' となる。
helpers
ja.yml
# サンプルコード
# ヘルパー関数はhelpersを起点にする。
# ヘルパー関数内で tメソッドを使用すると、呼び出し元のビューに基づいたパスが呼び出される。
# 例えばusersのshowから呼ばれたヘルパー関数内で t('.hoge') を実行した場合 users.show.hoge が参照される。
# 呼び出し元によって文言を変えたい場合はビュー側に記述する。(そんなことあるかわからないけど。)
ja:
helpers:
submit:
create: "%{model}を登録する"
update: "%{model}を更新する"
account:
create: "保存する"
login_form:
create: "ログインする"
select:
prompt: "選択してください。"
links:
show: "詳細"
back: "戻る"
destroy: "削除"
edit: "編集"
new: "新規作成"
cancel: "キャンセル"
errors
ja.yml
# サンプルコード
# グローバルな感じのエラーはerrorsを起点にする。
ja:
errors:
format: "%{message}"
messages: &errors_messages
inclusion: "%{attribute}が正しくありません。"
exclusion: "%{attribute}は正しくありません。"
invalid: "%{attribute}が正しくありません。"
confirmation: "%{attribute}が一致しません。"
accepted: "%{attribute}をチェックしてください。"
empty: "%{attribute}を入力してください。"
blank: "%{attribute}を入力してください。"
required: "%{attribute}を入力してください。"
too_long: "%{attribute}は%{count}文字以内で入力してください。"
too_short: "%{attribute}は%{count}文字以上で入力してください。"
wrong_length: "%{attribute}は%{count}文字で入力してください。"
not_a_number: "%{attribute}は数値で入力してください。"
not_an_integer: "%{attribute}は整数で入力してください。"
greater_than: "%{attribute}は%{count}より大きい値を入力してください。"
greater_than_or_equal_to: "%{attribute}は%{count}以上の値を入力してください。"
equal_to: "%{attribute}は%{count}にしてください"
less_than: "%{attribute}は%{count}より小さい値にしてください"
less_than_or_equal_to: "%{attribute}は%{count}以下の値にしてください"
odd: "%{attribute}は奇数を入力してください。"
even: "%{attribute}は偶数を入力してください。"
taken: "%{attribute}がすでに使用されています。"
before: "%{attribute}は%{threshold}よりも前の%{type}を入力してください。"
before_or_equal_to: "%{attribute}は%{threshold}以前の%{type}を入力してください。"
after: "%{attribute}は%{threshold}よりも後の%{type}を入力してください。"
after_or_equal_to: "%{attribute}は%{threshold}以降の%{type}を入力してください。"
out_of_contract: "%{attribute}が契約期間外です。"
file_size_exceed: "%{file_name}のファイルサイズが大きすぎます。"
file_type_invalid: "アップロードできないファイル形式です。"
file_name_too_long: "ファイル名が長すぎます、%{count}文字以内の名称のファイルを指定してください。"
access_forbidden: "指定された情報にアクセスする権限がありません。"
pixel_size_too_large: "画像ファイルの大きさは %{width} × %{height} ピクセル以内にしてください。"
invalid_chars: "%{attribute}に使用できない文字が含まれています(%{chars})。"
in_between: "の容量は%{min}以上%{max}以下にしてください。"
spoofed_media_type: "%{attribute}の拡張子と内容が一致していません。"
flash
ja.yml
# サンプルコード
# flashのi18nの設定方法
ja:
flash:
new: 作成しました!
updated: 更新しました!
failed: 失敗しました!
destroy: 削除しました!
login: ログインしました!
logout: ログアウトしました!
limited_access: 不正な侵入です!!
tag_follow: タグをフォローしました!
tag_not_follow: タグをフォローできませんでした。
tag_remove_follow: タグのフォローを解除しました!
複数行テキスト
config/locales/user_mailer/ja.yml
# サンプルコード
# 参考URL: https://qiita.com/jerrywdlee/items/d5d31c10617ec7342d56 (YAMLで複数行テキストを書きたい時のあれこれ)
# 基本形に「-」を追加することで最終行の改行を削除します。
ja:
user_mailer:
signature: |-
株式会社Hoge
営業時間:10:00-19:00
営業日:月~金(土日祝除く)
# 基本形
ja:
foo: |
bar
baz
Placeholders
<%= f.input :name, placeholder: true %>
ja:
helpers:
placeholder:
message:
name: "プレースホルダー"
HTMLを使う
_htmlで終わるkeyは、HTMLとして表示されます。
名前が'html'であるキー、および名前が'_html'で終わるキーは、「HTML safe」とマークされます。これらのキーをビューで使うと、その部分のHTMLはエスケープされません。
app/views/dashboard/show.html.erb
# app/views/dashboard/show.html.erb
<%= t ".welcome_html", name: "山田" %>
config/locales/views/dashboard/ja.yml
ja:
dashboard:
show:
hello_html: "Welcome, <strong>%{name}</strong>"
メールの件名
引数なし
user_mailer.rb
# user_mailer.rb
class UserMailer < ActionMailer::Base
def welcome(user)
#...
end
end
ja:
user_mailer:
welcome:
subject: "ようこそ!"
引数あり
default_i18n_subject
を使う
user_mailer.rb
# user_mailer.rb
class UserMailer < ActionMailer::Base
def welcome(user)
mail(to: user.email, subject: default_i18n_subject(user: user.name))
end
end
ja:
user_mailer:
welcome:
subject: "%{user}さん, ようこそ!"
参考
Rails国際化 (I18n) API
Ruby on RailsのI18nで使用する名前空間に関してのまとめと、ベストプラクティスの検討。 - 波打際のブログさん