Discuss New Concept,New Technic,New Tools, Including EAI,BPM,SOA,Tibco,IBM MQ,Tuxedo, Cloud,Hadoop,NoSQL,J2EE,Ruby,Scala,Python, Performance,Scalability,Distributed,HA, Social Network,Machine Learning.

March 22, 2011
Yoav Rubin (yoav@il.ibm.com), Software engineer, IBM
Gal Shachor, Senior Technical Staff Member, IBM

Summary: The mother tongue of most of the people in the world is not English. It might be a widely used language like Chinese or French, or a rarely used language like the Bask language or Yiddish. These people, regardless of their English skills, may be potential clients; the only problem is how to reach them. It is one thing to reach a potential client’s screen, and quite another to convey the message from their screen to their minds. Following various internationalization (i18n) guidelines helps to address this problem, especially in properly presenting your application Web site to the user in his or her native language. This can result in exposure to huge markets where the only barrier is language and cultural differences. In this article, discover a way to perform native language support in the context of Web sites and Web applications using the i18n feature of the Dojo toolkit.

Introduction

Internationalism, as defined by Wikipedia, is the process of designing a software application so that it can be adapted to various languages and regions without engineering changes (see Resources). Using this definition, in order to have internationalized software, the presence of three elements is essential:

• An element that is responsible to tell the software the locale in which the software is running
• A set of translation files that can be applied to the software’s current locale
• A component that is responsible to connect the previous two elements

In this article, we will create a simple internationalized Web application and demonstrate the Dojo toolkit standards for the first two elements (see Resources for more on Dojo). Then we will examine two Dojo usage scenarios for the third element: an html file or a widget.

Setting the locale in a Dojo-based application

The locale is a parameter defining the language that should be used in the application’s user interface. There may be situations where specifying the language may not be enough. Different countries may use the same language with subtle changes, ranging from spelling changes (for example, “center” in the United States as opposed to “centre” in the United Kingdom) to different words for the same meaning (“Elevator” in the U.S. as opposed to “Lift” in the UK). Therefore, the locale parameter may contain a country code in addition to the language code, to specify the specific language flavor that should be used.

Dojo provides two mechanisms of specifying the locale of the Web application. The first is programmatically (either in run time or design time), and the other is to rely on the default locale of the browser (which is defined during the browser’s installation).

Setting the locale programmatically is done by specifying the value of the “locale” attribute in the global object djConfig. The example in Listing 1 shows how to set the locale to en-us locale in design time:
Listing 1: Setting the locale programmatically in design time

  

Another possibility is programmatically calculating the locale (for example, by extracting it from the URL) and then setting locale. The example in Listing 2 shows how to set the locale programmatically in run time:
Listing 2: Setting the locale programmatically in run time

  

The last possibility is to not specify the locale, which results in using the default locale of the browser, which Dojo extracts from the navigator object. The default behavior, like any usage of default for that matter, is useful in cases where you can predict how your client’s browser and machine are configured. This is rarely the case, and installing the browser in a language which is not the user’s mother tongue, or a locale with which your application is not familiar, is not uncommon (so do try to avoid using this approach).

The translation files in Dojo applications

Now that you understand how to state the application’s locale, it is time to learn to provide the set of the translation files, called “resource bundle(s),” to Dojo applications.

A resource bundle is a group of files, all named the same, in which each file is applicable for a specific locale. Each file should be in the JSON format. For our greeting application, the resource bundle files are all named greeting.js. Their contents are shown in Listing 3.
Listing 3: Resource bundles for different English locales

 Content for the American English locale: { PAGE_TITLE:"God bless America", GREETING: “What’s up”, PERSON: “dude”, GREETING_SENTENCE: “${greeting}${personTitle}” } Content for the British English locale: { PAGE_TITLE:"God save the queen", GREETING:”Hello”, PERSON:”dear”, GREETING_SENTENCE: “${greeting}${personTitle}” } Content for the Australian English locale: { PAGE_TITLE:"God bless the ozis", GREETING:”G’day”, PERSON:”mate”, GREETING_SENTENCE: “${greeting}${personTitle}” } Content for the French locale: { PAGE_TITLE:"Vive la France", GREETING:”Bonjour”, PERSON:”monsieur”, GREETING_SENTENCE: “${greeting}${personTitle}” } 

