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 へのアクセス → 「ユーザー登録」
ビューオブジェクトの修正
レンダリング時のパラメータに言語が含まれる場合は翻訳用のヘルパーメソッドを追加するようにしました。
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 という正しい順番を見つけるのにもかなり苦労しました。これでなんとか国際化対応できました。