i18n using GWT’s UiBinder

Following my last article on how to efficiently include SEO with GWT, here’s a guide on how to easily add internationalization (i18n) to any UiBinder template and make your application available in different locales. Be sure to read Renaud’s beginner’s tutorial before if you want more details on UiBinders.

The first thing you will need to do is make sure you have Python installed, then grab a copy of Philippe Beaudoin’s mergelocales.py Python script and save it in the root of your project. This script does all the heavy lifting of processing the GWT’s compiler auxiliary extra files for us, and generates clean .properties files.

Preparing your UiBinders

Let’s start with two simple widgets hardcoded in English :

First, we need to add a few attributes to the ui:UiBinder tag to tell GWT’s compiler to generate extras for this UiBinder file:

Second, we need to wrap the translatable text with `ui:msg` tags:

Note the description attribute values. These need to be unique across your application. They are considered to be the unique identifier of the texts you want to translate. It is a good practice to prefix the value with the section of the application the text relates to.

Generating the extras

Now that our UiBinders are ready for translation, we need to generate the auxiliary extra files. This is done by passing the -extras and -extra <FOLDER> parameters to the GWT compiler. If you’re using Maven and the gwt-maven-plugin, you can simply add the extraParam and extra configuration tags:

The <extraParam> parameter tells the GWT compiler that we want to generate the extra auxiliary files, and the <extra> parameter instructs the GWT compiler to generate these files in a folder named extras (or the name of your choice).

In order to generate the extra files, simply compile your application (e.g. mvn clean gwt:compile). The generated extra files will be found at the root of your project. The extras folder will contain a subfolder named by your module: {projectRoot}/extras/{gwtModuleName}. In that folder, you should find one generated properties file per UiBinder file. Since in this example we have 2 UiBinder files, we’ll have 2 .properties file.

You might notice that every translatable text snippet (for instance, Hello, world!, This is an awesome i18n tutorial and Welcome to the i18n sample) is duplicated across the generated properties files; and that the descriptions are scattered across the many generated properties files. As your number of UiBinder files grows, you can imagine the complexity of managing all those snippets for each language of your application. This is where the mergelocales.py script comes into play.

Merging .properties files with mergelocales.py

Merging properties files

The idea is to only have one .properties file per language available in your application so that you have fewer files to maintain. The mergelocales.py script does all that for you. It will look for all the generated .properties files in the extras folder and merge them into a single language-specific properties file.

Let’s say we would like our application to also be available in French. We need to create two empty files named LocalizableResource.properties and LocalizableResource_fr.properties. The LocalizableResource.properties will contain the default (English) texts, whereas the LocalizableResource_fr.properties, will contain the French texts. Those files should be located in src/main/resources/com/google/gwt/i18n/client.

Next, we need to populate those files using the script : python mergelocales.py extras/<moduleName> src/main/resources/com/google/gwt/i18n/client/.

The first parameter (extras/<moduleName) tells the script where to look for the .properties files generated by GWT. The second parameter (src/main/resources/com/google/gwt/i18n/client/) tells the script where to write the centralized translations files. For our example, this would output:

You will notice that both files contain almost the same text, except for the #TODO: TRANSLATE comments found in the French properties file. Now, I can easily translate the LocalizableResource_fr.properties file:

That’s it! We now have a translated application. The last thing we need to do is to provide those translations to our users.

Handling the Locale

The GWT compiler needs to generate a permutation for each combination of browser and locale supported by our application. To tell the compiler which locale is supported, you need to add the following lines to your GWT’s module xml file (.gwt.xml).

This activates English and French permutations, and instructs the compiler that the default locale should be English. Without the 2 last lines, the default locale would be considered to be a different locale, even though all the texts are English, making the number of permutations that need to be compiled significantly higher.

You can now switch locale using a query parameter in your url. For example, to load our sample in French, we would simply need to use this URL : http://www.example.org/?locale=fr.

The complete source code for this article is avaiable on GitHub. For a more complete example, you can take a look at our website’s source code, also available on GitHub. You can also find more information on Locales or UiBinder on GWT’s documentation site.

Subscribe to our newsletter to receive our upcoming posts.

Thanks to Simon-Pierre Gingras (@spgingras, +SPGingras) for the original version of this example.

  • Stanislav Spiridonov

    Thank you, for great post about i18n in UiBinder.

    Few notes:

    1. It is safer to add to your GWT’s module xml file.

    Usually is indirectly inherited by . But it can be changed in the future.

    2. If you want to use the single language in your application and it isn’t English language anyway add the English to locale and set it as fallback as describe in the post. The difference will be only in one line:

    It will allows to correct work the widgets which doesn’t support German (they will correct fallback to English)

    3. Single language usually means the single country, in that case add to locale property country specific locale to :

    and

    It will enable country specific formatting for application language.

    • Maxime Mériouma-Caron

      Thanks for the comments.
      1. Agreed, changed it in the article.
      2 and 3 are a bit outside the scope of what I wanted to show, but are still good observations