Easily support multiple locales with a single code base.
locale client property.locale client
property during deployment.
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.
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.
com.google.gwt.i18n package:
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:
<!-- --> <!-- Copyright 2007 Google Inc. --> <!-- Licensed under the Apache License, Version 2.0 (the "License"); you --> <!-- may not use this file except in compliance with the License. You may --> <!-- may obtain a copy of the License at --> <!-- --> <!-- http://www.apache.org/licenses/LICENSE-2.0 --> <!-- --> <!-- Unless required by applicable law or agreed to in writing, software --> <!-- distributed under the License is distributed on an "AS IS" BASIS, --> <!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or --> <!-- implied. License for the specific language governing permissions and --> <!-- limitations under the License. --> <module> <!-- other inherited modules, such as com.google.gwt.user.User --> <inherits name="com.google.gwt.i18n.I18N"/> <!-- additional module settings --> </module>
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 {
String helloWorld();
String goodbyeWorld();
}
Now create an associated default properties file called
MyConstants.properties in the same package:
helloWorld = hello, world goodbyeWorld = goodbye, worldYou can also create a localized translation for each supported locale in separate properties file. In this case, we localize for Spanish:
helloWorld = hola, mundo goodbyeWorld = adiós, mundoTo use the internationalized constants, you create an implementation of
MyConstants using GWT.create(Class):
public void useMyConstants() {
MyConstants myConstants = (MyConstants) GWT.create(MyConstants.class);
Window.alert(myConstants.helloWorld());
}
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 {
String permissionDenied(int errorCode, String username);
}
with this properties file:
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.
Constants 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.
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.
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...
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.
com.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.
locale client property using the
<extend-property> element in your
module XML.
For example, the following module adds multiple locale values:
<!-- --> <!-- Copyright 2007 Google Inc. --> <!-- Licensed under the Apache License, Version 2.0 (the "License"); you --> <!-- may not use this file except in compliance with the License. You may --> <!-- may obtain a copy of the License at --> <!-- --> <!-- http://www.apache.org/licenses/LICENSE-2.0 --> <!-- --> <!-- Unless required by applicable law or agreed to in writing, software --> <!-- distributed under the License is distributed on an "AS IS" BASIS, --> <!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or --> <!-- implied. License for the specific language governing permissions and --> <!-- limitations under the License. --> <module> <inherits name="com.google.gwt.user.User"/> <inherits name="com.google.gwt.i18n.I18N"/> <!-- French language, independent of country --> <extend-property name="locale" values="fr"/> <!-- French in France --> <extend-property name="locale" values="fr_FR"/> <!-- French in Canada --> <extend-property name="locale" values="fr_CA"/> <!-- English language, independent of country --> <extend-property name="locale" values="en"/> </module>
To specify the locale client property using a meta tag in
the
host page,
embed a meta tag for gwt:property as follows:
<meta name="gwt:property" content="locale=x_Y">For example, the following host HTML page sets the locale to "ja_JP":
<html>
<head>
<meta name="gwt:module" content="com.google.gwt.examples.i18n.ColorNameLookupExample">
<meta name="gwt:property" content="locale=ja_JP">
</head>
<body>
<script src="gwt.js"></script>
</body>
</html>
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
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.