Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

developerWorks Community:

  • Close [x]

Implementing National Language Support (NLS) in WebSphere Portal 4.1

a Different Approach

Anthony Bernal (abernal@us.ibm.com), Senior I/T Specialist , IBM
Photo: Joey Bernal
Anthony (Joey) Bernal is a Senior I/T Specialist with the e-Workplaces/Knowledge and Content Management Practice with IBM Global Services. You can reach Joey at abernal@us.ibm.com .
Tim Buczak (tvb@us.ibm.com), IT Specialist/Architect, IBM
Photo: Tim Buczak
Tim Buczak is a I/T Specialist with the e-Workplaces/Knowledge and Content Management Practice with IBM Global Services. His interests include Knowledge Management, Portals and generally really cool stuff. When he's not working, he likes to spend time with his wife and family or hanging out in bookstores and coffee shops in Colorado You can reach Tim at tvb@us.ibm.com .
Yixing Gong (yixingg@us.ibm.com), Senior IT Specialist, IBM
Photo: Yixing Gong
Yixing Gong is an IBM certified IT Specialist working on developing dynamic workplaces and portal applications on the Internet/Intranet for enterprises using IBM e-business technology, products and tools. In recent years, he is working on developing enterprise e-Workplaces and corporate portals on the Web using IBM WebSphere Portal Offerings from Enable to Extend to Experience. You can reach Yixing at yixingg@us.ibm.com .

Summary:  WebSphere Portal applications can be designed to let users to easily select the language in which they want information displayed. This article describes a flexible approach that was used by a major manufacturer.

Date:  27 Nov 2002
Level:  Intermediate

Activity:  3743 views
Comments:  

Introduction

Many Web applications need to display their results in more than one language. WebSphere Portal applications can be designed to let users to easily select the language in which they want information displayed. The approach that is used in WebSphere Portal however, may not fit every requirement for a portal implementation.

During a recent Portal 4.1 engagement, a major North American manufacturer submitted the following national language support (NLS) requirements:

  • The portal must be able to display information in the three major languages (English, French and Spanish) used in North America.
  • The persistant store for the language text must be database driven and updateable. A major reason for using a database is because of the process and time lag involved in changing a system in production. This company, like many others, needed a long lead time when changing files such as NLS properties files and deploying them to a Web site.
  • The system must store users' language preferences so that the portal displays the correct language when a user returns to the application.
  • The system must provide good performance when multiple users are accessing the portal.

With these requriements in mind, we designed a system for managing and accessing NLS tags that would use the base portal functionality and architecture. This article outlines our approach and provides an end-to-end example of using portlet services and tag libraries within the WebSphere Portal architecture.


Designing an approach

The overall design for the NLS tag implementation is as follows:

  • Language preferences are set in the LDAP directory for a particular user upon portal registration. While using an attribute in the users LDAP record is useful for the users default language, we decided that using cookies would be helpful in changing a users language preference on the fly.
  • The expiration date on the cookies is set for one year to ensure that when a user returns to the portal the previously selected language still applies.
  • The NLS service checks the request object for a cookie. If one is not found, it uses the default language in the LDAP. If neither is found it defaults to English.
  • The NLS service caches the database entries in memory that can be accessed by portlets and JSP tag libraries. This cache can be refreshed when updates are necessary by using a refresh portlet.

Setting up the data tables

A simple database table was used to hold the data, with the following columns:

  • NLS_TAG_ID: Primary key for this table. Setup with a trigger and a sequence.
  • NLS_TAG_COMMON_NAME: The common name used to determine what tag to show (e.g., portal.command.logout).
  • NLS_TAG_VALUE_EN: The tag value in English (e.g., Logout).
  • NLS_TAG_VALUE_FR: The tag value in French (e.g., Sortie du systeme).
  • NLS_TAG_VALUE_ES: The tag value in Spanish (e.g., Registro de estado de la maquina).

This table was designed quickly because this functionality needed to be implemented quickly. For future releases it would be better to normalize the data into two or more tables and rewrite the administration portlet to be able to handle additional languages.

Tag-naming conventions

To ensure unique tag definitions and prevent different portlet developers from creating the same tags, portal commands and tags use the following format conventions:

 
Portal.command.login 
Portal.command.changepassword 

Portlets that use tags follow this format:

 
Portlet.portletname.function.tagname 

Some overlap in tag names and use is acceptable, but this naming convention cuts down on reusing the same tag name or tag value.


Setting language cookies

