/book/list?lang=es
16 Internationalization
Version: 4.1.0
Table of Contents
16 Internationalization
Grails supports Internationalization (i18n) out of the box by leveraging the underlying Spring MVC internationalization support. With Grails you are able to customize the text that appears in a view based on the user’s Locale. To quote the javadoc for the Locale class:
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 code for British English.
16.1 Understanding Message Bundles
Now that you have an idea of locales, to use them in Grails you create message bundle file containing 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 several message bundles for a whole range of languages within the grails-app/i18n
directory. For example:
-
messages.properties
-
messages_da.properties
-
messages_de.properties
-
messages_es.properties
-
messages_fr.properties
-
…
By default Grails looks in messages.properties
for messages unless the user has specified a locale. You can create your own message bundle by simply creating a new properties file that ends with the locale you are interested in. For example messages_en_GB.properties
for British English.
16.2 Changing Locales
By default, the user locale is detected from the incoming Accept-Language
header. 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’s locale and subsequent requests will use the switched locale.
By default, Grails uses SessionLocaleResolver as the localeResolver
bean.
You can change the default locale easily:
import org.springframework.web.servlet.i18n.SessionLocaleResolver
beans = {
localeResolver(SessionLocaleResolver) {
defaultLocale= new Locale('es')
}
}
Other localeResolver
are available. For example, you could use save the switched locale in a Cookie:
import org.springframework.web.servlet.i18n.CookieLocaleResolver
beans = {
localeResolver(CookieLocaleResolver) {
defaultLocale= new Locale('es')
}
}
Or fix the locale:
import org.springframework.web.servlet.i18n.FixedLocaleResolver
beans = {
localeResolver(FixedLocaleResolver, new Locale('de'))
}
16.3 Reading Messages
Reading Messages in the View
The most common place that you need messages is inside the view. Use the message tag for this:
<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.
Messages can also include arguments, for example:
<g:message code="my.localized.content" args="${ ['Juan', 'lunes'] }" />
The message declaration specifies positional parameters which are dynamically specified:
my.localized.content=Hola, me llamo {0}. Hoy es {1}.
Reading Messages in Grails Artifacts with MessageSource
In a Grails artifact, you can inject messageSource
and use the method getMessage
with the arguments: message code, message arguments, default message and locale to retrieve a message.
import org.springframework.context.MessageSource
import org.springframework.context.i18n.LocaleContextHolder
class MyappController {
MessageSource messageSource
def show() {
def msg = messageSource.getMessage('my.localized.content', ['Juan', 'lunes'] as Object[], 'Default Message', LocaleContextHolder.locale)
}
Reading Messages in Controllers and Tag Libraries with the Message Tag
Additionally, you can read a message inside Controllers and Tag Libraries with the Message Tag. However, using the message tag relies on GSP support which a Grails application may not necessarily have; e.g. a rest application.
In a controller, you can invoke tags as methods.
def show() {
def msg = message(code: "my.localized.content", args: ['Juan', 'lunes'])
}
The same technique can be used in tag libraries, but if your tag library uses a custom namespace then you must prefix the call with g.
:
def myTag = { attrs, body ->
def msg = g.message(code: "my.localized.content", args: ['Juan', 'lunes'])
}
16.4 Scaffolding and i18n
Grails scaffolding templates for controllers and views are fully i18n-aware. The GSPs use the message tag for labels, buttons etc. and controller flash
messages use i18n to resolve locale-specific messages.
The scaffolding includes locale specific labels for domain classes and domain fields. For example, if you have a Book
domain class with a title
field:
class Book {
String title
}
The scaffolding will use labels with the following keys:
book.label = Libro
book.title.label = TÃtulo del libro
You can use this property pattern if you’d like or come up with one of your own. There is nothing special about the use of the word label
as part of the key other than it’s the convention used by the scaffolding.