btoメモ

なんか適当に書く

Javascriptで国際化プログラミング

Javascriptでプログラムを国際化する仕組みがなさそうだったので作ってみました。

基本的にはUNIX系OSで広く使われているgettextJavascriptで使えるようにしたものです。

prototype.js が必要です。

gettext.js: gettext本体

local.php: ロケールデータをJSONに変換するPHPスクリプト

gettext.tar.bz2: アーカイブファイル 動作デモで使ってる全てのデータが入ってます。

動作デモ

仕様はほとんど同じなのですが、若干異なる部分があります。

メソッドは全てLocaleオブジェクトの中に閉じ込めています。

なので、全てのメソッドは Location.hoge() の形で呼び出す必要があります。

メソッド命名規則prototype.jsにあわせてあります。

Locale.setLocale(category, locale)

setlocale() と同じ。

現状LC_MESSAGESしか意味がありません。

Locale.bindTextDomain(domain, directory, func)

bindtextdomain() と同じですが、第3引数が増えています。

domain, directory で指定された情報を元にロケールデータを取得します。

ロケールデータはJSONで取得します。

アクセス先は

directory/LC_MESSAGES/locale/domain.js

になります。

第3引数にはロケールデータの読み込みが完了した時に実行する関数オブジェクトを指定します。

Locale.getText(string)

gettext()と同じ。

渡された文字列からロケールに含まれる文字を返します。

Locale.getTextNoop(string)

gettext_noop()と同じ。

xgettextにロケール文字列であることを知らせるだけに使用します。

処理は全く行いません。

_(), N_()

gettextを使う時は、gettextと書くのが大変なので、よく"_", "N_"のようなマクロを定義して使用します。

慣例にならって同じように"_", "N_"を定義しました。

それぞれLocale.getText, Locale.getTextNoopと全く同じ処理を行います。

Locale.setSuffix(suffix)

オリジナルのgettextにはないメソッド

ロケールデータはデフォルトではdomain.jsなのですが、拡張子を変更することができます。

動作デモではphpに変更しています。

webアプリならではのメソッドです。gettextだけのためにapacheの設定いじるのはやりたくないので。

使い方

ロケールデータを作ります。

xgettext -k_ -kN_ -j index.html -o locale/ja/LC_MESSAGES/i18n_javascript.po

.htmlが対応してない拡張子なのでwarningが出ますが問題なく処理されます。(Cのプログラムだと仮定して処理される)

poファイルを編集する。

編集後のpoファイル

poファイルのデータをJSONに変換するためにlocale.phpへのsymlinkをはる。

ln -s $PWD/locale.php locale/ja/LC_MESSAGES/i18n_javascript.php

po -> JSONの処理にはPEAR:File_Gettext, PEAR:Services_JSONを使ってます。

以上で作業は終わりです。

これでJavascriptで国際化したプログラムを書けるようになります。

まとめ

PHP, Perlなどのサーバサイドのスクリプトgettextを使って、出力するJavascriptの言語を動的に変更して国際化をすることもできます。

しかし、動的コンテンツとして出力するJavascriptを変更していては、クライアントでデータをキャッシュすることができないし、サーバにやさしくありません。

Javascriptで国際化をすれば、Javascriptファイルは動的に変化しないので静的コンテンツとして出力することができます。

謝辞:

PEAR:File_Gettext の使い方に

http://blog.poyo.jp/archives.php/categ-1/year-2006/month-4/id-1145313508

を参照させてもらいました。

貴重な情報をありがとうございます。