§Internationalization with Messages
§Specifying languages supported by your application
You specify languages for your application using language tags, specially formatted strings that identify a specific language. Language tags can specify simple languages, such as “en” for English, a specific regional dialect of a language (such as “en-AU” for English as used in Australia), a language and a script (such as “az-Latn” for Azerbaijani written in Latin script), or a combination of several of these (such as “zh-cmn-Hans-CN” for Chinese, Mandarin, Simplified script, as used in China).
To start you need to specify the languages supported by your application in the conf/application.conf
file:
play.i18n.langs = [ "en", "en-US", "fr" ]
These language tags will be validated used to create Lang
instances. To access the languages supported by your application, you can inject a Langs
instance into your component.
§Externalizing messages
You can externalize messages in the conf/messages.xxx
files.
The default conf/messages
file matches all languages. You can specify additional language messages files, such as conf/messages.fr
or conf/messages.en-US
.
You can retrieve messages for the current language using the play.i18n.Messages
object:
// Dependency inject with @Inject() public MyClass(MessagesApi messagesApi) { ... }
Collection<Lang> candidates = Collections.singletonList(new Lang(Locale.US));
Messages messages = messagesApi.preferred(candidates);
String message = messages.at("home.title");
The current language is found by looking at the lang
field in the current Context
. If there’s no current Context
then the default language is used. The Context
’s lang
value is determined by:
- Seeing if the
Context
’slang
field has been set explicitly. - Looking for a
PLAY_LANG
cookie in the request. - Looking at the
Accept-Language
headers of the request. - Using the application’s default language.
You can change the Context
’s lang
field by calling changeLang
or setTransientLang
. The changeLang
method will change the field and also set a PLAY_LANG
cookie for future requests. The setTransientLang
will set the field for the current request, but doesn’t set a cookie. See below for example usage.
If you don’t want to use the current language you can specify a message’s language explicitly:
String title = messagesApi.get(Lang.forCode("fr"), "hello");
Note that you should inject the play.i18n.MessagesApi
class, using dependency injection. For example, using Guice you would do the following:
public MyClass {
@javax.inject.Inject
public MyClass(play.i18n.MessagesApi messagesApi) { ... }
}
§Use in Controllers
If you are in a Controller, you get the Messages
instance through Http.Context
, using Http.Context.current().messages()
:
public Result index() {
Messages messages = Http.Context.current().messages();
String hello = messages.at("hello");
return ok(hellotemplate.render());
}
§Use in templates
Once you have the Messages object, you can pass it into the template:
@(messages: play.i18n.Messages)
@messages.at("hello")
You can also use the Scala Messages
object from within templates. The Scala Messages
object has a shorter form that’s equivalent to messages.at
which many people find useful.
If you use the Scala Messages
object remember not to import the Java play.i18n.Messages
class or they will conflict!
@Messages("hello")
Localized templates that use messages.at
or the Scala Messages
object are invoked like normal:
public Result index() {
return ok(hellotemplate.render()); // "hello"
}
If you want to change the language for the template you can call changeLang
on the current Context
. This will change the language for the current request, and set the language into a cookie so that the language is changed for future requests:
public Result index() {
ctx().changeLang("fr");
return ok(hellotemplate.render()); // "bonjour"
}
If you just want to change the language, but only for the current request and not for future requests, call setTransientLang
:
public Result index() {
ctx().setTransientLang("en-US");
return ok(hellotemplate.render()); // "howdy"
}
§Formatting messages
Messages are formatted using the java.text.MessageFormat
library. For example, if you have defined a message like this:
files.summary=The disk {1} contains {0} file(s).
You can then specify parameters as:
Messages.get("files.summary", d.files.length, d.name)
§Notes on apostrophes
Since Messages uses java.text.MessageFormat
, please be aware that single quotes are used as a meta-character for escaping parameter substitutions.
For example, if you have the following messages defined:
info.error=You aren''t logged in!
example.formatting=When using MessageFormat, '''{0}''' is replaced with the first parameter.
you should expect the following results:
String errorMessage = messages.at("info.error");
Boolean areEqual = errorMessage.equals("You aren't logged in!");
String errorMessage = messages.at("example.formatting");
Boolean areEqual = errorMessage.equals("When using MessageFormat, '{0}' is replaced with the first parameter.");
§Retrieving supported languages from an HTTP request
You can retrieve a specific HTTP request’s supported languages:
public static Result index() {
return ok(request().acceptLanguages());
}
Next: Dependency Injection