岩本隆史の日記帳(アーカイブ)

はてなダイアリーのサービス終了をうけて移行したものです。更新はしません。

Pinto公開に向けて #7 ― Ruby-GetText-Packageで多言語対応した

あらすじ

Rubyの勉強がてら、Pintoというソーシャルブックマークサービスを作っています。前回の予告どおり、Ruby-Gettext-Packageで多言語対応したので、そのメモを残しておきます。

テンプレートの検討

<a href="<%== uri('signup_openid', 'lang' => @lang) %>"><%= _('Sign Up') %></a>

としておいて、URIで指定された言語によってアンカー文字列を切り替えることにしました。

  • http://pinto.jp/index.en へのアクセス → 「Sign Up」
  • http://pinto.jp/index.ja へのアクセス → 「ユーザー登録」

コントローラの修正

URIで指定された言語をビューレンダリング時のパラメータとして渡すようにしました。

:lang => request['uri_map']['lang']

ビューオブジェクトの修正

レンダリング時のパラメータに言語が含まれる場合は翻訳用のヘルパーメソッドを追加するようにしました。

if param.has_key? :lang
  context.extend Pinto::View::Helper::Translate
  context.lang = param[:lang]
end

他のヘルパーと違ってextendにしなかったのは、テンプレート内のメソッドが:

<%= _('Sign Up', @lang) %>

のように言語を毎回指定する形だとDRYではないと考えたからです。そこでインスタンス変数として言語が設定できるようにしました。

Ruby-GetText-Packageの導入

ヘルパーメソッドでは国際化ライブラリを使います。国際化といえばgettextが定石と思い、Ruby-GetText-Packageを試すことにしました。

gem install gettext

実は、ここからかなり試行錯誤しました。現状、こんな流れでmoファイルを作っています。

potファイルの作成

rake pot

Rakefileのpotタスク内部から、GetText.rgettextを呼び出しています。

Windows環境なので、作成されるpotファイルの改行コードがCR+LFになってしまうのですが、Gitで管理する都合上、LFに直す対応もタスクに入れています。

poファイルの作成

poファイル編集ツールのPoeditで編集しています。

保存する際に、なぜだか分からないのですが、poファイルのヘッダから「POT-Creation-Date」や「PO-Revision-Date」の値が抜けてしまうことがあります。そのため、moファイル自動作成機能はオフにしています。

moファイルの作成

rake mo

moタスク内部から、GetText.create_mofilesを呼び出しています。

poファイル中の抜けているヘッダを補う対応も入れています。この辺、あんまり格好よくないですね。

ヘルパーメソッドの作成

moファイルができたので、いよいよヘルパーメソッドが動かせます。

def _(value)
  GetText.set_output_charset('UTF-8')
  GetText.bindtextdomain('pinto', {:path => '../locale'})
  GetText.set_locale(@lang)
  return GetText._(value)
end

この set_output_charset → bindtextdomain → set_locale という正しい順番を見つけるのにもかなり苦労しました。これでなんとか国際化対応できました。

次のアクション