...
Localization (aka L10n) is all about getting the right text to the user, in the right language.
Div | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
|
Localization support is well integrated into Tapestry. Tapestry allows you to easily separate the text you present to your users from the rest of your application ... pull it out of your Java code and even out of your component templates. You can then translate your messages into other languages and let Tapestry put everything together.
...
Individual pages and components can override the values defined in the message catalog.{float:right|width=45%} {note:title=Avoid BOMs}
Warning | ||
---|---|---|
| ||
Make sure that your properties files don't contain |
...
...
, because Java – and thus Tapestry – doesn't support BOM in properties files ( |
...
see http://bugs.sun.com/view_bug.do?bug_id=4508058). Some editors write them out when saving a file in UTF-8, so watch out. |
{note} {float}
Properties File Charset
Tapestry uses the UTF-8
character set (charset) when reading the properties files in a message catalog. This means that you don't have to use the Java native2ascii
tool.
...
- Using the "message:" binding expression in a component template
- By injecting the component's Messages object
In the first case, you may use the message: binding prefix with component parameters, or with template expansions:
Code Block | ||||
---|---|---|---|---|
| ||||
<t:layout title="message:page-title"> ${message:greeting}, ${user.name}! . . . </t:layout> |
Here, the page-title
message is extracted from the catalog and passed to the Border component's title parameter.
...
You would extend this with a set of properties files:
Code Block | ||||
---|---|---|---|---|
| ||||
page-title=Your Account greeting=Welcome back |
Or, perhaps, a French version:
Code Block | ||||
---|---|---|---|---|
| ||||
page-title=Votre Compte greeting=Bienvenue en arriere |
Programatically, you may inject your component message catalog into your class, as an instance of the Messages interface:
Code Block | ||||
---|---|---|---|---|
| ||||
@Inject private Messages messages; |
You could then get()
messages, or format()
them:
Code Block | ||||
---|---|---|---|---|
| ||||
public String getCartSummary() { if (items.isEmpty()) return messages.get("no-items"); return messages.format("item-summary", _items.size()); } |
The format() option works using a java.util.Formatter
, with all the printf-style loveliness you've come to expect:
Code Block | ||||
---|---|---|---|---|
| ||||
no-items=Your shopping cart is empty. item-summary=You have %d items in your cart. |
As easy as conditionals are to use inside a Tapestry template, sometimes it's even easier to do it in Java code.
...
If you change a property file in a message catalog, you'll see the change immediately, just as with component classes and component templates (provided you're not running in production mode).
Asset Localization
When injecting assets, the injected asset will be localized as well. A search for the closest match for the active locale is made, and the final Asset will reflect that.
...
The PersistentLocale service can be used to programmatically override the locale. Note: You should be careful to only set the persistent locale to a supported locale.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Inject private PersistentLocale persistentLocale; void onActionFromLocaleToggle() { if ("en".equalsIgnoreCase(persistentLocale.get().getLanguage())) { persistentLocale.set(new Locale("de")); } else { persistentLocale.set(new Locale("en")); } return this; } public String getDisplayLanguage() { return persistentLocale.get().getDisplayLanguage(); } |
Once a persistent locale is set, you will see the locale name as the first virtual folder in page render and component event requests URLs. In this way, a persistent locale will, in fact, persist from request to request, or in a user's bookmarks.
...
en (English) | el (Greek) | it (Italian) | pl (Polish) | sv (Swedish) |
bg (Bulgarian) | es (Spanish) | ja (Japanese) | pt (Portuguese) | vi (Vietnamese) |
cs (Czech)1 | fi (Finnish) | mk (Macedonian) | ru (Russian) | zh (Chinese) |
da (Danish) | fr (French) | nl (Dutch) | sl (Slovenian)2 |
|
de (German) | hr (Croatian) | no (Norwegian) | sr (Serbian) |
|
1 as of Tapestry 5.3.8
2 as of Tapestry 5.4
Providing translations for Tapestry built-in messages
Fortunately, Tapestry uses all the same mechanisms for its own locale support as it provides for your application. So, to support other locales, just translate the built-in message catalog (property) files yourself:
...
HTML |
---|
<style type="text/css">table.sectionMacro { width: auto; }</style> |
Section | |||||||
---|---|---|---|---|---|---|---|
| |||||||
|
To have Tapestry use these new files, just put them in the corresponding package-named directory within your own app (for example, src/main/resources/org/apache/tapestry5/core.properties).
Finally, please open a new feature request here and attach the translated files so that they can be included in the next release of Tapestry.
Info |
---|
Please note that a patch is always preferred over an archive of properties files. |
Scrollbar |
---|