Internationalization
Easily support multiple locales with a single code base.
Contents
- Overview Easily support multiple locales with a single code base.
- Static String Internationalization A type-safe and optimized approach to internationalizing strings.
- Dynamic String Internationalization A flexible and simplistic method of internationalizing strings that easily integrates with existing web applications that do not support the GWT
locale
client property. - Specifying a Locale How to add locales and specify the
locale
client property during deployment. - Localized Properties Files How to create localized properties files for use with Constants or Messages
Overview
Getting Started
Since GWT supports a variety of ways of internationalizing your code, begin by researching which approach best matches your development requirements. Are you writing code from scratch?
If so, you'll probably want to read up on GWT's static string internationalization techniques.
Do you want to internationalize mostly settings or end-user messages?
If you have mostly settings (the kind of thing for which you'd normally use simple properties files), consider Constants. If you have a lot a of end-user messages, then Messages is probably what you want.
Do you have existing localized properties files you'd like to reuse?
The i18nCreator tool can automatically generate interfaces that extend either Constants or Messages.
Are you adding GWT functionality to an existing web application that already has a localization process defined?
Dictionary will help you interoperate with existing pages without requiring you to use GWT's concept of locale.
Do you really just want a simple way to get properties files down to the client regardless of localization?
You can do that, too. Try using Constants without specifying a locale.
Internationalization Techniques
GWT offers multiple internationalization techniques to afford maximum flexibility to GWT developers and to make it possible to design for efficiency, maintainability, flexibility, and interoperability in whichever combinations are most useful.Static string internationalization refers to a family of efficient and type-safe techniques that rely on strongly-typed Java interfaces, properties files, and code generation to provide locale-aware messages and configuration settings. These techniques depend on the interfaces Constants and Messages.
At the other end of the spectrum, dynamic string internationalization is a simplistic and flexible technique for looking up localized values defined in a module's host page without needing to recompile your application. This technique is supported by the class Dictionary.
Using an approach similar to static string internationalization, GWT also supports internationalizing sets of algorithms using locale-sensitive type substitution. This is an advanced technique that you probably will not need to use directly, although it is useful for implementing complex internationalized libraries. For details on this technique, see Localizable.
The I18N Module
The core types related to internationalization reside in thecom.google.gwt.i18n
package: - ConstantsUseful for localizing typed constant values
- MessagesUseful for localizing messages requiring arguments
- ConstantsWithLookupLike Constants but with extra lookup flexibility for highly data-driven applications
- DictionaryUseful when adding a GWT module to existing localized web pages
- LocalizableUseful for localizing algorithms encapsulated in a class
The GWT internationalization types are included in the module com.google.gwt.i18n.I18N
. To use any of these types, your module must inherit from it:
Static String Internationalization
For example, if you wanted to localize the constant strings "hello, world" and "goodbye, world" in your GWT application, you could define an interface that abstracts those strings by extending the built-in Constants
interface:
public interface MyConstants extends Constants {Now create an associated default properties file called
String helloWorld();
String goodbyeWorld();
}
MyConstants.properties
in the same package: helloWorld = hello, worldYou can also create a localized translation for each supported locale in separate properties file. In this case, we localize for Spanish:
goodbyeWorld = goodbye, world
helloWorld = hola, mundoTo use the internationalized constants, you create an implementation of
goodbyeWorld = adiĆ³s, mundo
MyConstants
using GWT.create(Class): public void useMyConstants() {
MyConstants myConstants = (MyConstants) GWT.create(MyConstants.class);
Window.alert(myConstants.helloWorld());
}
The Benefits of Static String Internationalization
As you can see from the example above, static internationalization relies on a very tight binding between internationalized code and its localized resources. Using explicit method calls in this way has a number of advantages. The GWT compiler can optimize deeply, removing uncalled methods and inlining localized strings -- making generated code as efficient as if the strings had been hard-coded.The value of compile-time checking becomes even more apparent when applied to messages that take multiple arguments. Creating a Java method for each message allows the compiler to check both the number and types of arguments supplied by the calling code against the message template defined in a properties file. For example, attempting to use this interface:
public interface ErrorMessages extends Messages {with this properties file:
String permissionDenied(int errorCode, String username);
}
permissionDenied = Error {0}: User {1} does not have permission to access {2}results in a compile-time error because the message template in the properties file expects three arguments, while the
permissionDenied
method can only supply two. Which Interface to Use?
ExtendConstants
to create a collection of constant values of a variety of types that can be accessed by calling methods (called constant accessors) on an interface. Constant accessors may return a variety of types, including strings, numbers, booleans, and even maps. A compile-time check is done to ensure that the value in a properties file matches the return type declared by its corresponding constant accessor. In other words, if a constant accessor is declared to return an int
, its associated property is guaranteed to be a valid int
value -- avoiding a potential source of runtime errors. ConstantsWithLookup
is identical to Constants
except that the interface also includes a method to look up strings by property name, which facilitates dynamic binding to constants by name at runtime. ConstantsWithLookup
can sometimes be useful in highly data-driven applications. One caveat: ConstantsWithLookup
is less efficient than Constants
because the compiler cannot discard unused constant methods, resulting in larger applications.
Extend Messages
to create a collection of formatted messages that can accept parameters. You might think of the Messages
interface as a statically verifiable equivalent of the traditional Java combination of Properties
, ResourceBundle
, and MessageFormat
rolled into a single mechanism.
Properties Files
All of the types above use properties files based on the traditional Java properties file format, although GWT uses an enhanced properties file format that are encoded as UTF-8 and can therefore contain Unicode characters directly.Dynamic String Internationalization
Since it binds directly to the key/value pairs in the host HTML, whatever they may be, the Dictionary class is not sensitive to the the GWT locale setting. Thus, the burden of generating localized strings is on your web server.
Dynamic string localization allows you to look up localized strings defined in a host HTML page at runtime using string-based keys.This approach is typically slower and larger than the static string approach, but does not require application code to be recompiled when messages are altered or the set of locales changes.
Specifying a Locale
locale
as a client property whose value can be set either using a meta tag embedded in the host page or in the query string of the host page's URL. Rather than being supplied by GWT, the set of possible values for the locale
client property is entirely a function of your module configuration. If that sounded like gibberish (and it probably did), a quick digression into the purpose of client properties is in order...
Client Properties and the GWT Compilation Process
Client properties are key/value pairs that can be used to configure GWT modules. User agent, for example, is represented by a client property. Each client property can have any number of values, but all of the values must be enumerable when the GWT compiler runs. GWT modules can define and extend the set of available client properties along with the potential values each property might assume when loaded in an end user's browser. At compile time, the GWT compiler determines all the possible permutations of a module's client properties, from which it produces multiple compilations. Each compilation is optimized for a different set of client properties and is recorded into a file ending with the suffix .cache.html
.
In deployment, the end-user's browser only needs one particular compilation, which is determined by mapping the end user's client properties onto the available compiled permutations. Thus, only the exact code required by the end user is downloaded, no more. By making locale a client property, the standard startup process in gwt.js
chooses the appropriate localized version of an application, providing ease of use (it's easier than it might sound!), optimized performance, and minimum script size.
The Default Locale
Thecom.google.gwt.i18n.I18N
module defines only one locale by default, called default
. This default locale is used when the locale
client property goes unspecified in deployment. The default locale is used internally as a last-resort match between a Localizable interface and a localized resource or class. Adding Locale Choices to a Module
In any real-world application, you will define at least one locale in addition to the default locale. "Adding a locale" means extending the set of values of thelocale
client property using the
element in your module XML. For example, the following module adds multiple locale values:
Choosing a Locale at Runtime
The locale client property can be specified using either a meta tag or as part of the query string in the host page's URL. If both are specified, the query string takes precedence. To specify the locale
client property using a meta tag in the host page, embed a meta tag for gwt:property
as follows:
To specify the locale
client property using a query string, specify a value for the name locale
. For example,
http://www.example.org/myapp.html?locale=fr_CA
Localized Properties Files
native2ascii
. See the API documentation for the above interfaces for examples and formatting details. Many thanks to the Tapestry project for solving the problem of reading UTF-8 properties files in Tapestry's LocalizedProperties
class.
0 comments:
Post a Comment