今回は id:kimukou_26 さんにコメント頂いた「I18n Plugin」をいじってみました(一覧)。
I18n プラグインは Spring の MessageSource クラスを使ってメッセージの国際化*1をするプラグインです。 正直、リソースバンドルとかプロパティファイルってエンコーディング等々が面倒なのであんまり使ったことないんですよねぇ。 なので、以下の説明は「とりあえず動く」ってレベルだと思ってくださいな。
- I18n プラグインのインストール
- リソース・バンドルの配置
- リソース・バンドルのサンプル
- MessageSource クラス
- MessageSource オブジェクトの使い方
I18n プラグインのインストール
まずは I18n プラグインのインストール。 普通のプラグインのインストールと同じです。
griffon install-plugin i18n
リソース・バンドルの配置
次はリソース・バンドルの配置。 配置するフォルダは「$basedir/griffon-app/i18n」フォルダです。 このフォルダ下に「messages_《言語》.properties」という名前のプロパティ・ファイルを配置します。 例えば日本語 (ja) に対応するメッセージを定義したい場合は
- $basedir/griffon-app/i18n/messages_ja.properties (日本語 (ja) のメッセージ)
というファイルを作成します。 通常のリソース・バンドルのように国を指定することもできます*2。 デフォルトで読み込まれる(対応する言語がない場合に読み込まれる)リソース・バンドルを定義するには、同フォルダ下に「messages.properties」ファイルを定義します。
- $basedir/griffon-app/i18n/messages.properties (対応する言語がない場合のメッセージ)
I18n Plugin のドキュメントにはファイル名の「messages」の部分 (basename) を変更する方法が書かれていますが*3、イマイチうまくいかなかったのでここではスルー。
リソース・バンドルのサンプル
では、「関数描画アプリケーション」で使うリソース・バンドルのサンプルを定義してみましょう。 国際化を行うのは以下のものとします:
- アプリケーション・フレームのタイトル
- メニュー
- Controller.showAbout で表示されるメッセージ
メニューアイテム(「関数描画アプリケーション」ではアクションの名前)などは変更していませんが、やり方は同じです。
messages_ja.properties
まずは日本語に対応するリソース・バンドル。 ファイルは
- FunctionPlotter/griffon-app/i18n/messages_ja.properties
で、内容はこんな感じにしましょう:
app.title=関数描画アプリケーション app.menu.action=アクション (A) app.menu.laf=ルック&フィール (L) app.menu.help=ヘルプ (H) controller.showAbout.message=倭マン日記「はじめての Griffon 研」にて\nGriffon アプリケーションの例として作成した\n『関数描画アプリケーション』です。\n\nGroovy バージョン \: {0}\nGriffon バージョン \: {1}\nアプリケーション バージョン \: {2}
通常のリソース・バンドルと異なるのは controller.showAbout.message にある {《数字》} の部分です。 この部分はプレースホルダーになっていて、メッセージの呼び出し時に値を挿入することができます。 うむ、便利。 ただし、プロパティ・ファイルで日本語を扱いたい場合はエンコードしないといけなくて(しかも何故か ISO-8859-1)、実際には以下のようなファイルにしないとイケマセン:
app.title=\u95A2\u6570\u63CF\u753B\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3 app.menu.action=\u30A2\u30AF\u30B7\u30E7\u30F3 (A) app.menu.laf=\u30EB\u30C3\u30AF\uFF06\u30D5\u30A3\u30FC\u30EB (L) app.menu.help=\u30D8\u30EB\u30D7 (H) controller.showAbout.message=\u502D\u30DE\u30F3\u65E5\u8A18\u300C\u306F\u3058\u3081\u3066\u306E Griffon \u7814\u300D\u306B\u3066\nGriffon \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u4F8B\u3068\u3057\u3066\u4F5C\u6210\u3057\u305F\n\u300E\u95A2\u6570\u63CF\u753B\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u300F\u3067\u3059\u3002\n\nGroovy \u30D0\u30FC\u30B8\u30E7\u30F3 \: {0}\nGriffon \u30D0\u30FC\u30B8\u30E7\u30F3 \: {1}\n\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3 \u30D0\u30FC\u30B8\u30E7\u30F3 \: {2}
やっぱりプロパティ・ファイル嫌い。 IDE を使えばなんてこともないかも知れませんが、次回にちょっと改善策を。
messages.properties
次は対応する言語がない場合に使用されるメッセージ。 ファイルは
- FunctionPlotter/griffon-app/i18n/messages.properties
で、内容はこんな感じ:
app.title=Function Plotter app.menu.action=Action app.menu.laf=Look & Feel app.menu.help=Help controller.showAbout.message=A Function Plotter\nthat serves as a Griffon example for\n"Waman Diary"\n\nGroovy Version \: {0}\nGriffon Version \: {1}\nApplication Version \: {2}
MessageSource クラス
I18n プラグインのキークラス、MessageSource クラス。 このクラスには getMessage() メソッドがあれこれオーバーロードされています:
getMessage(String code) // kimukou_26 さんにご指摘頂きました。 getMessage(String code, Object[] args) getMessage(String code, List args) getMessage(String code, Object[] args, String defaultMessage) getMessage(String code, List args, String defaultMessage) getMessage(String code, Object[] args, Locale locale) getMessage(String code, List args, Locale locale) getMessage(String code, Object[] args, String defaultMessage, Locale locale) getMessage(String code, List args, String defaultMessage, Locale locale) getMessage(MessageSourceResolvable resolvable) getMessage(MessageSourceResolvable resolvable, Locale locale)
引数の大雑把な説明は下表の通り:
引数 | 型 | 必須 | デフォルト値 | 説明 |
---|---|---|---|---|
code | String | Yes | - | リソース・バンドルのキー文字列 |
args | Object[] List |
No | [] | {《数字》}の部分に挿入するオブジェクト |
defaultMessage | String | No | デフォルトのメッセージ | |
locale | java.util. Locale |
No | Locale.getDefault() | メッセージを取得する際に使用するロケール |
MessageSourceResolvable オブジェクトの引数はスルー:-9
MessageSource オブジェクトの使い方
それでは、満を持しての(?) MessageSource オブジェクトの使い方。 View と Controller で別々に見ていきます。
View で使う
View では messageSource プロパティ(もちろん MessageSource オブジェクトが返される)が追加されていて、このオブジェクトの getMessage() メソッドを呼び出すことでメッセージを取得することができます*4。 ただし、app オブジェクト自体(View では this で参照できるオブジェクト)に getMessage() メソッドが追加されているようなので、それを使う方が簡単でしょう:
application(title: getMessage('app.title'), ...){ menuBar(){ menu(mnemonic:'A', getMessage('app.menu.action')){ menuItem(action:paint) } menu(mnemonic:'L', getMessage('app.menu.laf')){ menuItem(action:showLaf) } glue() menu(mnemonic:'H', getMessage('app.menu.help')){ menuItem(action:about) } } ... }
プロパティとか関係なく、普通に getMessage() メソッドを呼び出せば、リソース・バンドルのメッセージを取得できます。 実行結果は下図のようになります:
いぇーい!
Controller で使う
Controller には messageSource プロパティを定義しても、View のように自動で値をインジェクトしてくれません。 でも、こちらでも app オブジェクトを介すればメッセージを取得するのは簡単です:
class FunctionPlotterController { ... def showAbout = { evt = null -> def meta = app.metadata // def meta = Metadata.current でも OK messageService.show( app.getMessage('controller.showAbout.message', [GroovySystem.version, meta['app.griffon.version'], meta['app.version']])) } }
ここではメッセージ中のプレースホルダー({《数字》}の部分)に挿入する文字列も指定しています。 結果はこんな感じ:
結局のところ、リソース・バンドル(プロパティ・ファイル)作るのが一番面倒でございました。
- 作者: アンドリューディッチ,デイビッドゼナッキー,Andrew Deitsch,David Czarnecki,風間一洋
- 出版社/メーカー: オライリー・ジャパン
- 発売日: 2002/09
- メディア: 単行本
- クリック: 2回
- この商品を含むブログ (2件) を見る