Grails supports Internationalization (i18n) out of the box through the underlying Spring MVC support for internationalization. With Grails you are able to customize the text that appears in any view based on the users Locale. To quote the javadoc for the
Locale class in Java:
A Locale object represents a specific geographical, political, or cultural region. An operation that requires a Locale to perform its task is called locale-sensitive and uses the Locale to tailor information for the user. For example, displaying a number is a locale-sensitive operation--the number should be formatted according to the customs/conventions of the user's native country, region, or culture.
A Locale is made up of a
language code and a
country code. For example "en_US" is the code for US english, whilst "en_GB" is the for British English.
Now that you have an idea of locales, to take advantage of them in Grails you have to create message bundles that contain the different languages that you wish to render. Message bundles in Grails are located inside the
grails-app/i18n
directory and are simple Java properties files.
Each bundle starts with the name
messages
by convention and ends with the locale. Grails ships with a bunch of built in message bundles for a whole range of languages within the
grails-app/i18n
directory. For example:
messages.properties
messages_de.properties
messages_es.properties
etc.
By default Grails will look in
messages.properties
for messages, unless the user has specified a custom locale. You can create your own message bundle by simply creating a new properties file that ends with the locale you are interested. For example
messages_en_GB.properties
for British English.
By default the user locale is detected from the incoming
Accept-Language
header. However, you can provide users the capability to switch locales by simply passing a parameter called
lang
to Grails as a request parameter:
Grails will automatically switch the user locale and store it in a cookie so subsequent requests will have the new header.
Reading Messages in the View
The most common place that you need messages is inside the view. To read messages from the view just use the
message tag:
<g:message code="my.localized.content" />
As long as you have a key in your
messages.properties
(with appropriate locale suffix) such as the one below then Grails will look-up the message:
my.localized.content=Hola, Me llamo John. Hoy es domingo.
Note that sometimes you may need to pass arguments to the message. This is also possible with the
message
tag:
<g:message code="my.localized.content" args="${ ['Juan', 'lunes'] }" />
And then use positional parameters in the message:
my.localized.content=Hola, Me llamo {0}. Hoy es {1}.
Reading Messages in Controllers and Tag Libraries
Since you can invoke tags as methods from controllers it is also trivial to read messages within in a controller:
def show = {
def msg = message(code:"my.localized.content", args:['Juan', 'lunes'])
}
The same technique can be used on
tag libraries, but note if your tag library has a different
namespace then you will need to
g.
prefix:
def myTag = { attrs, body ->
def msg = g.message(code:"my.localized.content", args:['Juan', 'lunes'])
}
Grails does not ship with i18n aware
scaffolding templates to generate the controller and views. However, i18n aware templates are available via the i18n templates plugin. The templates are identical to the default scaffolding templates, except that they are i18n aware using the
message tag for labels, buttons etc.
To get started install the i18n templates with the following command:
grails install-plugin i18n-templates
Then refer to the
reference on the wiki which explains how to use the i18n templates.