Ruby言語やLinuxのネタが多いです。
October 04, 2008 [おもひで]
■ [Rails] JavascriptのLocalization with GetText
いくつかやり方は考えられるけど、GetTextを使うのだから、
1. 外出しの*.jsをgettextの手法でローカライズできる。
2. もちろん、翻訳文字列はpoファイルで管理。マージ等もできるように。
という2つを大前提として、アイデアを考えてみた。まずは第1弾(?)。
■ まず、gettext.js, app.jsをpublic/javascripts/配下に配置する。
gettext.js ・・・ gettextライブラリ(Ruby-GetTextに同梱するイメージ)。今回は_()のみ。
app.js ・・・ アプリのために開発したJavascriptの関数をまとめたもの
- public/javascripts/gettext.js -
var transdata = new Array(); //transdataが肝
function _(str) {
return transdata[str] || str;
}
- public/javascripts/app.js -
function test(){
alert(_("Error!"));
}
■ View(layouts)のファイル(抜粋)。articlesとかはまぁ適当に。
- app/views/layouts/articles.html.erb -
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<%= javascript_include_tag "gettext" %> //(1)
<%= javascript_include_tag "app" %> //(2)
<%-
javascript_tag{ #(3)
GetText::TextDomainManager.textdomain("blog").current_mo.each do |key, val|
-%>
transdata["<%= key.gsub(/\n/, '\n') %>"] = "<%= val.gsub(/\n/, '\n') %>"
<%-
end
}
-%>
</head>
<body>
<a href="javascript:test();">click</a> //(4)
<%= yield %>
</body>
</html>
(1)でgettext.jsを先に読み込み、(2)でgettext.jsを使用するapp.jsを読み込む。
(3)で、JavascriptにGetText::TextDomainManagerという耳慣れないメソッドを使ってるけど、要はここでカレントロケールのmoファイルを取得し(ここでのテキストドメインは"blog")、transdataにkey, valを格納するというJavascriptのソースをHTMLに埋め込んでいく。
(4)で、app.js内の関数を呼び出している。このタイミングで呼び出した関数は適切に翻訳される。
■ あ、そうそう、忘れてたけど、Rakefileのupdatepoタスクにjsを読み込むように追加する。
task :updatepo do
require 'gettext/utils'
GetText.update_pofiles("blog", Dir.glob("{app,lib,public/javascripts}/**/*.{rb,erb,js}"),
"blog 2.0.0")
end
■ この方法だとmoファイルをそのまま読み込んでしまう。つまりJavascriptに関係ない文字列等も抽出してしまい、無駄が多い。また、JavascriptとしてHTML上に記述する翻訳データはフラグメントキャッシュも適用すべきだね。
テキストドメインがJavascript側で指定できた方がいいかも。
・・・などなど色々と検討しなければいけないことが多そうだな・・・。
■ ま、これで、他のerbファイル同様の翻訳を行うことができるし、updatepo/makemoも今までとやり方が変わらない。jsファイル・erbファイルなどに限らずローカライズされたメッセージを一元管理できるというのも魅力的だと思うので、ここを出発点にもう少し考えてみるとしよう。
