« Back to Localization

Portlet Localization - Outside Liferay

Introduction #

This wiki will explain how to localize non-Lifray dependent portlets outside of Liferay. You can use this method regardless of what framework you are using to build your portlets.

Some benefits of using resource bundles is efficiency in maintaining message bundles and the ability to localize or internationalize your messages from a centralized location. The centralized location is actually in your Language.properties files.

Localizing your portlets will require the following steps.

Create Message Bundles#

Language files are

.properties
files.

For example:

 hello-world=Hello World
 title-error=Please Enter A Valid Title Name

These files must be located in the classpath accessible by your portlet. A common location is within the portlet's WEB-INF/classes folder. The default message bundle is Language.properties, but can have any name, provided it is fully qualified (see Step 2 for details on this).

e.g.

 WEB-INF/classes/com/my/portlets/p1/Resource.properties

Your foreign language files will be named with the following syntax:

 Language_*.properties

So if you were creating a Spanish message bundle, you would name it Language_es.properties. Sometimes a language will have different dialects from different regions. For example Chinese, you could have Chinese from China or Taiwan. In this case you would name your files Language_zh_CN.properties and Language_zh_TW.properties.

Had you decided to use a different name for your bundles, the above would be:

 WEB-INF/classes/com/my/portlets/p1/Resource.properties
 WEB-INF/classes/com/my/portlets/p1/Resource_es.properties
 WEB-INF/classes/com/my/portlets/p1/Resource_zh_CN.properties
 WEB-INF/classes/com/my/portlets/p1/Resource_zh_TW.properties

Add More Locales#

The language and country code combinations, or "locales" are found in portal.properties (Languages and Time Zones section). If you want to add more locales, you would need to look up the proper codes. Here are good places to start: http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt http://userpage.chemie.fu-berlin.de/diverse/doc/ISO_3166.html

Non-Unicode characters#

Java can only read Unicode characters or latin1 characters so what do you do when you have non-unicode characters such as Arabic or Japanese ? One way of dealing with this is to write a Language_.properties.native file that uses the native language in the value. Afterwards, convert the native file using a native to ascii converter. A popular one is ascii2converter. http://java.sun.com/j2se/1.5.0/docs/tooldocs/solaris/native2ascii.html

Configuring your portlets to load their language bundles#

In your portlet.xml, define your <resource-bundle> as you created it above.

e.g.

 <resource-bundle>com.my.portlets.p1.Resource</resource-bundle>

Also in portlet.xml, define a <supported-locale> for each language you want to support. Example for Spanish and Chinese from China or Taiwan:

 <supported-locale>es</supported-locale>
 <supported-locale>zh_CN</supported-locale>
 <supported-locale>zh_TW</supported-locale>

The end result for several portlets could be something like:

  <portlet-app ...>
    <portlet>
      <portlet-name>p1</portlet-name>
      ...
      <supports>
		...
      </supports>
      <supported-locale>es</supported-locale>
      <supported-locale>zh_CN</supported-locale>
      <supported-locale>zh_TW</supported-locale>
      <resource-bundle>com.my.portlets.p1.Resource</resource-bundle>
      <portlet-info>
		...
      </portlet-info>
      ...
    </portlet>
    <portlet>
      <portlet-name>p2</portlet-name>
      ...
      <supported-locale>es</supported-locale>
      <supported-locale>zh_CN</supported-locale>
      <supported-locale>zh_TW</supported-locale>
      <resource-bundle>com.my.portlets.p2.Resource</resource-bundle>
      ...
    </portlet>
    ...
    <portlet>
      <portlet-name>pN</portlet-name>
      ...
      <supported-locale>es</supported-locale>
      <supported-locale>zh_CN</supported-locale>
      <supported-locale>zh_TW</supported-locale>
      <resource-bundle>com.my.portlets.pN.Resource</resource-bundle>
      ...
    </portlet>
  </portlet-app>

Loading your language bundles in your pages#

Portlet Standard Way#

