アプリケーションの i18n 対応

復元しようとしている森高千里さんのページは、日本語版だけでなく英語版も用意していました。当時は海外のファンも多かったですし、World Wide Web 自体も海外の方が進んでいたためです。実際 米Yahoo からリンク掲載依頼があり、日本のサイトより先に Yahoo のページにリンクが掲載されていたくらいです(当時、米Yahoo は登録制のリンク掲載サイトでした)。

そんなわけで、今回も日本語・英語の両ページを作ります。当時は力技で頑張っていましたが、Railsi18n の仕組みがあるので、それを活用します。今回は閲覧限定であるため、セッション管理はしないため、クッキーなどではなく URI に言語情報を埋め込むことにします。全ページに対して、日英の両ページを作成するつもりなので、処理は一括して ApplicationController の before_filter で済ませることができます。

class ApplicationController < ActionController::Base
  before_filter :set_locale
  protect_from_forgery
  AVAILABLE_LOCALES = %w(en ja)
  include MiscMethod

  # 全ページで、l18n.locale をパラメータから取得
  # パラメータがなければデフォルトを設定
  # 日本語のページである場合、@is_ja を true にセット
  def set_locale
    I18n.locale = params[:locale] || I18n.default_locale
    @is_ja = I18n.locale == :ja
  end

  # すべてのリンクに locale パラメータを追加する
  def default_url_options(options={})
    { :locale => I18n.locale }
  end
end

この結果、最初のアクセス時にはデフォルト値が設定されますが、それ以降は自分が保持している locale が引き継がれます。

また、各 model のタイトルに相当する属性には、j_title、e_title という属性を持たせます。英語のタイトルで両方に同じ情報をもたせるのも莫迦らしいので、その場合には e_title は nil にします。accessor としては、これらの属性とは別に、jtitle、etitle を用意します。さらに、title(is_ja) というメソッドを用意し、ApplicationController で用意した @is_ja を使って、対応する言語のタイトルが表示されるようにします。

各 model で同じ機能が必要なので,ここでは Title モジュールを作り、各モデルで include (Mix-in) するようにします。

# vim:set fileencoding=utf-8 filetype=ruby:

module Title
  # 日本語は j_title 属性をそのまま使います。
  def jtitle
    j_title
  end

  # 英語は、e_title があればそれをなければ j_title を使います。
  def etitle
    e_title || j_title
  end

  # title はフラグをみて、該当の言語を取得します。通常はこれしか使いません。
  def title(is_ja)
    is_ja ? jtitle : etitle
  end

end

各 view (HAML) では,基本的に日本語・英語を区別せずに記述します.基本的には I18n.t メソッドを使って翻訳したテキストを取得します.トップページの HAML の頭の部分は以下のようになります.

%h1=t :site_title
%p=t :top_comment
%hr
%ul
  %li=t :personal_info
  %li=link_to lh(t :history), years_path
  %li=link_to lh(t :list_of_albums), albums_path
  %li=link_to lh(t :list_of_singles), singles_path

このように、I18n.t (I18nは省略可能)にシンボルを渡します.なお、シンボルに対する翻訳テーブルは config/locales/ja.yml や config/locales/en.yml に記述します.ja.yml の一部を以下に示します.

# vim:set fileencoding=utf-8 filetype=ruby:

ja:
  cm: "森高千里"
  site_title: "森高千里データベース"
  home: "ホーム"
  top_comment: "このページでは、森高千里さんに関するさまざまな情報を提供しています."
  personal_info: "個人情報"
  history: "履歴"
  list_of_albums: "アルバム一覧"
  albums: "アルバム"
  list_of_singles: "シングル一覧"
  singles: "シングル"

同様に en.yml の一部を以下に示します.

# vim:set fileencoding=utf-8 filetype=ruby:

en:
  cm: "Chisato Moritaka"
  site_title: "Chisato Moritaka Database"
  home: "Home"
  top_comment: "In this home page, you can see information about Chisato Moritaka. "
  personal_info: "Personal Infomation"
  history: "History"
  list_of_albums: "List of Albums"
  albums: "Albums"
  list_of_singles: "List of Singles"
  singles: "Singles"

これらの翻訳テーブルのおかげで、HAML は言語に非依存で記述が可能となります。かなり便利ですね。