さて、前回 は Wicket の入口について書きました。普通だと、これからどんどん使うコンポーネントを増やしていくという流れになると思うのですが…
今回は、いきなりですが国際化をテーマに書きたいと思います!
理由は、国際化がやりづらい場合は自分のフレームワーク候補から消えるから。
個人で使う場合は構わないのですが、業務で使うとなると高い確率で国際化機能が必要になるため、出来ればフレームワークの方で簡単に対処できる方が嬉しいんです。優先度が高い要望なのです。
単に国際化したいだけで、プログラムで実行時に内容を切り替えたりしない文字列であれば、html で wicket:message タグで文字列を囲むことで簡単に実現できます(言語情報を記述したプロパティファイルが別途必要ですけど)。Java 側のコンポーネント記述の方でも何とかできるみたいなんですが、ここは Struts の様にタグだけで済む方が嬉しいので、敢えて調べてません!
具体的には、国際化したい文字列を以下の様に wicket:message タグで囲みます。
<wicket:message key="helloworld">Hello</wicket:message>
すると、上の例の場合 helloworld キーに対応した国際化文字列をプロパティファイルから検索してきて、Hello の代わりに表示してくれます。対応する文字列が見つからなかった場合は、Hello がデフォルトの文字列として表示されます。
タグで囲んだ文字列だけでなく、タグ属性についても国際化できます。
<input type="submit" value="Default text" wicket:message="value:helloworld"/>
wicket:message 属性値を "対象の属性名:キー" とします。上の例の場合、value 属性が helloworld キーに対応する国際化文字列に置き換わるというわけです。見つからなかった場合は、元の文字列を使います。
現在の処理状況表示など、プログラムで表示内容を切り替えたい場合も多いと思います。この様な場合に Java プログラムにて国際化文字列を取得するためには、org.apache.wicket.Component#getString() を使います。
public final java.lang.String getString(java.lang.String key); public final java.lang.String getString(java.lang.String key, IModel model); public final java.lang.String getString(java.lang.String key, IModel model, java.lang.String defaultValue);
なお、上記のメソッドは Component 上で getLocalizer().getString(String key, Component component) を実行するのと同じ様です。getString() で取得した国際化文字列をコンポーネントのモデルに設定してあげれば、動的にコンポーネントの表示内容を変えることができます。
国際化文字列は、多くの Java アプリケーション同様プロパティファイルとして用意します。プロパティファイルは、コンポーネント(Page とか Label とか)単位に作成することができます。それらのファイルの検索順序ですが、Apache Wicket の Wiki あたりで発見した検索の流れと最新版の流れがどうやら違っている様でして…
1.3 での検索順は ここ で紹介されている流れの様です。簡単にまとめると
となります。プロパティファイル名は コンポーネント名{_ロケール}.properties とします。例えば MyLabel に対応するプロパティファイルは MyLabel.properties や MyLabel_ja.properties の様になります。ロケールについては、現在のロケールに該当するファイルを探した後にロケール無しのファイルがデフォルトとして使われます。もっと分かりやすい説明は、ここ や ここ をご参照ください。プロパティファイルの検索順序だけでなく、プロパティファイル内の検索キーに応じた検索順序についても書かれています。
なお、自分が Apache Wicket の Wiki で見つけた順序は
です。
なお、各プロパティファイルは対応するクラスと同じクラスパス階層に存在しないといけないみたいです(実験でしか確認していないため、設定を変える等の方法があるかもしれません)。
現在のロケールですが、クライアントが提供したロケールが自動的に選択されて org.apache.wicket.Session に保存されます。自分で個別に設定したい場合は、WebPage でも使える org.apache.wicket.Component#getSession() を使って、getSession().setLocale(Locale.US) の様に設定できます。また、コンポーネント毎にロケールを変えたい場合は、そのコンポーネントの getLocale() をオーバーライドすることで実現できます。
なお、クライアントがロケール情報を指定しない場合、Java のデフォルトロケールを使用します(Locale.getDefault()/Locale.setDefault() によって操作可能)。
以下に、手動ロケール切り替えのサンプルを載せておきます。
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.model.PropertyModel;
public class I18nPage extends WebPage
{
public I18nPage()
{
Form langForm = new Form("langForm");
add(langForm);
List<Locale> localeList = new ArrayList<Locale>();
localeList.add(Locale.JAPANESE);
localeList.add(Locale.ENGLISH);
DropDownChoice ddcSelectLang =
new DropDownChoice("selectLocale",
new PropertyModel(getSession(), "locale"),
localeList,
new IChoiceRenderer() {
public Object getDisplayValue(Object object) {
Locale locale = (Locale)object;
return locale.getDisplayName(getSession().getLocale());
}
public String getIdValue(Object object, int index) {
return index + "_" + object.toString();
}
}
) {
protected boolean wantOnSelectionChangedNotifications() {
return true;
}
}
};
langForm.add(ddcSelectLang);
}
}
DropDownChoice は、html の select タグに対応しています。モデルに PropertyModel(getSession(), "locale") を使うことで、org.apache.wicket.Session の locale プロパティと、選択した値がバインドされます。これによって、値更新時の処理や表示のための値取得処理を書かなくて済みます。
DropDownChoice#wantOnSelectionChangeNotifications() で true を返すことによって、ドロップダウンボックスの値を変えた際に自動的に submit される様になります。デフォルトでは false を返すため、値をいくら変えても全然ロケールに反映されません。
IChoiceRenderer は、select タグ内の option タグの内容に関係します。getDisplayValue() で返した値が表示され、getIdValue() で返した値が option タグの value 属性として使われます。
<html>
<body>
<form wicket:id="langForm">
<select wicket:id="selectLang">
<option>Japanese(Default)</option>
<option>English(Default)</option>
</select>
</form>
<h1><wicket:message key="title">This text is default value.</wicket:message></h1>
</body>
</html>
title=日本語のタイトル
title=English Title
FC2 Blog Ranking に参加してます。クリックよろしくお願いします!
<<Wicket の勉強 (3) IAuthorizationStrategy を実装して認証/認可を実現する | ホーム | デミオ、修理のために旅立ちました…>>
Author:いちのせ りょう
1974年北海道生まれ、育ちは沖縄/宮崎、で現在は東京在住のSEです。社会人10年目、未だにばりばり作ってます!Rio's Laboratory もよろしく…
性別:男性
車:MAZDA DEMIO
好きな音楽:B'z、The Yellow Monkey、Bon Jovi
好きなゲーム:MGS、Bio Hazard、Zeldaとか
やりたい事:F1観に行きたい、沖縄の海に潜りたい、空を飛びたい