Portlet Internationalisation

Why internationalise?

Internationalisation is about users being presented with interfaces that are displayed in their preferred language. If your portlet provides options for a user to configure the portlet, or displays headings and other strings on screen, this is an essential step. And it is simple!

For your portlet to support multiple languages (e.g. French, German, Japanese) or even variants of the same language where spelling may be different (e.g. English US, English Australian), all hardcoded strings must be moved into a properties file. This properties file can then be translated into various languages. Your portlet then refers to the keys within the properties file, rather than the actual text. To accomplish this we use the JSTL fmt tag library, which is part of core JSTL.

For example, the following is a hardcoded string and will only ever appear in the language it is written in.

<p>This is some text</p>

In order to fix this we need to first move this string into a properties file where it can be translated, then add some additional setup to our pages to read the correct language version of the text into our page.

It's easy, lets do it!

First, create a properties file. Conventionally this is called messages.properties but it can be called anything.

messages.properties
my.internationalised.string = This is some text

 

Include the JSTL fmt tag library in your JSP:

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

 

Setup a language parameter in your JSP, and use that to set the Locale using the fmt:setLocale tag. This is important so that the fmt library knows what language file to get the property from.

<c:set var="language" value="${not empty param.language ? param.language : not empty language ? language : pageContext.request.locale}" scope="request" /
<fmt:setLocale value="${language}" />

 

Include the properties file in your JSP using the fmt:setBundle tag. The basename is like a package and refers to the directory that the file is in, in your classpath.

<fmt:setBundle basename="au.com.flyingkite.myportlet.utils.messages" />

This indicates the messages.properties file is located at au/com/flyingkite/myportlet/utils/messages.properties

 

Now, instead of hardcoding the text, output the internationalised string using the fmt:message tag:

<p><fmt:message key="my.internationalised.string" /></p>

 

Then for any other strings, you just add them to the properties file and refer to them by their key, and they will be retireved from the properties file.

People can then translate the file into a different language, store it with the language suffix, eg messages_fr.properties and if a user's locale is set to French for example, it will use the properties from that file instead.

Missing properties will always fall back to a base properties file, generally based on the locale that the JVM is set to run as, so whatever language that file is in will be the default if any properties are missing (this is generally English but not always so).

Important things to note

If you have a string that accepts dynamic data, perhaps from a variable, such as "Hello my name is USERNAME, how are you today?" where 'USERNAME' is a variable, you must NOT concatenate strings together within your code. The properties file system contains the facility for placeholders to be set. This is because the way you structure a sentence may not be the same way a user from a different locale structures the same sentence. Using placeholders allows the correct sentence structure to be set for each locale.

 

Don't do this:

greeting.text.1=Hello
greeting.text.2=, how are you today
 
<fmt:message key="greeting.text.1"/> ${username}<fmt:message key="greeting.text.2"/>

 

Do this instead:

greeting.text=Hello {0}, how are you today?

 

Then in your JSP you then provide the fmt:message tag a list of parameters that will be substituted for the placeholders:

<fmt:message key="greeting.text">
	<fmt:param value="${username}" />
</fmt:message>