|Home > Guides > Core Developers Guide > Localization|
The framework supports internationalization (i18n) in the following places:
Resource bundles are searched in the following order:
Interface.properties (every interface and sub-interface)
BaseClass.properties (all the way to Object.properties)
This is how it is implemented in a default implementation of the
LocalizedTextProvider interface. You can provide your own implementation using
To clarify #5, while traversing the package hierarchy, Struts 2 will look for a file package.properties:
FooAction.properties does not exist,
com/acme/action/package.properties will be searched for, if not found
com/acme/package.properties, if not found
If you configure action as follow
it will use a default class defined with
struts-default.xml which is
com.opensymphony.xwork2.ActionSupport. It means you have two options here to get I18N working in that case:
com/opensymphony/xwork2/ActionSupport.propertiesand put messages there
default-class-refto your base class and then defined appropriated
.propertiesfile (corresponding to class' name or package)
There are several ways to access the message resources, including
text tag, and the
getTextfrom a Tag
To display i18n text, use a call to
getText in the property tag, or any other tag, such as the UI tags. (The
getText technique is especially useful for labels of UI tags.)
The default implementation of
TextProvider which is used in
ActionSupport perform evaluation of value read from bundle base on the provided key, see Localizing Output for an example.
The text tag retrieves a message from the default resource bundle.
The i18n tag pushes an arbitrary resource bundle on to the value stack. Other tags within the scope of the i18n tag can display messages from that resource bundle.
Internationalizing SiteMesh decorators is possible, but there are quirks. See SiteMesh Plugin for more.
The key attribute of most UI tags can be used to retrieve a message from a resource bundle:
Essentially, the i18n Interceptor pushes a locale into the ActionContext map upon every request. The framework components that support localization all utilize the ActionContext locale. See I18n Interceptor for details.
A global resource bundle could be specified programmatically, as well as the locale.
See Formatting Dates and Numbers for more details and examples.
Struts 1 users should be familiar with the application.properties resource bundle, where you can put all the messages in the application that are going to be translated. Struts 2, though, splits the resource bundles per action or model class, and you may end up with duplicated messages in those resource bundles. A quick fix for that is to create a file called ActionSupport.properties in com/opensymphony/xwork2 and put it on your classpath. This will only work well if all your actions subclass XWork2's ActionSupport.
If you want use a different logic to search for localized messages, or you want to use a database or just want to search default bundles, you must implement both those interfaces (or subclass the existing implementations). You can check a small example app how to use both. Please remember that the
TextProvider interface is implemented by the
ActioSupport class, that's why an extra layer -
TextProviderFactory - is needed.