Ymirではアプリケーションの国際化のための仕組みとして、ロケール情報の管理機能とメッセージリソース機能を持っています。
ロケール情報の管理機能
Ymirではアプリケーション利用者毎にロケールを持たせるための仕組みをフレームワークとして提供しています。
ロケールの操作にはLocaleManagerを用います。LocaleManagerは特に設定をしなくてもPageクラス等から利用できますが、app.diconに登録されているアプリケーション用コンポーネントからLocaleManagerを利用したい場合は、app.diconからymir-component.diconをインクルードしておいて下さい。
LocaleManagerを利用したいコンポーネントには、org.seasar.ymir.LocaleManagerのためのSetterを用意しておけばLocaleManagerコンポーネントが自動的にインジェクトされます。
利用者に関連付けられているロケールを取得するには、org.seasar.ymir.Request#getLocale()を使うか、org.seasar.ymir.LocaleManager#getLocale()を使います。
現在のセッションにロケールを関連付けるためには、org.seasar.ymir.LocaleManager#setLocale(Locale)を使います。
現在のセッションに関連付けられているロケールを削除するには、org.seasar.ymir.LocaleManager#removeLocale()を使います。
なお、LocaleManagerはメッセージリソースから適切なメッセージを取り出す処理などでYmirの内部からも利用されますので、アプリケーションでは基本的にはLocaleManagerを使ってロケールの管理をするようにして下さい。
メッセージリソース機能
メッセージリソースとは、Strutsのメッセージリソースと同様のもので、ロケールごとのプロパティを扱うための仕組みです。
メッセージリソースは、次のようにして利用されます。
- バリデーションエラーなどのエラーメッセージを格納するNotesオブジェクトから実際のメッセージ文字列を構築する
- ZPTテンプレート中にメッセージリソースのキーを指定したTALES式を埋め込むことで、メッセージ文字列を表示する
- Pageクラスなどからメッセージリソースを明示的に取得してメッセージ文字列を構築する
メッセージリソースを管理する実体は、org.seasar.ymir.Messagesの実装クラスのシングルトンコンポーネントです。
ymir-skeletonで登録されるデフォルトのMessagesコンポーネント実装では、クラスパス上のmessages_XXX.xproperties(XXXはロケール名。なおこのファイルのソースはsrc/main/resources/ディレクトリ直下にあります)というロケール毎のファイルに格納されたリソースがメッセージリソースとして使われるようになっています。
xpropertiesファイルの書式は基本的に通常のJavaのプロパティファイルと同じですが、UTF-8で直接非ASCII文字を記述することができます。
Notesオブジェクトを使ったメッセージ文字列の構築
例えば、PageクラスのgetNotes()メソッドが返すNotesオブジェクトから現在のロケールに従ったメッセージ文字列を表示するには、ZPTテンプレート中で次のように書きます。
<ul> <li tal:repeat="note self/notes/notes" tal:content="note/%value">メッセージ</li> </ul>
Noteオブジェクトを格納する変数「note」について「note/%value」と書くと、現在のロケールに従ったメッセージ文字列がMessagesコンポーネントから取り出され、Noteがパラメータを持つ場合はパラメータが埋め込まれてメッセージ文字列が構築されて表示されます。
詳しくは「ZPTテンプレート」の「セグメントの解釈」の表のNoteに関する項目を参照して下さい。
- バリデーションエラーなどのエラーメッセージを格納するNotesオブジェクトから実際のメッセージ文字列を構築する
- ZPTテンプレート中にメッセージリソースのキーを指定したTALES式を埋め込むことで、メッセージ文字列を表示する
- Pageクラスなどからメッセージリソースを明示的に取得して利用する
メッセージキーを直接指定したメッセージ文字列の構築
例えば、メッセージキー「message.ok」に対応する現在のロケールに応じたメッセージ文字列を表示するには、ZPTテンプレート中で次のように書きます。
<span tal:replace="messages/%message.ok">メッセージ</span>
なお、この方法ではパラメータの埋め込みはできません。
ロケールによらずデフォルトのメッセージを表示したい場合は次のように「%」をつけずに書いて下さい。
<span tal:replace="messages/message.ok">メッセージ</span>
詳しくは「ZPTテンプレート」の「セグメントの解釈」の表のMessagesに関する項目を参照して下さい
プログラムコードにおけるメッセージ文字列の構築
プログラム中でメッセージ文字列を構築するには、メッセージリソースを管理するMessagesコンポーネントを取得して利用します。Pageクラス等から利用する場合は特に設定は不要ですが、app.diconに登録されているアプリケーション用コンポーネントからMessagesコンポーネントを利用したい場合は、app.diconからymir-component.diconをインクルードしておいて下さい。
このコンポーネントを利用したいクラスでMessagesクラスを引数に持つSetterメソッドを用意するだけで、自動的にMessagesコンポーネントがインジェクトされます。後はMessagesインタフェースの提供メソッドを呼び出してメッセージ文字列を構築することができます。
メッセージ文字列の取得には、Messages#getMessage(String key)を使って下さい。指定したキーに対応するメッセージ文字列のうち、現在のロケールに合うものが返されます。
ページ固有のメッセージ文字列の探索
Ymirでは、あるキーに対応するメッセージをページ毎に変えることができるようになっています。具体的には、指定されたキーからページ固有のキーを生成し、そのキーに対応するメッセージ文字列を使用するようになっています。見つからない場合は、指定されたキーそのものに対応するメッセージ文字列が使用されます。
ページ固有のキーは、次のルールに従って生成されます。
- キーがドットを含まない場合、ページのコンポーネント名(またはページのコンポーネント名の末尾から「Page」を取り除いたもの)とキーをドット区切りで連結したもの
- キーがドットを含む場合、キーのドットより前の部分とページのコンポーネント名(またはページのコンポーネント名の末尾から「Page」を取り除いたもの)とキーのドットより後ろの部分をドット区切りで連結したもの
例えば「/index.html」ページ(コンポーネント名はindexPage)の場合はページ固有のキーは以下のようになります:
pageTitle -> indexPage.pageTitle, index.pageTitle label.userName -> label.indexPage.userName, label.index.userName message.action.succeed -> message.indexPage.action.succeed, message.index.action.succeed
キーの探索順序は以下のようになります:
indexPage.pageTitle -> index.pageTitle -> pageTitle
上記のようなメッセージ文字列探索が行なわれるのは、以下の場合です。
- バリデーションエラーなどのエラーメッセージを格納するNotesオブジェクトから実際のメッセージ文字列を構築する場合
- ZPTテンプレート中にメッセージリソースのキーを「%」つきで指定したTALES式を埋め込むことで、メッセージ文字列を表示する場合
- Messages#getMessage(String)を使用してメッセージ文字列を取得する場合
画像の国際化
画像をロケールに従って切り替えたい場合は、TALESのi18npage式を使います。例えば/image/title.jpgという画像をロケール毎に切り替えたい場合は以下のように記述します:
<img tal:attributes="src i18npage:/image/title.jpg" src="/image/title.jpg" />