Wednesday, March 26, 2008

Notes on Grails Internationalization (i18n)

When using Grails for web app development, it's desirable to place all text in messages.properties files. When you do this, you can easily change the text to another language, and that makes internationalization easier. You still have to deal with other issues such as date formats and currency, but at least the text is easy to modify that way.

Once you have all your properties files created, you can make change languages by passing in the lang parameter and setting it to the language of your choice. For instance, if you want to list out some values, you can call the "list" action and pass it the Spanish language as a parameter.

<g:link action="list" params="[lang:'es']">

Note: Once you pass this parameter to any page, your app will now be in that language until you change it.

So, in order to facilitate this, you need to create the necessary files and reference the properties in your code. For example, create a messages.properties file and add text such as "Search" for your home page.

home.search=Search

Now, you can create a messages_es.properties that contains your Spanish translations:

home.search=Buscar

So, once you have all the text defined in your messages.properties file(s), (one for each language you are translating to) all you then need to do is reference that particular property in your code. Grails picks that up and inserts the appropriate property for you. Here are some tips on doing that in your code.

In the GSP page, if you want to reference the file in just plain text, use the g:message tag:

<g:message code="home.search" default="Search"/>

This tells Grails to find the property "home.search" in the properties file, and insert that value here. If it cannot find "home.search" in your properties file, it will insert whatever is in the default parameter.

When using the sortableColumn GSP tag, use the "titleKey" parameter to set the property as follows:

<g:sortableColumn property="title" titleKey="certification.title"/>

To set the text of a button, you can pass in a variable from the controller. I've used the flash scope to pass data back to the view, but you can use another object if you want to and return it. First, grab the value from the flash scope in the GSP page as follows:

<input type="submit" value="${flash.search}"/>

Next, in the controller action, just set the flash.search parameter before you return:

flash.search = message(code: 'home.search')

Now, the action in the controller will grab the message and throw it into the flash.search variable. You simply read that variable in the GSP page and it's all good. There's probably a better way of reading that parameter directly in the GSP page, and when I find it, I'll post an update.