The standard way of loading your language bundles in portlets is by accessing a couple of objects in the portlet context:

 <%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
 <%@ page import="java.util.Locale" %>
 <%@ page import="java.util.ResourceBundle" %>
 <portlet:defineObjects />
 <%
 // renderRequest and portletConfig are objects which, accoring to the
 // portlet spec, are required to be in context. So they should just be 
 // there for you to use.
 Locale locale = renderRequest.getLocale();
 ResourceBundle res = portletConfig.getResourceBundle(locale);
 %>

This method doesn't require you to know the actual name of the bundle. The portlet container should take care of setting that up for you (provided you configured your portlet.xml properly)

Utilize java.util.ResourceBundle#

We can use the ResourceBundle to select which Language.properties files to use. The ResouceBundle requires two parameters to be passed including the locale codes; you could use the Locale class to retrieve the current locale.

Import these classes in your jsp:

 <%@ page import="java.util.ResourceBundle" %>
 <%@ page import="java.util.Locale" %>

Also include the following in your jsp:

 <% 
  Locale locale = (Locale)request.getSession().getAttribute("org.apache.struts.action.LOCALE");
  String language = locale.getLanguage();
  String country = locale.getCountry();
  // Remember, "Language" is the fully qualified name of a bundle in the classpath
  //
  // e.g.    WEB-INF/classes/Language_*.properties
  ResourceBundle res = ResourceBundle.getBundle("Language", new Locale(language, country));
 %>

In the above snippet you can see that we request a Locale object, which we then use to get the Language and Country codes. Those codes are then passed in as parameters in ResourceBundle.getBundle(String, new Locale(String, String)) to identify which bundle to use.

Localize Messages#

Use your messages with the following syntax:

 res.getString("message-key")

If you have a hello world button, instead of making the button

 <input type="button" value="Hello World" />

make it

 <input type="button" value="<%= res.getString("hello-world") %>" />

Now you are set to use your localized/internationalized messages. When you change the Locale via the Language portlet, your localization should appear!

Titles and Category#

Portlet Title#

There are three standard keys defined specifically for the localization of portlet info, including the title.

 javax.portlet.title=My Portlet
 javax.portlet.short-title=MyPortlet
 javax.portlet.keywords=My,Portlet

Include these in your language bundles to localize those values and the portlet titles, displayed throughtout the portal (including the "Add Content" menu), will be localized.

(*4.3) Portlet Category/"Add Content" Menu#

Suppose you create a new portlet category in which to group your portlets, and you configure the liferay-display.xml as such;

e.g.

  <display>
    <category name="my.new.category">
      <category name="my.new.sub-category">
        <portlet id="portlet_A" />
        <portlet id="portlet_B" />
      </category>
      <portlet id="portlet_C" />
      <portlet id="portlet_D" />
    </category>
  </display>

All you need to do to have the appropriate name appear in the "Add Content" menu of the portal is to add the keys to your localization files. For the above two categories, include the following in your language bundles:

 my.new.category=This is My Category
 my.new.sub-category=My Sub-Category

That's it.

Note: If for example you have the four portlets above defined in your portlet.xml, and each one has it's own language bundle, the first bundle found to contain the keys will be used. So to be safe, just copy the category keys to each bundle.

Struts#

If using struts, in struts-config.xml, define the <message-resource>. If your files are in WEB-INF/classes/abc/123/Language.properties you would do this:

 <message-resources parameter="abc.123.Language" />

Note: One WAR with multiple portlets#

Remember, if you have more than one portlet in your war, they won't be able to share the same resource bundle. What does this mean? It means you can't do this (as is done in the portal war):

 javax.portlet.title.xxxx=TEST

You can only do:

 javax.portlet.title=TEST

Use the method suggested above to separate your portlet resource bundles.

0 Attachments
73340 Views
Average (5 Votes)
The average rating is 4.2 stars out of 5.
Comments
Threaded Replies Author Date
Or else, you can use language hook: (see... Ilya Zverev April 6, 2009 2:32 AM
You can also use <liferay-ui:message key="key"... Ruth Coca November 1, 2009 10:04 AM

Or else, you can use language hook: (see http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/Portal+Hook+Plugins)­
Posted on 4/6/09 2:32 AM.
You can also use <liferay-ui:message key="key" /> emoticon
Posted on 11/1/09 10:04 AM.