The portal uses JavaScript to set cookies, with the cookie stored on the user's machine for future reference. Setting cookies is done using a set of radio buttons that call the setLanguage() function in the project's JavaScript library.

 
<td> 
<form name="LanguageSet" action="">  
<input value="EN" type="radio" name="language" onClick="javascript:setLanguage('EN')"  
<% if (languageValue.equals("EN")) { %> 
   checked 
v% } %> 
>English 
</td> 
</tr> 
<tr> 
<td> 
<input value="FR" type="radio" name="language" onClick="javascript:setLanguage('FR')" 
<% if (languageValue.equals("FR")) { %> 
   checked 
<% } %> 
>Fran#x437ais 
</form> 
</td> 
 

When a user clicks on a radio button, the portal calls the JavaScript, which sets the cookie to the requested language and reloads the portal page to display text in that language.


sample screen

This example has only two language selections. Spanish was not implemented in the first release. You could add Spanish by adding the text to the NLS tags and adding a radio button for Spanish.

The following code shows two JavaScript functions. The first one is called to set the language cookie with a name of language and a value of whatever is passed into the function. The application used the values EN, ES or FR. These constants are set in a utility class so that they are stored in only one place throughout the portal.

 
function SetLanguage(language) { 
   var expdate = new Date (); 
   expdate.setTime (expdate.getTime() + (1000 * 60 * 60 * 24 * 31)); 
   var sURL = unescape(window.location.pathname); 
   setCookie("language", language, expdate); 
   window.location.href = sURL; 
} 
 
function setCookie (name, value, expires) { 
   if (!expires) expires = new Date(); 
document.cookie = name + "=" + escape (value) + "; expires="  
                         + expires.toGMTString() +  "; path=/"; 
}                                                        


Building a portlet service

Portlet services are used heavily through out the entire project. The service makes considerable use of the methods for adding and updating NLS tags from different portlets. This section focus on two main methods that perform most of the work for the NLS display. The WebSphere Portal InfoCenter provides a thorough description of the use of portlet services and the advantages of properties for initializing a service.

 
package com.mycompany.b2b.wps.nlstag.portletservice; 
 
import org.apache.jetspeed.portlet.service.*; 
import org.apache.jetspeed.portlet.service.spi.*; 
import org.apache.jetspeed.portlet.*; 
import org.apache.jetspeed.portletcontainer.services.portletserviceregistry.*; 
import javax.servlet.http.*; 
import javax.servlet.*; 
import java.util.*; 
import java.sql.*; 
import javax.sql.DataSource; 
import com.mycompany.b2b.wps.nlstag.*; 
import com.mycompany.b2b.wps.data.portletservice.*; 
 
public class NlsTagServiceImpl implements NlsTagService, PortletServiceProvider { 
public static Hashtable nlsCache;	 
	private final static String NLSQuery  
	 = "SELECT NLS_TAG_ID, NLS_TAG_COMMON_NAME, NLS_TAG_VALUE_EN,  
      NLS_TAG_VALUE_FR, NLS_TAG_VALUE_ES FROM NLS_TAG ORDER BY NLS_TAG_COMMON_NAME"; 
	 
public void destroy() {} 
       

The refreshData() method is designed to read the NLS tags from the database and cache them in memory. A Hashtable was used to key off the NLS tag name and its associated NLS tag object. This approach ensures that the application doesn't have to access the database every time a user displays a tag on the portal. Because there are hundreds of tags in use, this was an important performance consideration. Click here to see refreshData() method

Since all tags are cached for performance as mentioned above, we needed a method to refresh the cache when a tag is added or changed in the database. A small portlet was built that allows the administrator to refresh the cache using this method when an NLS tag has been updated.

 
	public void refreshNlsTagCache() { 
			nlsCache = new Hashtable(); 
			refreshData();		 
	} 


Tying it all together

A JSP tag library brings all the components together. Getting the text into portlets could be done in a couple of ways. With the service available to the portlets, text could be pulled and passed to the JSP via a bean or printed to the screen directly by the portlet controller. Our approach was to build a JSP tag that would output the language directly from the JSP. This approach also allowed the tags to be accessed from the main portal JSPs as well.

The first step in implementing this was to create the .tld file, which determined what classes were going to be called when the tag was used.

 
<?xml version="1.0" encoding="ISO-8859-1" ?> 
<!DOCTYPE taglib PUBLIC  "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" 
  "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> 
<taglib> 
    <tlibversion>1.0<tlibversion></tlibversion> 
    <jspversion>1.1<jspversion></jspversion> 
    <shortname>Tags for My Company Portal<shortname></shortname>    
    <tag> 
        <name>nls<name></name> 
        <tagclass>com.mycompany.b2b.wps.tags.nls.NLSTag<tagclass></tagclass> 
        <bodycontent>empty<bodycontent></bodycontent> 
        <attribute> 
            <name>attribute<name></name> 
            <required>true<required></required> 
        </attribute> 
    </tag>     
</taglib> 

Using the library within the JSPs required setting up two lines of code. The following line at the start of the JSP sets up the tag for use within the page.

 
<%@ taglib uri="/WEB-INF/tld/B2BTags.tld" prefix="bibtag" %> 

The tag can then be used whererever text needs to be displayed in a specific language.

 
<bibtag:nls attribute="portlet.selfregistration.text.dealerheading"/> 

Java tag library

The code library was developed after the .tld file was set up:

 
package com.mycompany.b2b.wps.tags.nls; 
 
import javax.servlet.http.*; 
import javax.servlet.*; 
import javax.servlet.jsp.*; 
import javax.servlet.jsp.tagext.*; 
 
import com.ibm.wps.engine.RunData; 
 
import com.mycompany.b2b.wps.nlstag.portletservice.*; 
import org.apache.jetspeed.portletcontainer.services.portletserviceregistry.*; 
 
public class NLSTag extends TagSupport { 
 
