はじめに
Rails2.2ではついに国際化が標準で搭載されることになった。
これまでRuby on Railsで作ったアプリの検証メッセージなどを日本語化する場合は
gettextを使う方法がデファクトスタンダードだったけれど、正直めんどくさいし、初心者にはとっつきにくかった。
ということで正式版が登場する前にi18nを試してみよう。
準備
まずはプロジェクトを作成してedge版を展開する。
- % rails sample
- % cd sample
- % rake rails:freeze:edge
次に必要なプラグインをインストールする
localized_datesとi18nを入れる。
http://github.com/clemens/localized_dates/tree/master
http://github.com/mattetti/i18n/tree/master
- % script/plugin install git://github.com/clemens/localized_dates.git
- % script/plugin install git://github.com/svenfuchs/i18n
次にi18nを初期化してロケールファイルを読み込む処理を用意
config/initializers/init_i18n.rb
というファイルを作成して
- I18n.default_locale = 'ja-JP'
- LOCALES_DIRECTORY = "#{RAILS_ROOT}/config/locales/"
- LOCALES_AVAILABLE = Dir["#{LOCALES_DIRECTORY}/*.{rb,yml}"].collect do |locale_file|
- File.basename(File.basename(locale_file, ".rb"), ".yml")
- end.uniq.sort
を記述する。
デフォルトのロケールを日本語にしてconfig/locales/以下にあるロケール名.rb、ロケール名.ymlを読み込む。
次にロケール用のファイルを用意する
- touch config/locales/ja-JP.rb
- touch config/locales/ja-JP.yml
サンプルアプリをscaffoldで作成する
日本語化の準備ができたのでサクっとscaffoldでメモ帳など作ってみよう。
- % script/generate scaffold note title:string body:text
app/models/note.rbを編集する
- # app/models/note.rb
- class Note <ActiveRecord::Base
- validates_presence_of :title, :body
- validates_uniqueness_of :title
- end
確認
ではサーバを起動して確認してみよう
- % rake db:migrate
- % script/server
失敗。
翻訳が見つからないそうだ。
config/locales/ja-JP.rb
を以下のように編集して、基本的な翻訳メッセージを用意してやる。
- {
- :'ja-JP' => {
- # date and time formats
- :date => {
- :formats => {
- :default => "%Y-%m-%d",
- :short => "%e %b",
- :long => "%B %e, %Y",
- :long_ordinal => lambda { |date| "%B #{date.day}, %Y" },
- :only_day => "%e"
- },
- :day_names => %w(日曜日 月曜日 火曜日 水曜日 木曜日 金曜日 土曜日),
- :abbr_day_names => %w(日 月 火 水 木 金 土),
- :month_names => [nil] + %w(1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月),
- :abbr_month_names => [nil] + %w(1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月),
- :order => [:year, :month, :day]
- },
- :time => {
- :formats => {
- :default => "%a %b %d %H:%M:%S %Z %Y",
- :time => "%H:%M",
- :short => "%d %b %H:%M",
- :long => "%B %d, %Y %H:%M",
- :long_ordinal => lambda { |time| "%B #{time.day}, %Y %H:%M" },
- :only_second => "%S"
- },
- :am => '',
- :pm => ''
- },
- # date helper distance in words
- :datetime => {
- :distance_in_words => {
- :half_a_minute => '30分',
- :less_than_x_seconds => '{{count}} 秒以下',
- :x_seconds => '{{count}} 秒',
- :less_than_x_minutes => '{{count}} 分以下',
- :x_minutes => '{{count}} 分',
- :about_x_hours => '約 {{count}} 時間',
- :x_days => '{{count}} 日',
- :about_x_months => '約 {{count}} ヶ月',
- :x_months => '{{count}} ヶ月',
- :about_x_years => '約 {{count}} 年',
- :over_x_years => '{{count}} 年以上'
- }
- },
- # numbers
- :number => {
- :format => {
- :precision => 3,
- :separator => '.',
- :delimiter => ','
- },
- :currency => {
- :format => {
- :unit => '¥',
- :precision => 2,
- :format => '%u%n'
- }
- }
- },
- # Active Record
- :activerecord => {
- :errors => {
- :template => {
- :header => "{{model}}でエラーが発生しました",
- :body => "以下のメッセージを確認してください:",
- },
- :messages => {
- :inclusion => "は、リストに含まれていません",
- :exclusion => "は、有効な値ではありません",
- :invalid => "は、妥当な値ではありません",
- :confirmation => "は、確認できません",
- :accepted => "は、入力できません",
- :empty => "は、何も入力されていません",
- :blank => "は、空白です",
- :too_long => "は、長すぎます ({{count}}文字以下)",
- :too_short => "は、短すぎます ({{count}}文字以上)",
- :wrong_length => "は、桁数が合っていません({{count}}桁必要です)",
- :taken => "は、有効ではありません",
- :not_a_number => "は、数字ではありません",
- :greater_than => "は、{{count}}文字を超えて入力されています",
- :greater_than_or_equal_to => "は、{{count}}文字以上入力されています",
- :equal_to => "は、{{count}}と同値です",
- :less_than => "は、{{count}}文字未満です",
- :less_than_or_equal_to => "は、{{count}}文字以下で入力されています",
- :odd => "は、端数が入力されています",
- :even => "は、偶数が入力されています"
- }
- },
- },
- }
- }

