Internationalization with the Dojo Toolkit
In this tutorial,you'll learn how the Dojo Toolkit supports internationalization (i18n),including the uSEOf dictionaries for string substitution,and how basic locale formatting for things such as Dateobjects,numbers and currencies are supported.
Getting StartedCreating a web application for a specific target market is usually a daunting task,but libraries such as the Dojo Toolkitease that task by providing tools to quicklyassemble userinterfaces (i.e. Dijit),supporting code to easethe pain of cross-browsercompatibility,and various add-ons/plug-insfor specific functionality such as the DojoX Charting package. No such toolkit would be complete without the ability to localize an application—in other words,the ability foran application to be presented using language based on the location of the application's user. The Dojo Toolkit provides thisability for application developers through the use of dojo.i18n. A Short HistoryIn software development,two terms are used when discussing the ability to display application elements based on a user's locale:internationalization (or i18n) and localization (or L10n). While many usethese terms interchangably,there is a subtle difference between the two:
If you are wondering where "i18n" and "L10n" come from,it is an old computer science tradition that lists the numberof letters in the term that are abbreviated,and is wrapped with the first and last letters of the term. The capital "L" for localizationis normally used to distinguish the term from i18n. A good explanation of the concept and differences can befound at Wikipedia. Because applications built using the Dojo Toolkit are dynamic in nature (i.e. compiled and executed at run-time),they are consideredto be internationalized and not localized. Internationalization with the Dojo Toolkit takes two forms: the ability to define resource bundles that can be loadedbased on a user's locale,and special built-in i18n facilities based on the Unicode CLDRfor dates,numbers and currencies. Locales with the Dojo ToolkitIn order for an application to know what resources it may need to use for i18n,a locale must first be defined. What are locales?Locales are a short string,based on a language code anda country code,separated by a dash. For example,the localefor a typical user in the United States is en-us. Normally,the locale is determined for a browser during the browser's installation,and cannot be easily configured. When loading a Dojo Toolkit-based application,the user's locale is detected automatically and can be found programmaticallythrough the Specifying a localeIf you need to specify a locale,you may do so by setting a // before dojo.js is loaded var dojoConfig = { locale: "pt-pt" }; // or in the script tag: <script src="path/to/dojo.js" data-dojo-config="locale:'pt-pt'"></script> You should always include the full locale (i.e. language + country) when specifying a locale,even though many resourcebundles are defined by language only (as you'll see later on). Once a Dojo Toolkit-based application is loaded,it is not possible to change the locale. Including extra localesThere may be times when you want to include more than one locale-specific resource—for instance,if you needto display date resources in more than one language. While this is not the normal use-case,the Dojo Toolkit allowsyou to include more locale-based resources through the use of the // before dojo.js is loaded var dojoConfig = { locale: "pt-pt",extraLocale: ["zh-cn","zh-tw"] }; // or in the script tag: <script src="path/to/dojo.js" data-dojo-config="locale:'pt-pt',extraLocale:['zh-cn','zh-tw']"></script> These extra locales can be passed into methods such as Resource BundlesA resource bundle is a file containing a JavaScript object literal (or dictionary) of terms used by yourapplication code for a specific locale. When a user's locale is detected (and define( ({ invalidMessage: "入力した値は無効です。",missingMessage: "この値は必須です。",rangeMessage: "この値は範囲外です。" }) ); If you're wondering what There are a few things to note here about the structure of this resource bundle:
Let's take a look at how to create a resource bundle,as part of a larger set of resource bundles. Creating resource bundlesThe first step in creating resource bundles is to create a subdirectory called nls where your code lives,like so: Note that the directory must be named "nls",and must be a subdirectory of the code that will be using it.In our example above,we have i18n directories for both the root of Dijit (i.e. for any widget that lives directly underthe Inside the The name of each resource bundle does not matter,though by convention it should be close to the purpose of it. For example,in our screen shot above,there are three main resource bundles in the root of The resource bundles in the root of the You do not have to create locale-specific bundles for all possible languages/locales; in the case that alocale is detected but no locale-specific resource exists,the master bundle will be used in full. In your language or locale directory,create identically named resource bundles as the master bundles; in each locale-specificbundle,define whatever properties you will be using in your code. Finally,in your master bundle (the main one in the root of the // the master bundle,from dijit/form/nls/validate.js: define({ root: ({ invalidMessage: "The value entered is not valid.",missingMessage: "This value is required.",rangeMessage: "This value is out of range." }),"zh": true,"zh-tw": true,"tr": true,"th": true,"sv": true,"sl": true,"sk": true,"ru": true,"ro": true,"pt": true,"pt-pt": true,"pl": true,"nl": true,"nb": true,"ko": true,"kk": true,"ja": true,"it": true,"hu": true,"he": true,"fr": true,"fi": true,"es": true,"el": true,"de": true,"da": true,"cs": true,"ca": true,"ar": true }); // our localized Japanese resource,from // dijit/form/nls/ja/validate.js: define( ({ invalidMessage: "入力した値は無効です。",rangeMessage: "この値は範囲外です。" }) ); Notice that in our "master" bundle,the properties to be consumed by your code is a full JavaScript objectliteral called root,while the localized Japanese version is a straight-up object literal.You must follow this form for i18n to work correctly. Consuming resource bundlesTo consume resource bundles in your application code,you'll rely on the Both // at the top of ValidationTextBox.js: dojo.require("dojo.i18n"); dojo.requireLocalization("dijit.form","validate"); // later on,in the declaration of the widget: postMixInProperties: function(){ this.inherited(arguments); this.messages = dojo.i18n.getLocalization("dijit.form","validate",this.lang); if(this.invalidMessage == "$_unset_$"){ this.invalidMessage = this.messages.invalidMessage; } if(this.missingMessage == "$_unset_$"){ this.missingMessage = this.messages.missingMessage; } } // Note that some lines in postMixInProperties have been removed for brevity.View Demo You'll see that With the release of the Dojo Toolkit 1.6 and the gradual transition to AMD, You'll also note that these localized properties are set in the Creating builds with resource bundlesA typical step in deploying a Dojo Toolkit-based application is to createa build of your application; a build minifies your JavaScript,inlines HTML and CSS,and generally makes yourapplication run much more efficiently. The Dojo Build Tools alsoprovides ways of flattening your resource bundles through the command line parameter Normally you won't need to include this command line parameter to create your build; by default,the following listof locales is included: "en-gb,en-us,de-de,es-es,fr-fr,it-it,pt-br,ko-kr,zh-tw,zh-cn,ja-jp" However,if your application needs more than these locales defined,you can write your own comma-delimited listas the value of the A common "gotcha" when creating internationally-aware applications is to forget to copy over any Dates,Numbers and Currencies in the Dojo ToolkitInternationalization in a toolkit would not be complete without the ability to parse and format dates,numbers and currencyin locale-specific formats. The Dojo Toolkit provides this functionality with You can learn more about working localization and dates specifically in the Dojo Date tutorial. Locale-aware dates with the Dojo ToolkitAs with our resource bundles, // with our config object: var dojoConfig = { extraLocale: [ "zh-cn","ja-jp" ] }; // after dojo.js has been loaded: dojo.require("dojo.date.locale"); var d = new Date(2006,9,29,12,30); // to format a date,simply pass the date to the format function dojo.date.locale.format(d); // => "10/29/06 12:30 PM" // the second argument may contain a list of options in Object syntax,// such as overriding the default locale dojo.date.locale.format(d,{locale:'zh-cn'}); // => "06-10-29 下午12:30" For more information about working with Date objects with the Dojo Toolkit,seethe Dojo Date tutorial. Note that if you plan on formatting and parsing dates,numbers and currencies in a number of different locales,you mustset the Locale-aware number formattingLike // => 1,000,000 ...but German,French and Indian users would expect the following formats: // => 1.000.000,00 German // => 1 000 000,00 French // => 10,00,000.00 Indian Like with dojo.require("dojo.number"); console.log(dojo.number.format(100000,{ locale: "hi-in" })); // => 10,000.00 console.log(dojo.number.parse("10,000.00",{ locale: "hi-in" })); // => 1000000 Locale-aware currenciesFinally, dojo.require("dojo.currency"); // in the United States dojo.currency.format(1234.567,{currency: "USD"}); // => "$1,234.57" // basic Euro formatting dojo.currency.format(1234.567,{currency: "EUR"}); // => " |