JavaScriptで、国際化されたメッセージを取得する(Gettext.js)
Starbug1は、gettextを使ってメッセージを国際化しています。現在、英語・日本語・中国語(簡体/繁体)に対応してます。JavaScriptでもメッセージを表示してるので、今までは、Ajaxでサーバにメッセージ変換リクエストを投げて、変換する仕組みを自前で実装していました。この実装が、うまくなくて、投稿時などの、確認メッセージを表示するときに、数秒待たされることがありました。(それを回避しようとして、非同期でメッセージ変換をしたりしたけど、今度はページロード直後にプチフリするような感じになってしまっていました)
サーバと同じメッセージリソースの*.moファイルを読んでくれるJavaScriptのgettext実装があればいいのにと、Twitterでつぶやいたところ、
http://twitter.com/#!/smeghead/status/68972362183360512
@smeghead: JavaScriptによるgettext実装ってあるのかな?
http://twitter.com/#!/finalfusion/status/68972869794803713
@finalfusion: @smeghead 昨日だか一昨日あたりに紹介記事を見かけたような
早速、@finalfusionさんに、最近紹介されていたという情報を頂きました。
http://www.moongift.jp/r/2011/05/20110511
2011/05/10
JavaScriptでもGettextを使った多言語対応「JavaScript Gettext」
おぉ、数日前にmoongiftで紹介されている。なんとグッドタイミングなんだと、ちょっとビックリした。
使い方
Starbug1への導入時にやったことの記録です。 http://jsgettext.berlios.de/doc/html/Gettext.html を参考にしました。言語リソースデータの指定方法はいくつかありますが linkタグでjsonのurlを指定する形式を選択してみました。
// ////////////////////////////////////////////////////////// // The other way to load the language lookup is a "link" tag // Downside is that not all browsers cache XMLHttpRequests the // same way, so caching of the language data isn't guarenteed // across page loads. // Upside is that it's easy to specify multiple files <link rel="gettext" href="/path/LC_MESSAGES/myDomain.json" /> <script language="javascript" src="/path/Gettext.js'></script> var gt = new Gettext({ "domain" : "myDomain" }); // rest is the same |
linkタグで指定した場合、XMLHttpRequestsリスエストで、データを取得するようなので、キャッシュが効かないブラウザも あるとありますが、chromeで確認したらキャッシュされてました。
出力するhtmlに、以下を含めるようにした。
<link rel="gettext" href="/starbug1/index.cgi/../js/lang/ja_JP.json" /> <script type="text/javascript" src="/starbug1/index.cgi/../js/Gettext.js"></script> <script type="text/javascript"> var gt = new Gettext({"domain": "starbug1"}); function _ (msgid) { return gt.gettext(msgid); } </script> |
これで、_ 関数が使えるようになる。
jsonのリソースファイルの用意は、http://jsgettext.berlios.de/doc/html/po2json.html を参考に po2json を使った。
$ po2json /path/to/domain.po > domain.json |
これで、C言語から使っているpoファイルから、jsonを生成できた。 ここでちょっと嵌ったのが、linkタグに指定するデータは、これを少し修正する必要がある。 messageというキーの値として、po2jsonの結果を指定したものである必要がありました。
$ echo '{"message": ' > domain.json $ po2json /path/to/domain.po >> domain.json $ echo '}' >> domain.json |
最終的には、Makefileに以下を追加しました。
jsresource: js/lang/en_US.json js/lang/ja_JP.json js/lang/zh_CN.json js/lang/zh_TW.json js/lang/en_US.json: locale/en.po echo '{"message": ' > js/lang/en_US.json bin/po2json locale/en.po >> js/lang/en_US.json echo '}' >> js/lang/en_US.json js/lang/ja_JP.json: locale/ja.po echo '{"message": ' > js/lang/ja_JP.json bin/po2json locale/ja.po >> js/lang/ja_JP.json echo '}' >> js/lang/ja_JP.json js/lang/zh_CN.json: locale/zh.po echo '{"message": ' > js/lang/zh_CN.json bin/po2json locale/zh.po >> js/lang/zh_CN.json echo '}' >> js/lang/zh_CN.json js/lang/zh_TW.json: locale/zh_TW.po echo '{"message": ' > js/lang/zh_TW.json bin/po2json locale/zh_TW.po >> js/lang/zh_TW.json echo '}' >> js/lang/zh_TW.json |
結局これだけで、サーバサイドで使っている言語リソースを共有することができ、しかもパフォーマンス的にも 以前より快適になったと思います。
ssss