Wasn't this a jQuery plugin?
Globalization is a vital part to every website in today's world. Many could potentially be sacrificing business from international customers who don't understand or want to support one particular language. What if I told you that supporting any customer from any location in the world is now just as easy as not supporting them? Well, this article is here to teach you how.
Background of the problem
Not everyone in the world speaks the same language. Nor does everyone in the world format his or her numbers, dates, and currency the same way.
You may wonder why this is a problem now. Websites have been around for years now and different countries have been around for 10,000 years. The problem is becoming more acute because we are increasingly seeing websites do more work on the client, instead of relying on the server to do all the work, or relying on Ajax client-server calls to do the work. Developers want a pure-client solution for everything now.
$("#reponseSpan").text(2 * new Number($("#inputTextField").val()));
You could instruct users of your website to type all numbers in US format, but is that really the best answer? Do you want to force your users to do things your way, or do you want to accept whatever they do and make the user experience as nice as possible.
Table 1 shows examples of possible formats for numbers that exemplify why the Globalize plugin is the best solution.
Table 1. Number formats for different countries
How does the Globalize plugin deal with these aforementioned issues? They structure the solution in terms of cultures. A culture shouldn't be thought of as a language, because many countries in the world speak the same language, like Spanish. Likewise, a culture shouldn't be thought of as a country, since there are some countries that have multiple official languages, like Switzerland. Instead, the notion of a culture can be thought of as a unique combination of a country and a language. Thus, while Spanish isn't unique and Spain isn't unique, Spanish-Spain is unique, and thus can be considered a culture (to differentiate it from Spanish-Mexico and Catalan-Spain).
When you group together all the unique languages and countries in the world, there are approximately 350 cultures that need to be supported. (That's another reason you wouldn't even want to consider hacking together a solution yourself.) When the Globalize plugin constructs the culture, it uses two 2-letter codes. The first is a 2-letter lowercase language code, termed the ISO 639 code and the second is a 2-letter uppercase country code, termed the ISO 3166 code (see Resources). For example, "en-US" would denote that it's an English language and United States culture, and a "fr-FR" would denote a French language and France culture.
Also important is the "neutral" culture. In effect, the Globalize plugin says, "If you can't get specific language and country information, you can just pass the language, and we'll make a best guess as to how to properly format everything". This is a big help, as you'll see later. People browsing the web tend to identify the language they speak, but determining their country code can sometimes be very difficult.
The first step is to download the Globalize plugin itself (see Resources). Also note, that jQuery is not required to use the Globalize plugin. It was in the past, but the newest version doesn't require it. The Globalize plugin is designed so that the "main" plugin is in the root folder and called "globalize.js". This file is small (only 44 KB), but it only does American English. This is because it only contains the default values for all the functionality, and doesn't contain any actual culture code. Open the "cultures" folder and there are 353 files, which can add complexity to the problem. Now identify this special file: "globalize.cultures.js" — this file contains every possible culture so you don't have to load specifically the ones you need to work with. Of course, including every culture has its drawback in that it creates a large file, 828 KB. That's likely excessive in any production situation. However, it's good enough for us to write some example code for now.
Listing 1. Loading Globalize in test environments
Listing 2. Setting a Culture
// Remember, this only works if you include the globalize.js file! // And, you HAVE to include the globalize.cultures.js file OR // each individual culture's JS file // You can set the culture directly by referencing its name Globalize.culture = Globalize.cultures.de; // You can set the culture directly by referencing it from // the Cultures array Globalize.culture = Globalize.cultures["de-DE"];
Formatting a number
Formatting and parsing are the two most fundamental functions when working with internationalization. After all, you're letting your users type in numbers and dates in the format they wish. Yet, you need to get their input into a format you can work with (parse), or display your own data in a format they want (format).
In most languages, formatting numbers involves working with four types of formats: numbers (the digits in front of a decimal point), decimals (the digits after a decimal point), percentage (which multiplies the number by 100 and shows the "%" sign) and currency (which shows that culture's currency symbol, like the $ or the Euro symbol). Each type of format can take a numerical argument as well, to tell the formatter how to properly apply the pattern.
- n— is used for numbers, and denotes to the formatter to turn this Number object into a number. This argument can be used with a number, which tells the formatter how many decimal points to use. For example, "n3" will tell the formatter to make the argument a number with 3 decimal points.
- d— is used for decimals, and denotes to turn this Number object into a number with decimals. This argument can be used with a number, which tells the formatter how many digits to use before the decimal point. For example, "d2" will the formatter to make the number forcibly have 2 digits to the left of the decimal point.
- p— is the same as the "n" argument, except that the formatter multiplies the number by 100 and adds a "%" after the number.
- c— is the currency symbol, and adds the culture's currency symbol to the appropriate spot. Adding a number argument as well will tell the formatter how many decimal digits to use.
Listing 3. Number formatting examples
// Assume that the correct Culture JS file is always added here // make the Culture German Globalize.culture = Globalize.cultures.de; // test the "n" command Globalize.format(1839.560, "n1"); // outputs 1.839,6 Globalize.format(1839.560, "n0"); // outputs 1.840 Globalize.format(1839.560, "n6"); // outputs 1.839,560000 // test the "c" command Globalize.format(1839.560, "c2"); // outputs 1.839,56 Globalize.format(1839.560, "c3"); // outputs 1.839,560 Globalize.format(1839.560, "c6"); // outputs 1.839,560000 // now make it English and run the same code Globalize.culture = Globalize.cultures.en; // test the "n" command Globalize.format(1839.560, "n1"); // outputs 1,839.6 Globalize.format(1839.560, "n0"); // outputs 1,840 Globalize.format(1839.560, "n6"); // outputs 1,839.560000 // test the "c" command Globalize.format(1839.560, "c2"); // outputs $1,839.56 Globalize.format(1839.560, "c3"); // outputs $1,839.560 Globalize.format(1839.560, "c6"); // outputs $1,839.560000
There are a few things I don't like about the formatting functions used here, though. First, the currency formatting isn't flexible to allow me to specify where I want the currency symbol. Compare that to a formatter like Java™ uses, where the coder can specify where the currency symbol should go, for example, in front, in back, with a space, or without a space. It's possible with this Globalize plugin, but it requires either editing the "de" Culture object (not recommended) or creating a custom one. Additionally, Java formatting allows you to add characters to the beginning and end as further customization. For example, when you're talking a signing bonus for a new job, you may write your desired signing bonus as "$24k", with the "k" representing "thousands". This type of abbreviation is common in the US, with "k" for thousands, "M" for millions, and "B" for billions. Unfortunately, this is not possible in the Globalize plugin formatting right now, without writing your own Culture object to do so.
Ultimately, I do not think that the formatting is as powerful as Java on the server-side, but it's still a solution in nearly every use case you would need it.
Parsing a number
Once a user types in a number, currency, or percentage, you need to get that information, and you need it in a form that you can create a Number object with it. In other words, you need it in a way that the code can do math with it. In addition, you may want to get it in the proper form if you pass it to the server. In this case, you need to parse the number, turning it from a string into a number.
Listing 4. Number parsing examples
// Assume that the correct Culture JS file is always added here // make the Culture German Globalize.culture = Globalize.cultures.de; // Call parseInt() on it, and get an object back we can work with var num = Globalize.parseInt("1.839,56"); // will create an object with value 1840 // now make it English and run the same code Globalize.culture = Globalize.cultures.en; // Call parseInt() on it, and get an object back we can work with var num = Globalize.parseInt("1,839.56"); // will create an object with value 1840 // Likewise, there's a parseFloat() that will preserve the decimal points var num = Globalize.parseFloat("1,839.56"); // will create an object with value 1839.56
Formatting a date
Formatting is not just limited to numbers with the Globalize plugin. Dates can also be formatted. After all, the date March 8, 2011, can be written as 3/8/11 in the United States, and 8/3/11 in Germany. Formatting dates is much more complicated and involved than formatting numbers, and for that reason, I won't go into great detail here about all the options you can use with formatting a date. That's what the documentation is for after all.
Listing 5. Date formatting examples
// Assume that the correct Culture JS file is always added here // make the Culture German Globalize.culture = Globalize.cultures.de; // Create a date for March 8th, 2011 // NOTE - months are 0 indexed, but the day isn't...how dumb! Globalize.format(new Date(2011,2,8),"d"); // outputs 08.03.2011 Globalize.format(new Date(2011,2,8),"M"); // outputs 08 März Globalize.format(new Date(2011,2,8),"D"); // outputs Dienstag, 8. März 2011 // now make it English and run the same code Globalize.culture = Globalize.cultures.en; Globalize.format(new Date(2011,2,8),"d"); // outputs 3/8/2011 Globalize.format(new Date(2011,2,8),"M"); // outputs March 08 Globalize.format(new Date(2011,2,8),"D"); // outputs Tuesday, March 08, 2011
Parsing a date
Parsing a Date object is just as easy.
Listing 6. Date parsing examples
To this point, we've used the "globalize.cultures.js" file in our examples to make the code easier to work with. The "globalize.cultures.js" file contains all 350 cultures, and as a result, it's 828 KB. That's fine for these examples, but it will not work in a production environment. Why pass 349 unneeded cultures with every page load when you don't have to? Most of your users will only need one or two cultures loaded on their page in order to completely internationalize the page.
In addition, how do you even know which cultures should be loaded on a page? It's not as if a browser can tell you exactly where the user is coming from in the world (though that's changing with location-based services and with IP address lookups). If I travel with my laptop to Stockholm, I wouldn't want every site to automatically convert everything to Swedish formatting just because I've physically changed locations. I haven't physically changed the way I read numbers and dates just cause I've changed locations. Wouldn't it be nice if there was a way to automatically tell what languages and countries a user preferred as they surfed the web.
Our goal is to determine what language(s) the user prefers. Then, based on those languages, we want to load only those cultures onto the page, in order to reduce traffic and page load time. Finally, we want to call Globalize.culture() with the users' preferred language, so that the Globalize plugin knows how to format everything. Listing 7 shows code in Java and Listing 8 shows code in PHP that you can use to internationalize your web page automatically.
If you use JSP or PHP, feel free to take this code and paste it into your own code if you plan to use the Globalize plugin. It's ready to deploy and has no external dependencies; Java 5 or higher, PHP 4 or higher.
Listing 7. Java internationalization code
Listing 8. PHP internationalization code
We did not go into some of the more detailed aspects of the Globalize plugin. For example, the plugin is adaptable enough that you can easily write your own culture and plug that into the system. However, because we know there are 350 cultures already included with the plugin, are you really in need of another one? If you think you are, it's easy to do, but I didn't see that as a necessary topic in this article.
Finally, I showed you Java and PHP code that could dynamically determine the correct cultures your visitors prefer to use with their browser, and then dynamically load the correct culture files to include with the Globalize plugin, and finally how to dynamically call culture() to set those cultures on the page. You should be able to simply cut and paste the above code into your own code to internationalize your web pages.
- Read the official announcement from the jQuery team regarding the release of this plugin.
- Here is a list of ISO 639 language codes.
- Here is a list of ISO 3166 country codes.
- Working with jQuery, Part 1: Bringing desktop applications to the browser, Part 2: Building tomorrow's web applications today, and Part 3: Rich Internet applications with jQuery and Ajax (Michael Abernethy, developerWorks, 2008): This previous series provides an introduction to the jQuery library.
- The Open source developerWorks zone provides a wealth of information on open source tools and using open source technologies.
Get products and technologies
- Download the Globalize plugin and read the documentation on its GitHub site.
- Browse the updated Globalize documentation goals.
- Try out IBM software at no cost. Download a trial version, log in to an online trial, work with a product in a sandbox environment, or access it through the cloud. Choose from over 100 IBM product trials.
Dig deeper into Open source on developerWorks
Get samples, articles, product docs, and community resources to help build, deploy, and manage your cloud apps.
Keep up with the best and latest technical info to help you tackle your development challenges.
Software development in the cloud. Register today to create a project.
Evaluate IBM software and solutions, and transform challenges into opportunities.