Serving content in several languages

Play comes with handy support for internationalization so that you can define the messages of your application in several languages and automatically select the language to use according to the user preferences (as defined by the Accept-Language request header).

When a user performs a request to a server from his web browser, this one usually sets an Accept-Language header according to the user preferences. For instance, in my case, it is the following:

Accept-Language:en,en-US;q=0.8,fr;q=0.6,fr-FR;q=0.4

This means that the language I prefer to read is English and then French. The preference level is defined by the q factor. If there is no q factor associated with a language (for instance, en, in the preceding code), its value defaults to 1 (highest preference).

So, when I request a page, the server should serve the English version of the page if it has one, or the French version. This means that the server has to choose, among the languages it supports, the one that fits best its client.

In a Play application, you can define which languages are supported in the conf/application.conf file, using their ISO 639-2 language code (optionally followed by an ISO 3166-1 alpha-2 country code):

application.langs="en,fr"

The preceding line of code specifies that the application supports both English and French. This information is used by Play to determine which language to use for each request; it takes the request's accepted languages in decreasing order of preference and selects the first that is supported by the application. If the application does not support any of the request's accepted languages, then Play selects the first language supported by the application (in this case, en).

Note that if a client specifies that he accepts a language without setting a country code and you defined that your application supports this language refined with a country code, your language still satisfies his language. However, the inverse is not true. For example, if a client accepts the language fr and you support just fr-FR, this is fine because fr-FR satisfies fr. Inversely, fr does not satisfy fr-FR.

Once this language has been determined, it is used to find the corresponding translation of each message in the application. Indeed, all the messages in an internationalized application should be defined in the conf/messages.xx-yy files, where xx is a language code and yy is an optional country code. These files contain a list of messages defined as a key-value pair. For instance, our application's index page displays the message Just Play Scala (or Just Play Java). In order to display Juste Play Scala (or Juste Play Java) to French users, we have to do the following.

First, create the conf/messages.fr and conf/messages.en files and define a message named index in both files:

# file messages.fr
index=Juste Play Scala
# file messages.en
index=Just Play Scala

Then, in the app/views/main.scala.html template, replace occurrences of the message content with the @Message("index") expression. The whole template should look like the following:

<!DOCTYPE html>
<html>
    <head>
        <title>@Messages("index")</title>
    </head>
    <body>
        <h1>@Messages("index")</h1>
    </body>
</html>

The Messages function looks for a translation of a message given its key. It determines which language the message should be translated into by using an implicit Lang parameter, so your template also have to take an implicit Lang parameter:

@()(implicit lang: Lang)

Note that this is not required in Java because the current language is automatically imported from the current HTTP context. Also note that within a controller, an implicit Lang parameter is automatically provided if there is an implicit RequestHeader header in the scope.

The translation search algorithm allows you to define default translations for your messages and refine them for some languages or countries. It first searches in the conf/messages.xx-yy file, where xx-yy is the selected language, which contains a language code and country code. Then, it falls back to a conf/messages.xx file. Then, it finally falls back to a conf/messages file. If none of these files provide a translation, the message key is returned.

Note that the last file, conf/messages, is used to search the message's translations regardless of the selected language. You can use it to provide default messages in the language of your choice in case your application is only partially translated.

When a user tries to authenticate with an unknown name, we can produce this error message: Unknown user: <name>, where <name> is the username. The French version will be Utilisateur inconnu : <name>. Translations can be parameterized. They use the java.text.TextFormat syntax:

authentication.unknown=Unknown user: {0}

To get a translation of the authentication.unknown message, you have to supply one parameter:

Messages("authentication.unknown", username)

When retrieving a translation from Java code (which is not the case in HTML templates), you have to use the Messages.get static method:

import play.i18n.Messages;
Messages.get("authentication.unknown", username);
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.19.174