よたらぼ
自分の興味の赴くままにIT技術系のネタを取りとめもなくメモっています。
Ruby言語やLinuxのネタが多いです。

October 04, 2002

[tDiary] アクセスカウンタ表示プラグイン

また、counter.rbが壊れました。今度のは豪快に1コ前(つまり今日まる一日分)のデータがバックアップともにぶっとびました。

#しょうがないので1日前のデータに復旧しました。むぅ。

ちなみに今までも何回か壊れてたんだけど、自動復旧できてたんだよねぇ(実は壊れたらメールをくれるようにリリース版に手を入れてある)。今の自動復旧の仕組はまだ甘いと言うことか。トホホ。


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ファイルなどに限らずローカライズされたメッセージを一元管理できるというのも魅力的だと思うので、ここを出発点にもう少し考えてみるとしよう。


追記