はじめに
現在、プログラミングスクールRUNTEQで未経験からWebエンジニア転職を目指して学習中のyushiと申します。
Railsについて学ぶ中でi18n対応をするためのymlファイルの構成について腑に落ちない部分があったので詳しく調べてみました。
プログラミング初学者のため、内容に誤りがある可能性がございます。
もし間違いがあればご指摘いただけると幸いです。
まずはざっくりとi18nについて抑えておきたいと思います。
i18nとは?
アプリケーション内で使われる文字列を抽象化して言語ごとに訳文を定義してあげることで、動作する言語環境に応じてアプリケーション側で自動で翻訳するための仕組みです。
ビューに記載する文字列が特定の言語に依存せずに済むようになり、複数言語での開発や実行環境による差分を用意する手間を減らすことができます。
「internationalization」という単語が語源になっていて、最初の「i」と最後の「n」の間に18文字あることから「i18n」と呼ばれているそうです。
Railsにはデフォルトでi18nの機能が備わっていますが、rails-i18n
というgemと組み合わせることでアプリケーションの国際化・地域化が容易になります。
rails-i18nに用意してあるja.ymlについては自分で記述せずに利用できるようになります。
翻訳の仕組み
config/locales
以下にあるすべての.rb
ファイルと.yml
ファイルは、自動的に訳文読み込みパスに追加されます。(以下、まとめて翻訳ファイルと呼びます)
一般的に翻訳先の言語.yml
のように命名されます。(en.yml
、ja.yml
)
翻訳ファイルは複数に分割することもできます。
規模の大きいプロジェクトになると翻訳ファイルの行数が膨大になるので、役割ごとに翻訳ファイルを分割するのが一般的なようです。
翻訳する際にはビューヘルパーメソッドであるtranslate
メソッド、もしくはエイリアスのt
メソッドを使います。
<%= translate('users.new.title') %>
<%= t('users.new.title') %>
また、enum_help
やsimple_form
などgemがi18nに対応している場合は、それぞれの形式で訳文を追加できるようになります。
1つ注意点としては、デフォルトのロケールが英語(:en
)に設定されているので、デフォルトを日本語にしたい場合はconfig/application.rb
の記述を変更する必要があります。
module App
class Application < Rails::Application
...
# この部分の:enを:jaに変更する
config.i18n.default_locale = :en
end
end
ymlファイルの構成について
ymlファイルの書き方として、基本的にインデントを利用して階層構造を表現します。
訳文を追加する際には、キー: 値
のペアになるようにします。
多層構造になっている訳文を呼び出したい場合は:
を.
に読み替えて、繋げて呼び出します。
まず、一行目にどの言語の翻訳ファイルなのかということを明記します。
ここの情報とアプリケーションの実行環境を照らし合わせて、どの翻訳ファイルから訳文を呼び出すかが決まります。
この下に訳文を記述していくのですが、いくつかルールがあります。
例を見ながら説明していきましょう。
ja:
helpers:
submit:
create: 登録
update: 更新
label:
email: メールアドレス
password: パスワード
defaults:
flash_message:
success: "%{item}の作成に成功しました"
failure: "%{item}の作成に失敗しました"
activerecord:
models:
user: ユーザー
attributes:
user:
name: ユーザー名
age: 年齢
height: 身長
users:
index:
title: ユーザー一覧ページ
new:
title: ユーザー新規登録ページ
header:
login: ログイン
logout: ログアウト
1. モデルの訳文はactiverecord
以下に記述する
これによってモデル名.model_name.human
メソッドとモデル名.human_attribute_name(attribute)
が使えるようになります。
また、バリデーションエラーのメッセージなどで表示されるカラム名が翻訳されるようになります。
2. ビューはビューを格納しているフォルダ名を起点にして、ファイル毎に記述する
対応するビューで呼び出す時にツリーを省略できるようになります。(遅延探索)
<%= t('users.new.title') %>
<%# 上の翻訳ファイルのusers以下とビューファイルのパスが一致しているため、以下の呼び出しも可能 %>
<%= t('.title') %>
3. ヘルパーメソッドの訳文はhelpers
以下に記載する
例えば、form_with
メソッドで生成したフォームの中で使うヘルパーメソッド(f.label
やf.submit
)などの訳文はここで定義します。
下の例では、ユーザーの新規登録処理を行なっているので、翻訳ファイルのhelpers: submit: create:
が呼び出されてf.submit
で生成されるボタンのテキストが「登録」になります。
ここはform_with
メソッドと同様にmodel
オプションにセットしたインスタンスの状態によって参照する訳文が変わります。
<%= form_with model:@user %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit %>
4. 引数を渡して表示する訳文を動的に変える
訳文にエスケープ文字を記述することで、動的に文面を変えることもできます。
訳文を""
で囲むこととエスケープ文字%{}
の記述に注意してください。
def create
@user = user.new(user_params)
if @user
redirect_to root_path
else
flash.new[:danger] = t('defaults.flash_message.failure', item: 'ユーザー')
render :new, status: :unprocessable_entity
end
end
5.defaults
オプションについて
- アプリケーション内の複数箇所で共通して使用される文言をまとめて指定する
- 特定の言語に対する翻訳が見つからなかった場合に、ここで設定した値で代替される
6. これらのルールに当てはまらない場合
例えば、ヘッダーやフッターなど部分テンプレートで使うテキストの訳文を指定したい場合は、ymlファイルで定義した階層構造を.
で読み替えて呼び出します。
<%# ヘッダーにログインページへのリンクを置く場合 %>
<%# ymlファイルでheader: login: と定義しているので、これに従って呼び出す %>
<%= link_to t('header.login'), login_path %>
最後に
というわけでi18nに使うymlファイルの構成について整理してみました。
最初に触れた時は見よう見真似で済ませてしまっていましたが、改めて整理してみるとどういう理屈で訳文が呼び出されているのか理解が深まったように思います。
今回調べていても翻訳ファイルからどういうルールで呼び出しているかを詳しく書いた記事があまり見つからなかったので、後学の方の参考になると嬉しいです!