In last article we discussed how to localize mark-up files in wicket. It would be very annoying having 14 different html files if we have 14 different languages that we should support for that particular page/component.
In this article we are going to learn how to use resource bundles instead of localizing mark-up files. Imagine your application contains so many texts that need i18n. In this situation it is very difficult to put a wicket:id on all of these, and then add a Label to each.
Wicket provides a simple way to provide i18n support for your applications.
You can use the wicket:message element in the HTML file directly
<wicket:message key=”staticMessage” >Message</wicket:message>
The property files are
DisplayPage.properties:
staticMessage= Message
For Germany
DisplayPage_de.properties:
staticMessage= Nachricht
For Netherland
DisplayPage_nl.properties:
staticMessage= Bericht
The key “staticMessage” is used to lookup the message in the property files. The default text Message is used when the message could not be found. Wicket framework provides getString(String key) method in Component class which search for a property by given key in resource bundles.
Localized pages and panel can have their own bundle files having as base name the class name of the related component and placed in the same package.
So in our example we have DisplayPage.java class. We have created our resource bundles based on name of this class for. E.g DisplayPage_de.properties. Note all these resource files are located in same place where out DisplayPage.java class resides.
Alternatively if you want to use text from properties file in wicket components like labels etc. simply use getString(“key”) method provided by Component class in wicket.
How lookup algorithm works:
Wicket will search all resource files with the names equal to the components in your component hierarchy, starting from application level at top to component defaults as a last place to look.
So when Wickets wants to look up a message used in MyPanel, where MyPanel is contained within MyPage, and the application is called MyApplication,
Wicket will look in:
- MyApplication_locale.properties, …, and then MyApplication.properties (..)
- MyPage_locale.properties, …, and then MyPage.properties
- MyPanel_locale.properties, …, and then MyPanel.properties
And what if it has same key in all these hierarchy properties files?
The lookup algorithm gives priority to the bundles of the containers (parents) of the component that is requesting a localized resource. The more a container is higher in the hierarchy, the bigger is its priority over the other components. In other words properties inside the resource bundle of a page will have the priority over the properties with the same key defined in the bundles of children components.
So for example in our sample code if we have HomePage which is container for DisplayPage, have a property with same key i.e. staticMessage with some other value in its resource bundle then it will be displayed instead of property in DisplayPage resource bundles. HomePage.properties staticMessage= Title Message.
So here text “Title Message” will be displayed instead of DisplayPage.
Also note that for DisplayPage component DisplayPage.properties is a default resource bundle.
So for e.g. your locale is set to “de” and there is no resource bundle for that locale (DisplayPage_de.properties is missing) then lookup algorithm will fall back to default resource bundle in this case DisplayPage.properties
To display languages like Chinese, Japanese etc, which need UTF-8 encoding you need to just append resource bundles with .utf8.properties extension.
Finally how to change locale?
To manually switch the locale in wicket:
Session.get().setLocale(new Locale(Locale.GERMAN));
Isn’t it pretty easy to i18n wicket applications. 🙂
A complete source code for sample example could be found here.