エラーメッセージが日本語になった!
でもnoteとかTitleとかBodyとか中途半端だ。
Modelの属性名もちゃんと日本語化したい。
モデルの属性名を翻訳
config/locales/ja-JP.ymlを以下にように編集して、サーバを再起動する
- ja-JP:
- activerecord:
- models:
- note: ノート
- attributes:
- note:
- title: タイトル
- body: 本文

おー、モデルの属性値も日本語化された。
完璧、完璧。
しかし、New Noteとかの文言も日本語化したいと思うのが親心というもの。
モデル以外の文言も翻訳する
config/locales/ja-JP.ymlを以下のように編集
- ja-JP:
- activerecord:
- models:
- note: ノート
- attributes:
- note:
- title: タイトル
- body: 本文
- label:
- notes:
- new_note: 新しいノートを作成
- create: 作成する
- back: 前の画面へ
そしてapp/views/notes/new.html.erbを
- <h1><%= t('label.notes.new_note') %></h1>
- <% form_for(@note) do |f| %>
- <%= f.error_messages %>
- <p>
- <%= f.label :title, t('activerecord.attributes.note.title') %><br />
- <%= f.text_field :title %>
- </p>
- <p>
- <%= f.label :body, t('activerecord.attributes.note.body') %><br />
- <%= f.text_area :body %>
- </p>
- <p>
- <%= f.submit t('label.notes.create') %>
- </p>
- <% end %>
- <%= link_to t('label.notes.back'), notes_path %>
ちょっと冗長な気がするけど気にしない気にしない
サーバを再起動して確認すると

できたー。
基本はロケールファイルにハッシュで翻訳メッセージを記述していき
tメソッドで呼び出すという感じみたいだ。
gettextほどお手軽ではないけれども、今後スタンダードになっていくのだから今から覚えておいても損はないはずだ。
ファイル一式
今回作成したファイル。

2月 23rd, 2009 at 5:40 PM #yuum3のお仕事日記
[Ruby] Ruby on Rails 2.3 で I18N を使ってみた
バージョン2.2はスキップしてしまったので、正式なI18Nを使うのは バージョン2.3 が初めてです。 Rails2.2の新機能i18nを使ってみる – func09 が大変参考になりました。 ただし、この記事はバ…
2月 26th, 2010 at 10:25 PM #Rails 2.3.5 で i18n を使ってメッセージを日本語化する : Serendip - Webデザイン・プログラミング
[...] リソースファイルの内容はこちらのサイト『Rails2.2の新機能i18nを使ってみる – func09』の翻訳メッセージを参考にした。 [...]