You now need to place these files in the proper location, so that Dojo can read them. In order to do so, you need to construct a hierarchy of folders, in the way that Dojo expects. Assume that the application defines a module path called “sampleApp” in the location “../../sample/application” relative to Dojo. So the directory structure you need to create is like the one seen inFigure 1.
Figure 1. Directory structure

Basically, a folder named “nls” should be under the defined module. It contains the locale folders, which are lower cased, and a hyphen separates the language code from the optional country code.

Note that in the translation files we have separated the greeting into two parts, since different languages may have different sentence structures and may build the greeting differently. Hence, we need a way to construct the greeting from its components in an internationalized way. For this we use Dojo’s utility dojo.string.substitute, which receives a template for a string, with parameterized values, and substitutes the placeholders in the templates with the given values. The template itself is the entry GREETING_SENTENCE in the resource bundle.

Connecting the pieces within an HTML file

In order to connect all the previously defined pieces, we create the html file that contains our application, shown in Listing 4.
Listing 4: The application’s HTML file

 


The most important thing to notice in this application is the usage of two Dojo commands that extract the localized information. The first one is: dojo.requireLocalization("sampleApp", "greeting"). This call is responsible for requesting from the server the resource bundle called “greeting” that is found under the defined module “sampleApp.” The second one is: var nlsStrings = dojo.i18n.getLocalization("sampleApp","greeting"). This call is responsible for transforming the received “greeting” resource bundle (which was found under the “sampleApp” module) into a JavaScript object, which is returned. Once you have this object (the nlsStrings object), you can refer to any of its fields in order to set the appropriate dom element with the needed strings.

Connecting the pieces and displaying the content using custom-created widgets

Usually, when the application gets a little bigger than a sample application, custom-created widgets are introduced. In this section, we recreate the sample application, now using custom-created widgets. You’ll see how properly to separate all the mechanisms of internationalism from the content displaying widgets.

First of all, create the widget that is responsible for handling all the internationalism issues, starting with the “mixin,” shown inListing 5, which is responsible for all the native language support (NLS) operations.
Listing 5: The NLS mixin

  dojo.require("dojo.i18n"); dojo.require("dojo.string"); dojo.requireLocalization("sampleApp", "greeting"); dojo.provide("sampleApp.widget.NlsMixin"); dojo.declare("sampleApp.widget.NlsMixin",null, { data: {__initialized: false}, constructor: function() { if(!this.data.__initialized) { this.data.nlsStrings = dojo.i18n.getLocalization("sampleApp", "greeting"); this.data.__initialized = true; } }, /** * * @param {String} key - the name of the key in the translation file * @param {Object or Array?} substitutes - in cases where the translated * string is a template for string substitution, this parameter * holds the values to be used by dojo.string.substitute on that * template */ getString: function(/*String*/ key, /*Object or Array?*/ substitutes) { var str = this.data.nlsStrings[key]; return (substituteValues)? dojo.string.substitute(str,substitutes): str; }, postMixInProperties: function() { this.inherited('postMixInProperties', arguments); this.initializeStrings(); }, initializeStrings: function(){} } ); 

There are three things to note in this mixin:

• In order to reduce memory usage, the resource bundle object is static and singleton.
• Widgets that use this mixin need to override the function ‘initializeStrings‘, and populate it with calls to thegetString function. This method is invoked during the call to postMixinProperties in order to make all the internationalized strings available to use while rendering this widget (in other words, using these strings within the widget’s template).
• The getString function receives two parameters. One is the key within the resource bundle. If the returned string needs further handling by dojo.string.substitute, then the second parameter is used to supply the substitution object or array (depending on the way that the template was defined in the resource bundle).