	/** 
	 * Constructor for NLSTag 
	 */ 
	public NLSTag() { 
		super(); 
	} 

The main method in the tag library grabs the attribute that is passed in the tag and passes it to the portlet service along with the request object. The service uses that information to look up the tag and return it in the required language.

 
public int doStartTag() throws JspException { 
  NlsTagService nlsTagService = null; 
	String myTag = null; 
	try { 
		nlsTagService = 
			(NlsTagService) PortletServiceRegistryAccess.
			                 getPortletService(NlsTagService.class); 
	} catch (Throwable t) { 
		System.err.println( 
      "NLSTag.doStartTag(): unable to get NLSTagService handle for "  
		 	  + NlsTagService.class.getName()); 
		System.err.println("Exception: " + t.toString()); 
		t.printStackTrace(System.err); 
	} 
	try {   
		myTag = nlsTagService.getNlsTag( 
           iAttribute, RunData.from(pageContext.getRequest()).getRequest()); 
		pageContext.getOut().print(myTag); 
	} catch (Exception e) { 
		System.err.println( 
        "NLSTag.doStartTag(): unable to get value from NLSTagService for "  
           + iAttribute); 
		System.err.println("Exception: " + e.toString()); 
		e.printStackTrace(System.err); 
	} 
	int ret = 0; 
	return (ret); 
} 
 
public void resetCustomAttributes() { 
	iAttribute = null; 
} 
	 
public void setAttribute(String aAttribute) { 
	iAttribute = aAttribute; 
} 
// private Members 
private String iAttribute; 
} 

As you can see this is a fairly simple class that provides a big piece of functionality for the design. The class is deployed in a JAR file and placed in the WebSphere/AppServer/lib/app directory.

Building the admin portlet

For administration of the tags, a portlet was created that allowed administrators to add, delete and edit the tags on the fly.


the admin portlet

This portlet provides two ways to search NLS tags: by tag names or by tag text values. In either case, the search result is a list of tags. From this list, an administrator can select a tag and delete it or edit its text values. An administrator can also add a tag by giving the tag name and its English, French, and Spanish text values.

A separate portlet was created to allow for the refreshing cached data when tags were changed in the system.

The framework for the portlet itself, providing basic create, update, and delete functionality, is another work product built in the engagement and may be the subject of a future article.


Conclusion

This article has shown how you can easily add NLS functionality to Portal applications. You can apply the model outlined here to a variety of situations or easily modify it to add more functionality.


About the authors

Photo: Joey Bernal

Anthony (Joey) Bernal is a Senior I/T Specialist with the e-Workplaces/Knowledge and Content Management Practice with IBM Global Services. You can reach Joey at abernal@us.ibm.com .

Photo: Tim Buczak

Tim Buczak is a I/T Specialist with the e-Workplaces/Knowledge and Content Management Practice with IBM Global Services. His interests include Knowledge Management, Portals and generally really cool stuff. When he's not working, he likes to spend time with his wife and family or hanging out in bookstores and coffee shops in Colorado You can reach Tim at tvb@us.ibm.com .

Photo: Yixing Gong

Yixing Gong is an IBM certified IT Specialist working on developing dynamic workplaces and portal applications on the Internet/Intranet for enterprises using IBM e-business technology, products and tools. In recent years, he is working on developing enterprise e-Workplaces and corporate portals on the Web using IBM WebSphere Portal Offerings from Enable to Extend to Experience. You can reach Yixing at yixingg@us.ibm.com .

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=13976
ArticleTitle=Implementing National Language Support (NLS) in WebSphere Portal 4.1
publish-date=11272002
author1-email=abernal@us.ibm.com
author1-email-cc=
author2-email=tvb@us.ibm.com
author2-email-cc=
author3-email=yixingg@us.ibm.com
author3-email-cc=