Now we’ll show you how to create the simple greeting widget, which would be placed within your page to greet your application’s users. See Listing 6.
Listing 6: The greeting widget’s code

  dojo.provide("sampleApp.widget.Greeting"); dojo.require("dijit._Widget"); dojo.require("dijit._Templated"); dojo.require("sampleApp.widget.NlsMixin"); dojo.declare("sampleApp.widget.Greeting", [dijit._Widget,dijit._Templated ,sampleApp.widget.NlsMixin], { templateString: "
\${greeting}
", greeting:””, initializeStrings: function() { var greetingString = this.getString("GREETING"); var personString = this.getString("PERSON"); this.greeting = this.getString("GREETING_SENTENCE", {greeting:greetingString, personTitle:personString}); } } ); 

As you can see, the template refers to a variable that gets a “real” value during the call to initalizeStrings, which uses thegetString method in order to get the proper internationalized content.

Now, all that needs to be done is use this widget in an HTML file to view the internationalized content, seen in Listing 7.
Listing 7: The greeting page for the en-au locale

 


Quick testing

Translating the application to languages that are not the language used by developers during development adds the necessity for three types of tests to be done on the software.

• The first one is to test the quality of the translation, which is something that is usually very difficult to do, since it requires another person besides the translator that is fluent in the translated language. This kind of testing is beyond the scope of this article.
• The second type is to test the way that the application’s user interface displays each of the languages. Sentences or words may turn out to be much longer or shorter in other languages, and this change may cause the UI to look different. (There are also other aspects of i18n, which are not discussed here, such as the need to sometimes use a different set of colors and icons in different locales due to cultural differences.) This testing is done by the development team, and may result in using different style sheets for different locales. This kind of testing is also beyond the scope of this article.
• The third type is a coverage test. It basically means that the developer needs to verify that each and every string that is presented to the end user by the application is not hard coded, but comes from the proper resource bundle. We’ll present one way of doing this test. There may be others, but this one is simple, efficient, and there is no need to do something more complicated here.

Testing for hard-coded elements

Below is a step-by-step guide to performing a coverage test on the internationalized content:

1. Create a dummy locale, called “en-num” (add a folder as a sibling of the other locale folders).
2. Copy the resource bundle you want to test to this folder .
3. Either by hand or automatically using some small program or a script written in your favorite programming language, change all the strings in this file (not including substitution markers for dojo.string.substitute) to numbers.
4. Set the application’s locale to be “en-num” and go over all the screens of your application. If you see a string that is not composed of numbers, then most likely this string did not originate from the resource bundle.

Summary

In conclusion, you have seen how to perform internationalism in Web applications using the Dojo toolkit. This article presented a way to design, implement, and test the translation aspect of i18n. There are other aspects, more related to localization, such as formatting some of the displayed elements according to the locale (different countries use different methods to present numbers, currencies, time, and date). Other aspects of i18n that are not addressed here are things that are derived from cultural differences. Icons that mean one thing in one country may mean the opposite in another country. For example, using an owl icon to signify a wise thing in the UI won’t work in some Asian countries, as an owl sometimes symbolizes stupidity.

Still, the translation aspect of i18n is the most resource demanding, requiring much work from the software developers. Using information presented in this article may save you some time and money. If so, then our work here was worth doing.

Resources

Learn

• See Wikipedia’s page on Internationalization.
• The Dojo toolkit is a JavaScript toolkit that has many components to support Ajax application development.
• IBM globalization has many resources that handle various aspects regarding globalization concerns.
• Blogamundo is an excellent blog that discusses various internationalization aspects.
• Global by design is a blog that discusses various Web globalization aspects.
• The Dojo campus holds many good tips and cookies regarding using Dojo.
• Expand your Web development skills with articles and tutorials that specialize in Web technologies in the developerWorks Web development zone.
• Browse the technology bookstore for books on these and other technical topics.

Discuss