Internationalization, or i18n, is the process of making an application flexible to work in different languages and respect different conventions and customs. An identifier called a locale represents a language code with an optional list of variants, which may include geographic or other information. Based on the locale, different data and logic may be applied when rendering text or dealing with numbers or dates. This section will cover the basic concepts of internationalization and show how these features are implemented in Dojo.
Dojo aims to make internationalization a basic feature of the toolkit, such that the presentation to the user never assumes one particular language or culture. Developer-facing resources, such as console output and API documentation do not yet have an internationalization framework.
Localization in the form of translated resources, mostly in the Dijit project, are generally available starting with the 1.0 release in over a dozen languages, with more to come.
Dojo addressed the globalization features at the very beginning of its development. This document presents the rules and describes how to use these features to globalize your Web applications based on Dojo version 1.0. Each of the rules use one of the following directive words:
* Must: You must always follow the rules; otherwise your application cannot be globalized.
* Should: You are recommended to follow the rules in some situations. Your application can be globalized if you do not follow these rules, but more effort might be needed.
* May: These rules do not affect the capability of globalization. You can choose whether to follow them or not.
Use the following guidelines to implement internationalization.
You should always use UTF-8 for encoding settings wherever applicable.
You should encode all text files in UTF-8.
You must specify the UTF-8 encoding in every HTML file before any non-English characters.
You must use the BOM header for UTF-16 files.
You must use UTF-8 to decode XHR request parameters.
You must use UTF-8 encoding when using a non-English string in a URL.
You must set Content-Type in an HTTP response header if the response is not encoded in UTF-8.
You must set Content-Type in an HTTP response header if the response is not encoded in UTF-8.
You must set djConfig.locale in all files to the same as the locale used by the server code.
You must always use resource bundle to store the strings displayed to users.
You should use djConfig.locale to set the default locale and extra locales, and use only dojo.requireLocalization without the locale parameter.
You may make a build to include resource bundles in the locales that you use.
You should use the Js2Xlf tool to convert JSON files into XLIFF files for translation.
You should deal with free text using ICU library at the server side.
You should use only casing functions for locale neutral situation.
You should not use locale sensitive casing functions provided by JavaScript.
You should always escape a string as a whole rather than character by character.
You should not use any comparing, searching, or replacing functions for strings that might contain combining character sequences.
You should not use inserting, removing, or splitting functions for strings that might contain special characters.
You should not use trimming functions for strings that might contain special characters.
You should not use counting functions for strings that might contain special characters.
You must check the return value of String.charAt() when the string contains surrogates.
You must use dojo.string.substitute() to generate text output rather than simply use "+" between strings.
You must use Dojo format functions to convert locale sensitive data into text.
You must use Dojo validating and parsing functions to convert text from the users' input into data.
You should not hard-code patterns and locales when formatting data.
You should not specify both the height and the width of a widget to be translated by numeric units.
You must ensure that all resources used in widgets are localizable.
You should consider BiDi support in development and customization.
The following guidelines should be used to implement internationalization in encoding.
This is a general rule for Web application design and development. You should manually set the encoding for files or I/O streams wherever applicable, because the default encoding (usually ISO-8859-1) cannot handle all Unicode characters. UTF-8 is the best choice when you use Dojo in your application, since Dojo only uses UTF-8.
The rest of this chapter describes the details of setting encodings in a Web application.
You should encode all text files in UTF-8, including HTML files, CSS files, JavaScript files, etc.
You must specify the UTF-8 encoding in every HTML file before any non-English characters.You must specify the encodings of all HTML files as early as possible. Ideally, this occurs on the server such that the server applies HTTP encoding headers to mark the document, otherwise this must be achieved in the browser using the meta tag. For example:
Hello World!
...
This encoding declaration must appear before any non-English characters in a file; otherwise a browser might fail to read it correctly. For example, IE 6.0/7.0 cannot render the following content (encoded in UTF-8):
???
Hello!
By default, browsers assume that all files referred by an HTML file use the same encoding as the referring HTML file. So if you have the encoding of every HTML file specified, you do not need to declare the encoding setting in each CSS or JavaScript file again, but you can override the encoding anyway when some files are not in the same encoding as the HTML file. For example,
... ... ...
A BOM header consists of 2, 3, or 4 bytes at the very beginning of a text file to indicate its encoding. For example, 0xFF 0xFE means that the file is encoded in UTF-16LE, while 0xEF 0xBB 0xBF means that the encoding is UTF-8. The BOM header can override the encoding settings mentioned above in a browser.
Using UTF-16 is not recommended, but if you choose it for some reason, the BOM header is required. Because UTF-16 is not compatible with ASCII, a browser even does not have a chance to read the encoding setting of the file content.
You must use UTF-8 to decode XHR request parameters.
The dojo.xhr* functions are the most common way in Dojo to
enable Ajax features -- sending an asynchronous request to the server by an
XMLHttpRequest object. The typical call to one of these
functions can be:
dojo.xhrGet({
url: "foo.jsp",
content: {"name": "\u4e00"} // \u4e00 ("?") is the Chinese character for "one"
});
The url is where this request will be sent to. The
content is the JSON object that will be sent in the request. In
Dojo’s implementation, the key and value pairs in the content
are encoded by the encodeURIComponent function first, and then
converted to a query string like "key=value&key=value&...". The
xhrPost function puts the query string into the request
content, and other functions like xhrGet append the query
string to the end of the url, so the previous code is equal to
the following code:
dojo.xhrGet({
url: "foo.jsp?name=%e4%b8%80", // %e4%b8%80 are the UTF-8 bytes for \u4e00
});
Because the encodeURIComponent function always uses UTF-8, you
must use UTF-8 at the server side to decode the request parameters both in
the URL (xhrGet) and in the request content
(xhrPost).
For example, in Tomcat, you can set the encoding of URL by the
URIEncoding attribute in server.xml:
<
You can set the encoding of the request content (xhrPost) by
simply calling request.setCharacterEncoding before using the
request object:
<%@page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%request.setCharacterEncoding("utf-8");%>
...
name=<%=request.getParameter("name")%>
You MUST manually set the encoding on your server, because almost no Web server uses UTF-8 to decode URLs and request content by default. For example, Tomcat always uses ISO-8859-1 to deal with requests if you do not set the encoding. WebSphere uses a locale-encoding map to determine the request encoding from the client's language, but no locale is mapped to UTF-8 by default.
You must use UTF-8 encoding when using a non-English string in a URL.
Some browsers like IE always send URLs using the default system encoding.
For example, in a Simplified Chinese Windows XP operating system, IE sends a
URL encoded in GB2312. If you need to put some non-English parameters in a
URL, make sure that you have encoded it first using the
encodeURIComponent function. For example, in a Simplified
Chinese Windows XP, if you run the following script in IE:
dojo.xhrPost({
url: "foo.jsp?name1=\u4e00",
content: {"name2": "\u4e00"}
});
You might get different results for name1 and
name2 at the server side:
name1 --> 0xD2 0xBB (in GB2312, Wrong!) name2 --> 0xE4 0xB8 0x80 (in UTF-8, Right!)
The right way is to encode name1 first:
dojo.xhrPost({
url: "foo.jsp?name1=" + encodeURIComponent("\u4e00"),
content: {"name2": "\u4e00"}
});
An XMLHttpRequest object first checks the HTTP header of a response to see if there is a Content-Type property that sets the encoding of the response; otherwise, it always uses UTF-8 to decode the response into a string. Web servers usually set the Content-Type property automatically for dynamic files like JSP. However, for static files, Web servers probably do not know the encoding of the files and also do not set the Content-Type property for them.
There is a slight difference in the locale naming conventions between Dojo and Java. Dojo uses "-" (hyphen) as the separator for concatenate language code, country code, and variants, whereas Java uses an "_" (underline). For example, "zh_CN" in Java is similar to "zh-cn" in Dojo.
Like the default locale in Java, Dojo has a global locale value that is stored in a global variable: dojo.locale. This default locale value affects the behavior of several locale-related functions and widgets. The value of dojo.locale is not supposed to be changed. You should use djConfig.locale to initialize this value.
Must set djConfig.locale in all files to achieve server-based personalizationIf djConfig.locale is undefined, Dojo will consult the browser's navigator object for the setting chosen at browser install time. Note that this is unrelated to the locale setting in the preferences dialog, which is for interaction with the server only. To provide personalization from the server to control locale settings in an application, you must set djConfig.locale in the page at the server side, prior to loading dojo.js. For example, here is a JSP page that sets the default locale for Dojo:
...
<%
String actualLocale = ResourceBundle.getBundle("my.app.test",
request.getLocale()).getLocale().toString().replace('_', '-');
%>
...
Dojo introduces resource bundle into JavaScript. If you are familiar with Java resource bundle, you can find that Dojo resource bundle is very similar to Java resource bundle. The following table shows a summary of the differences between Java and Dojo:
| Java | Dojo | |
| File Format | Properties file | JSON file |
| Locale Identifier | Suffix of file name | Directory name |
| Locale Naming | Use "_" (underline) as separator | Use "-" (hyphen) as separator |
| Get Bundle | ResourceBundle.getBundle | dojo.requireLocalization, dojo.i18n.getLocalization |
| Get Message | ResourceBundle.getString | JSON object |
For example, there are two resource bundles named "bar" and "foo" in a package named "my.app" with some of their localized versions:
In Java (6 files with different names):
my/
app/
bar.properties
bar_zh.properties
bar_zh_CN.properties
bar_zh_TW.properties
foo.properties
foo_zh_CN.properties
And in Dojo (4 directories and 6 files):
my/
app/
nls/
bar.js
foo.js
zh/
bar.js
zh-cn/
bar.js
foo.js
zh-tw/
bar.js
The fallback strategy in Dojo is the same as that in Java.
First, you should use the dojo.registerModulePath function to define the directory where resource bundles are as a registered module. The module name needs to be used in later callings to the dojo.requireLocalization and dojo.i18n.getLocalization functions. For the previous example, you can use the following line to define the module "my.app":
dojo.registerModulePath("my.app", "../../my/app");
Note: Here, the "../../my/app" path is relative to the directory that contains "dojo.js".
Then you can use the dojo.requireLocalization function to load resource bundles from files. After a resource bundle is loaded, the dojo.i18n.getLocalization function returns a copy of the bundle object.
When you get the bundle object, you can use it as a normal JSON object (a hash) to get messages. If you modify values in the bundle object, the original global bundle object will not be affected.
You may use djConfig.locale to set the default locale and extra locales, and use only dojo.requireLocalization without the locale parameter.djConfig.locale overrides the browser's default locale as specified by the navigator Javascript object. This setting is effective for the entire page and must be declared prior to loading dojo.js. djConfig.extraLocale establishes additional locales whose resource bundles will be made available. This is used rarely to accomodate multiple languages on a single page. No other locales may be used on the page.
If you omit the locale parameter when calling the dojo.requireLocalization function, the function will load the resource bundles for locales in djConfig.locale as well as for all the locales in djConfig.extraLocale.
For example, if you define:
then the following two code blocks are equal:Code block A:
dojo.requireLocalization("my.app", "bar");
var bar = dojo.i18n.getLocalization("my.app", "bar");
Code block B:
dojo.requireLocalization("my.app", "bar", "zh-cn"); // default locale
dojo.requireLocalization("my.app", "bar", "zh-tw"); // extra locale
dojo.requireLocalization("my.app", "bar", "fr"); // extra locale
var bar = dojo.i18n.getLocalization("my.app", "bar", "zh-cn"); // default locale
The first method is preferred as it is less brittle.
Before you deploy your Web application using Dojo, you should consider building the Dojo layers that are used by your application into a single JavaScript file. Using such a build brings you many advantages. The unused scripts, white spaces, comments, and overridden string values can be removed to make smaller downloads, and the need to search by locale can be skipped such that extra server requests and 404 responses are avoided. In general, the build reduces the request time from the browser to the server to avoid latency issues.
Should make a build to include resource bundles in the locales that you useResource bundles can either be included in a build or be used without a build. If you use resource bundles without a build, the first request for each resource bundle will generate N+1 HTTP requests when it searches the server for values, where N is the number of segments in the target locale. For example, a call of dojo.requireLocalization("my.app", "bar") in the "zh-cn" locale looks for "bar.js" first in the "zh-cn", then in "zh", and finally in the root. Without optimization, some of these requests might result in harmless HTTP 404 errors (page not found) if a variant does not need to override any definitions from its parent.
JSON is a convenient and efficient format for resource bundles in JavaScript, but the JSON format is not well supported by many professional translation centers. XLIFF is the industry standard file format for localization and translation. Among other things, XLIFF will ease in declaration of encoding and hide details from the translator such as JavaScript character entities. Tools will be developed to support round-trip transforms between JSON and XLIFF. Support for gettext PO files in the future is also possible.
Translators must also be aware of the substitution syntax of Dojo — ${x}
Some special characters in Unicode can probably cause problems in a string to be manipulated:
| Ordinary Character | Combining Character Sequence | Surrogate Character | |
| Conversion | Locale Sensitive (Unsolvable) |
Locale Sensitive (Unsolvable) |
Locale Sensitive (Unsolvable) |
| Recognition | Unicode Specific (Unsolvable) |
Unicode Specific (Unsolvable) |
Unicode Specific (Unsolvable) |
| Join | (No Problem) | (No Problem) | (No Problem) |
| Division | (No Problem) | Broken Combining Character (Unsolvable) |
Invalid Code Point (Solvable) |
| Enumeration | (No Problem) | Wrong Character Number (Unsolvable) |
Wrong Character Number (Solvable) |
| Comparison | (No Problem) | No Canonical Comparison (Unsolvable) |
(No Problem) |
Locale Sensitive: JavaScript has a pair of locale sensitive casing functions -- String.toLocaleUpperCase and String.toLocaleLowerCase, but they only honor the default locale of the client's operating system and cannot be controlled by Web applications.
Unicode Specific: JavaScript might not recognize all Unicode characters that have a specific property. For example, some white-space characters (e.g., the no-break space -- U+00A0) cannot be removed when the string is trimmed in JavaScript:
alert("\u00A0".replace(/\s/g, "").length); // 0 (in Firefox), 1 (in IE)
Show Me (THIS STILL NEEDS TO BE FIXED)
The only safe operation for all strings is joining. To manipulate a string, first you need to know what kinds of characters are allowed in it and whether the manipulation is locale sensitive. If the string accepts combining character sequences and surrogate characters or if the manipulation is locale sensitive like casing, you are recommended to send the string to the server and deal with it by using ICU library at the server side. For example, your application might need to handle the following kinds of strings: Restricted Identifier: most identifiers, such as the user's login name, are restricted to letters and numbers, so you can manipulate them in JavaScript freely and safely. Program Information: program information is a string that is only used for your application code, for example, enumeration item names, program commands, and statements. Make sure that no combining character sequence or surrogate character is included in your program information. Then you can manipulate them without potential problems. URL or E-mail Address: URLs and e-mail addresses might contain almost any Unicode characters. You should deal with them at the server side. Free Input Text: the text entered freely by users should be manipulated at the server side. String Manipulating Functions in JavaScript and Dojo
Other casing functions perform locale sensitive casing conversion with the default locale of the client's operating system. You should never use them. The reasons are: first, it is not guaranteed that browsers implement these functions as the exact behavior defined in the latest Unicode Standard; second, you cannot control the output by your Web application. It is almost unacceptable that an end user needs to change the default locale of the operating system so as to change the locale of your Web application. These functions include:
Functions in this section might encounter problems from the manipulation of comparison and division on free text. They might replace wrong characters, return invalid strings or characters, and they cannot perform canonical comparison. Use them only for program information without special characters. These functions include:
Functions in this section might have the problem from division on free text. They might return invalid string or characters. Use them only for program information without special characters. These functions include:
Trimming functions might have the problem of Recognition. They cannot recognize all white-space characters defined by Unicode. Use them only for program information without special characters. These functions include:
Functions for counting characters can only return the number of UTF-16 units rather than the real meaningful characters. These functions include:
The String.charAt() function might return an unpaired surrogate that is invalid. You should always check the returned value, for example: view plaincopy to clipboardprint?
function codePointAt(s, pos) {
var c = s.charAt(pos);
if (c == "") {
return c;
}
var code = c.charCodeAt(0);
if (code >= 0xD800 && code <= 0xDBFF) {
// lower surrogate detected, we need to fetch more char
if (pos < s.length - 1) {
code = s.charCodeAt(pos + 1);
return code < 0xDC00 || code > 0xDFFF ? "" : s.substring(pos, pos + 2);
} else {
return ""; // error in the string
}
} else if (code >= 0xDC00 && code <= 0xDFFF) {
// higher surrogate detected, we need to fetch more char backward
if (pos > 0) {
code = s.charCodeAt(pos - 1);
return code < 0xD800 || code > 0xDBFF ? "" : s.substring(pos - 1, pos + 1);
} else {
return ""; // error in the string
}
}
}
Dojo has the capability of formatting messages like what Java does. Message formatting functions are very important to the translatability of an application -- separating code and translatable materials and supporting application translation without any modification to the code. Furthermore, Dojo provides full functions for data formatting and validation based on Unicode CLDR data, just like what ICU library does. You can easily format your output and validate users' input in Dojo without invoking code at the server side.
You can use dojo.string.substitute() to substitute place holders in the message string. This function provides a function similar to the java.text.MessageFormat.format() function in Java. You must use this function to get your text output instead of simply using the "+" operator; otherwise your application loses its translatability. For example, an English message "File 'foo.txt' is not found in directory '/root/bar'." can be translated as "?'/root/bar'??????'foo.txt'???" in Chinese. If you write your code like msg = pieceA + fileName + pieceB + dirName + pieceC, you cannot translate this message into Chinese without modifying your code, because the positions of fileName and dirName are swapped. Therefore, the right approach is to write the code like this: /* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #000066; font-weight: bold;} .geshifilter .kw2 {color: #003366; font-weight: bold;} .geshifilter .kw3 {color: #000066;} .geshifilter .co1 {color: #009900; font-style: italic;} .geshifilter .coMULTI {color: #009900; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #3366CC;} .geshifilter .nu0 {color: #CC0000;} .geshifilter .me1 {color: #006600;} .geshifilter .re0 {color: #0066FF;}
And the resource bundle "message.js" is like this: /* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #000066; font-weight: bold;} .geshifilter .kw2 {color: #003366; font-weight: bold;} .geshifilter .kw3 {color: #000066;} .geshifilter .co1 {color: #009900; font-style: italic;} .geshifilter .coMULTI {color: #009900; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #3366CC;} .geshifilter .nu0 {color: #CC0000;} .geshifilter .me1 {color: #006600;} .geshifilter .re0 {color: #0066FF;}
You must use Dojo format functions to convert locale sensitive data into text
Dojo utilizes the Unicode CLDR data to format and validate locale sensitive information, such as time, number, and currency. The built-in conversion functions in JavaScript like Date.toString() are not fully Unicode- compatible, and you should not use them in a globalized Web application. For dates and numbers, Dojo format functions are not needed to be called explicitly in your code, and the dojo.string.substitute() function mentioned above can combine the format capabilities with format functions. You only need to specify the format function name in the template string, for example: /* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #000066; font-weight: bold;} .geshifilter .kw2 {color: #003366; font-weight: bold;} .geshifilter .kw3 {color: #000066;} .geshifilter .co1 {color: #009900; font-style: italic;} .geshifilter .coMULTI {color: #009900; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #3366CC;} .geshifilter .nu0 {color: #CC0000;} .geshifilter .me1 {color: #006600;} .geshifilter .re0 {color: #0066FF;}You must use Dojo validating and parsing functions to convert text from the users' input into data
Although JavaScript provides some methods to convert text to data, it does not fully support localized text, for example, view plaincopy to clipboardprint? /* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #000066; font-weight: bold;} .geshifilter .kw2 {color: #003366; font-weight: bold;} .geshifilter .kw3 {color: #000066;} .geshifilter .co1 {color: #009900; font-style: italic;} .geshifilter .coMULTI {color: #009900; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #3366CC;} .geshifilter .nu0 {color: #CC0000;} .geshifilter .me1 {color: #006600;} .geshifilter .re0 {color: #0066FF;}You should not hard-code patterns and locales when formatting data
Usually, you only need to set the selector and the formatLength properties for date (type for number and currency for currency), and use the default values of other properties when calling formatting, validating, or parsing functions. Dojo looks for the correct pattern based on the current default locale. If you specify the pattern by hard coding, the output format cannot be changed with the user's locale.
Dojo uses the Unicode Common Locale Data Repository (CLDR) to format and parse locale-specific data. A subset of the locales supported by the CLDR is transformed to JavaScript and checked into the dojo.cldr package as resource bundles. Although only a handful of locales ship in dojo.cldr, any or all of the hundreds of locales supported by the CLDR may be generated easily by invoking a script. Dojo provides an Ant task to perform the transformation from LDML, an XML-based markup, to JSON files. The entire CLDR source is available with these tools in the util/buildscripts/cldr directory. To invoke this script, you need to check out the current Dojo source code or download the buildscripts archive file and overlay it with your Dojo build, and consult the README file in util/buildscripts/cldr for details. It is as simple as invoking 'ant' in that directory. After the script is executed, all transformed JSON files are added to the "dojo/cldr/nls" directory.
All Dijit Widgets are implemented according to these Globalization guidelines except for right-to-left bi-directional (BiDi) support, which is not complete as of the 0.9 release.
You should not specify both the height and the width of a widget to be translated by numeric units.
You must ensure that all resources used in widgets are localizable.
You should consider BiDi support in development and customization.
When the text content in a widget is translated into another language, the translated string might be longer than the original one, i.e., the one in English. If you specify the size of the widget by numeric units, the widget may not render properly in other languages. For example, some text might be truncated or unexpected text wrapping may distort the layout. Therefore, keeping the translation spread in mind at the beginning of development might be a better practice. You can use the following approaches to set the size of a widget:
Eventually, all Dijit widgets will be consistent with the direction of the HTML document. [TODO: the following text needs to be changed; I think we're only checking for the .dijitRtl class which is based on the document's direction -AP] By default, the display direction is inherited from the parent node, and the direction of the whole page is left-to-right. There are two ways to change the display direction for an HTML node: one is to set the DIR attribute, and the other is to set the direction style. The direction style can override the setting to the DIR attribute, and the computed value of the direction style is the actual way in which the node is displayed. To make the pop-up menu mirrored, for example, you can just set DIR="rtl" on the HTML node to mirror the whole page.
If a page contains a right-to-left layout, you must also import the RTL style sheet of the current Dojo theme and make sure that it is the last one to be imported. The RTL style sheet has no effect on the left-to-right layout.
view plaincopy to clipboardprint?
If the whole page is in a right-to-left layout, you only need to import the RTL style sheet. To make the whole page right-to-left, you can set DIR="rtl" on either the HTML node or the BODY node.
If you want to mix both left-to-right and right-to-left layouts in a page, you must add a dijitRtl class to each right-to-left layout container besides importing the RTL style sheet.
view plaincopy to clipboardprint?
Benefited from the CLDR support of the Dojo core library, Dijit provides plenty of localized widgets that are related to date, number, and currency data processing. You can find their introduction and manual in the corresponding chapters in the Dojo Book 0.9. These widgets include:
Widgets Development and Customization
The resources that are used in widgets include texts, images, audio and video clips, etc. Only HTML code and style names can be hard-coded in the widget code. You can use the resource bundles in Dojo to store localized resources. See "Locale and Resource Bundle" for more information.
Most browsers and HTML itself support the mirrored display in the BiDi environment, but it does not mean that Dijit widgets can support BiDi by nature. There still are some specific codes in Dijit to handle the mirror feature. For example, when displayed in right-to-left direction, the popup menu should appear from left rather than from right, and the arrow that indicates sub menus should also be flipped.
[TODO: strike this para? I think dir is gone? -AP]
Dijit widgets have a dir attribute that is defined in the dijit._Widget class, the base class of all widgets. The dir attribute can be set to indicate the direction of the widget when it is being created. To know the actual direction in the code, you should use the _Widget.isLeftToRight() function. The returned value of this function is not supposed to be changed after the widget is created. That is, currently, Dijit widgets do not support dynamic change of the display direction.
To develop or customize the Dijit widget with BiDi enabled, you should use different styles for the left-to-right and right-to-left directions. For example, it is always required to change the styles like float: left and background-image: url(images/left-arrow.png) for the right-to-left layout for some portion of a widget. You can write all right-to-left styles in an RTL style sheet, and all style classes should begin with the dijitRtl class:
view plaincopy to clipboardprint?
Better still, try to avoid any gestures or visual cues which imply left or right direction, so that styling and coding for BiDi becomes unnecessary. For example, dijit.Tree uses the space key to open a tree instead of a left or right arrow. A "+" symbol might be used for an indicator for extended data, rather than a left or right arrow.
Other encodings should be used with great care. A user agent such as one of the current generation browsers infers the encoding of a page using the content-type header provided by a server or it may be picked up from a meta tag in the head of a document, such as the following:
The most common means of specifying the encoding in a page is to use the META tag. Note that the META tag only works in pages loaded directly by browsers or IFRAMEs and may not function when used in other situations, such as in a document referenced by HREF in dijit.layout.ContentPane. UTF-8 is the detault encoding used by XML documents exchanged by the XmlHttpRequest object and also is the encoding that is used internally by Dojo APIs such as dojo.io.bind. We recommend using UTF-8 as the encoding for all of your applications.
It is important to properly specify the encoding of the page when forms or form widgets are present as the page's encoding is used to properly encode data that is sent back to a server.
By default, the locale of this browser is "".
To override the locale to make German the default for Dojo, use
Localization is driven by a locale, a short string often supplied by the host environment, which conforms to RFC 3066 used in the HTML specification. It consists of short identifiers, typically two characters long which are case-insensitive. Note that Dojo uses dash separators like the RFC, not underscores like Java (e.g. "en-us", not "en_US"). Typically country codes are used in the optional second identifier, and additional variants may be specified. For example, Japanese is "ja"; Japanese in Japan is "ja-jp". Notice that the lower case is intentional -- while Dojo will often convert all locales to lowercase to normalize them, it is the lowercase that must be used when defining your resources.
By default, Dojo derives the user locale setting from the navigator browser object, the only locale information available from Javascript. The browser locale is determined during browser installation and is not easily configurable. Note that this is not the same as the locale in the preferences dialog which can be used to accompany HTTP requests; there is unfortunately no way to access that locale from the client without a server round-trip. The user's locale may easily be overridden on a page prior to the Dojo bootstrap by setting the djConfig.locale property. Of course, setting this property in a static way defeats internationalization for other users. This setting may be established by a server to achieve personalization of web applications, where a user may be able to select their locale or this information may be available through some other means. Once Dojo is loaded, it is not possible to change the locale for the page.
Several locales used since the early days of the Internet have been deprecated in favor of new codes. These include 'iw' for Hebrew in favor of 'he'. Also, 'in' in favor of 'id' for Indonesian, 'no' in favor of 'nb' Norwegian Bokmål (to differentiate from Nynorsk), and 'ji' became 'yi' for Yiddish. Dojo tries to adhere to the latest specifications. Unfortunately, some applications still use the deprecated codes, most notably the JDK. The best practice when dealing with these technologies is to run a transformation on the string before assigning to djConfig.locale to assure that the new locale codes are used.
In the unusual case where multiple locales are used on a single page, the djConfig.extraLocale property must be set, prior to bootstrap, listing the additional locales as elements in an array, otherwise they will not work at runtime. Optionally, one of these extra locales may be passed into routines like dojo.date.format or Dijit widgets using the 'lang' attribute, but such use cases are rare. Typically, the one locale is sufficient to localize the entire page and the locale should not be applied to any one specific widget or API.
dojo.i18n solves a problem in Javascript: now that we've implemented a significant amount of logic on the client, there are i18n issues which cannot easily be solved by server substitution. Furthermore, server substitution scales poorly and exposes the client-side toolkit to a particular server architecture. With a client-side internationalization framework, the integration point moves to the browser where simple or complex logic can be applied without becoming a bottleneck. This architecture also encourages encapsulation and efficient caching both at edge servers and in the browser. And, while all translations are present on the server, rest assured that only those which match the user's locale are requested by the client and sent over the wire.
The methods used in Dojo to substitute localized resources are intended for Dojo-generated content. There are trade-offs to this approach, such as trading server-load for client-side response time. It is usually best to continue using the same mechanism to localize the rest of the page, which is typically a webapp server, rather than trying to force everything on the page through Dojo and Javascript. This does mean that there will usually be two different sets of resources to manage, translate, and deploy. Dojo and Dijit will soon provide translations for many major languages, and additional translations may be provided by the community. Those augmenting Dojo or writing their own widgets will need to create and translate their own set of resources, as needed.
The translation task in a Dojo application is limited to anything which appears in the DOM, that is anything which is visible on the web page. It's unacceptable to hard-code an English string and have that appear to users, no matter how unlikely it is to appear. Debug or console message however, for the time being, are not localized as a matter of policy. There are no guidelines on console messages at the present time. They are generally discouraged in production code.
dojo.requireLocalization() / dojo.i18n.getLocalization()
these methods leverage the DojoPackageSystem (link?) to load localized resources. Each translated resource is implemented as a file containing a Javascript Object (see JSON notation) where each property may be a string or any other Javascript type. Resources are located within the directory structure beneath a specially named "nls" directory (short for native language support). Each translation is made available in a subdirectory named by locale.
dojo.requireLocalization() is used to declare usage of these resources and load them in the same way that dojo.requires() pulls in Javascript packages, but using the translation appropriate to the caller. The location of the bundle is specified using two arguments: the first is the directory structure containing the nls directory; the second is the name of the file in that directory containing the localized resources. The locale used is discovered at runtime from the browser, or specified by an override in djConfig (see "Specifying a locale") If djConfig.extraLocale is set, the localizations in that list will be loaded also.
Use dojo.i18n.getLocalization() to get a reference to the object representing the localized resources. The resources loaded by dojo.requireLocalization() are searched and one best matching the user's locale are used. The localized values will be available as properties on the returned object. For example:
//TODO: replace this example with the strings from dojo.color when translations are available
dojo.require("dojo.i18n");
dojo.requireLocalization("dijit.form", "validate");
var validate = dojo.i18n.getLocalization("dijit.form", "validate");
console.log(validate.invalidMessage);For an English-speaking user, the example above will display the value for invalidMessage from dijit/form/validate.js:
"* The value entered is not valid."
The root happens to have the English translation, which also acts as a fallback for any unsupported locales (English was an arbitrary choice, but the one commonly used in Dojo). Therefore, no translations were found in the en or en-us directories as they would have been redundant. Meanwhile, a Japanese user in the ja-jp locale will see the value in dijit/form/nls/ja, which is the best match for that locale:
"* 入力したデータに該当するものがありません。"
Translation subdirectories are searched and mixed in such a way that variants can specify overrides for some or all of their parent locale. Because the search requires looking for translations under both the language as well as variants, sometimes a 404 will occur; this is normal and can be optimized at build time.
Unlike standard Javascript, Dojo is capable of formatting and parsing date formats for many locales, using the CLDR repository at unicode.org. Both the date and time portion of a JavaScript Date object may be converted to or from a String representation using these routines. For example, look at the following date formatted using the default locale for the user (in this case, English - United States) and also with a specific locale override of Chinese - PRC China:
// the page must specify djConfig.extraLocale: 'zh-cn' to bootstrap the environment with support for an extra locale
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"
Note that the positioning of month, day, and year are all different, as well as the "PM" symbol and its placement. Use of a locale override in this API is limited to examples like this one; usually the correct thing to do is to assume the user's default, or override the locale for the entire page (see "Setting a locale") Dojo.date offers a variety of formatting choices, such as the option to a different format "length" -- a choice of "short", "medium", "long", or "full" -- or to print only the date or time portion of the Date object:
dojo.date.locale.format(d, {selector:'date', formatLength:'full'});
=> "Sunday, October 29, 2006"
dojo.date.locale.format(d, {selector:'time', formatLength:'long', locale:'zh-cn'});
=> "下午12时30分00秒"
Also, it is possible to reverse the process and parse String objects into Dates. For a user running in a Dutch locale like "nl-nl", the following would produce a valid Date object:
dojo.date.locale.parse("maandag 30 oktober 2006", {formatLength: "full"});Special patterns may be specified may be used to provide custom formats, however using such a pattern overrides the locale-specific behavior and may result in an application that is not properly localized. The patterns used follow the specification and are similar to those used by the Java dateformat class (e.g. MMddyyyy).
Also available under dojo.cldr.supplemental are routines to provide the first day of the week and the start and end of the weekend, according to local custom.
The formatting and parsing of numbers is handled in much the same way. Conventions vary around the world for the decimal and thousands separator, placement of the sign, and symbols used to indicate exponential numbers or percentages. There are other exceptions, such as in India, where the thousands separator is used at the thousands place, then again after every two digits instead of three. Dojo provides the facilities to properly format and parse numbers on a localized basis using the methods in dojo.number:
dojo.require("dojo.number");
// in the United States
dojo.number.format(1234567.89);
=> "1,234,567.89"
// in France
dojo.number.format(1234567.89);
=> "1 234 567,89"
Other options may be specified to limit output to a certain number of decimal places or use rounding. And again, custom formats may be specified, overriding the local customs.
dojo.currency combines the functionality of dojo.number to use the appropriate syntax with knowledge of the conventions associated with a particular currency -- this includes the number of decimal places typically used with a currency, rounding conventions, and the currency symbol which itself may be rendered differently according to locale, any of these may be overridden. When calling dojo.currency APIs, be sure to specify a currency according to its 3-letter ISO-4217 symbol.
dojo.require("dojo.currency");
// in the United States
dojo.currency.format(1234.567, {currency: "USD"});
=> "$1,234.57"
dojo.currency.format(1234.567, {currency: "EUR"});
=> "€1,234.57"
// a French-speaking Swiss user would see
dojo.currency.format(-1234.567, {currency: "EUR"});
=> "-1 234,57 €"
// while a German-speaking Swiss user would see
dojo.currency.format(-1234.567, {currency: "EUR"});
=> "-€ 1,234.57"
Note: handling of Hindi and Arabic style numerals is planned for 1.0, but not yet implemented.
It is not necessary to craft translated files to support these conventions in your locale. Dojo supports the above cultural conventions and currency types in pretty much every locale available through the CLDR, which is included with the Dojo build tools. However, by default, only a subset of these locales and currencies are built as Javascript objects in the Dojo repository under dojo.cldr. A script is available to build a custom or more complete set -- look for instructions at util/buildscripts/cldr/README.
Some languages, mostly middle-eastern in origin, have text flow from the right to the left (e.g. Hebrew and Arabic) This affects not just the characters in a sentence, but the entire flow of the user interface. The web browser generally takes care of this "mirroring" for us, provided the DIR attribute is set to "rtl" for right-to-left text direction. Note that text direction and locale are orthogonal concepts as defined by the HTML spec.
Dojo functions, including Dijit, only support a single text direction per document, which must be declared on the HTML or BODY element with the DIR attribute. With some exceptions, the HTML elements comprising the widgets on the page are flipped from right to left by the browser -- browser quirks occasionally require additional workarounds. Still, some other issues remain when mirroring the user interface of complex page fragments, such as those created by widgets. For example, if a graphic indicates a left or right direction, it may also have to be flipped or swapped to follow the new right-to-left logic. Wherever possible, mirroring is achieved using CSS rules. Sometimes the logic of an application or widget must change to accommodate Bi-Di. Keyboard accelerators or other code logic may also have to be modified. For example, in right-to-left mode, menu widgets drop down and to the left and contents are right-justified.
Bi-Di issues are largely related to widgets, and are therefore addressed mostly within the Dijit project. To support right-to-left users, some extra CSS is required. At the present time, these rules reside in a separate stylesheet and must be explicitly loaded to provide Bi-Di support. (e.g. themes/tundra/tundra_rtl.css, which imports themes/tundra/tundra.css for you)
As of the 1.1 release, all Dijits, except for deprecated widgets, are Bi-Di capable. DojoX BiDi support varies.
As of the 1.0 release, the following the widgets have limited Bi-Di support using the Tundra theme:
Dojo Car Store is a globalized fictional MVC Web application demo. It’s designed to illustrate how to integrate dojo with typical web technology and construct a globalized AJAX Web application.
As a pure JavaScript library, dojo can be used with a wide variety of server side technologies, including JSP, PHP, Ruby, WebService, etc. This tutorial chooses JSP for demonstration and focuses on how to integrate dojo globalization features with the existing J2EE globalization best practices (JSTL, JSF, etc.).
Dojo Car Store mainly provides the following functions:
1. Locale switching
2. Car exhibiting (including detailed information)
3. Shopping cart
4. Order and shipment form
4.2 Step by step implementation
4.2.1. Locale (language) switching
You have two options for switching locales (languages) in Dojo Car Store.
- Option 1: Browser language option
Step1:
Open the language configuration tab of your browser:
- For Firefox: Tools-Options-Advanced-Language options
- For IE: Tools-Internet Options-General-Languages
Step2:
Add a locale (language) to or remove a locale (language) from the list, and set your preferred language as the first priority option.
Step3:
Click Confirm, close the tab, and refresh the current page. Please make sure that there is no locale parameter like …… index.jsp?locale=en_US in the address field of the browser, because the demo will deduce locale information from your preferred language list first (see Option2), and then from the browser language configuration.
- Option2: User’s preferred language list on the entry page – index.jsp
Select your preferred language from the dropdown list of languages. When you select another locale, the page will be refreshed automatically.
To ensure a consistent locale deducing strategy for both the client side (dojo) and the server side (JSTL /JSF tag),
the following steps are used:
Step 1: Get the locale from HttpRequest on the server side (for the above mentioned Option1):
<% Locale locale = request.getLocale(); %>
or
Get the locale parameter from HttpRequest URL on the server side (for the above mentioned Option2):
<% String localeStr = request.getParameter("locale");
……
Locale locale = new Locale(……) %>
or
Get the locale parameter from Http session on the server side:
<% Object sessionLocale = session.getAttribute("locale"); %>
Step 2: Set the retained locale in the session scope for later use.
<% session.setAttribute("locale", locale); %>
Note: Here the parameter set in the session is the uniform locale for both the client and the server side.
Step3: Initialize the dojo global parameter dojo.locale as:
/* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */
.geshifilter {font-family: monospace;}
.geshifilter .imp {font-weight: bold; color: red;}
.geshifilter .kw1 {color: #000066; font-weight: bold;}
.geshifilter .kw2 {color: #003366; font-weight: bold;}
.geshifilter .kw3 {color: #000066;}
.geshifilter .co1 {color: #009900; font-style: italic;}
.geshifilter .coMULTI {color: #009900; font-style: italic;}
.geshifilter .es0 {color: #000099; font-weight: bold;}
.geshifilter .br0 {color: #66cc66;}
.geshifilter .st0 {color: #3366CC;}
.geshifilter .nu0 {color: #CC0000;}
.geshifilter .me1 {color: #006600;}
.geshifilter .re0 {color: #0066FF;}
Please also note that dojo only accepts locale string with the format “en-us”, but the locale string from Servlet API has the format “en_US”. Therefore, the above modification is required.
Please refer to index.jsp and checkout.jsp (under DojoGlobalizationDemo.war/DojoCarStore/) for more details.
4.2.2. Literal translation
The literal translations of Dojo Car Store are implemented in the following ways:
1. JSTL i18n tags
Three JSTL i18n tags are used for loading resource bundle: setLocale, setBundle, and message.
Step1: Set the resource bundle locale:
Here, ${sessionScope.locale} is the locale parameter set in session previously.
Step2: Set the base resource bundle:
Step3: Display the literal translation using the resource bundle:
2. Localized JSF tags
Three JSF tags are used for loading the resource bundle: locale, loadBundle, outputText
Step1: Set the locale for the JSF view tag:
Here, #{locale} is the locale parameter set in session previously.
Step2: Set the base resource bundle:
Step3: Display the literal translation using the resource bundle:
3. JSON resource bundle
The literal translations of all the localized dojo widgets come from the JSON resource bundle, for example, DateTextbox, ValidationTextbox, etc. Actually, you can get any JSON resource bundle in the dojo package including CLDR data (please refer to Dojo resource bundle usage sample in Appendix A ).
4. Java resource bundle
Some literal translations are first generated on the server side and then sent back to the client side.
Therefore, these literal translations are loaded from the resource bundle using the normal Java method like:
ResourceBundle resBundle = ResourceBundle.getBundle(……, this.locale);
String pattern = resBundle.getString(……);
Object[] msgArgs = {String.valueOf(this.currentOrderId)};
String confirmJson = …… + MessageFormat.format(pattern, msgArgs) + ……;
Please refer to dojo.g11n.demo.servlet.DojoServlet and dojo.g11n.demo.db.DBManager for more details.
5. DB
Car profiles are stored in separate tables in DB with different language versions (the name of a table contains locale information like “CAR_en”), so when a user loads car profiles, the locale parameter should match the corresponding table.
Please refer to dojo.g11n.demo.servlet.DojoServlet and dojo.g11n.demo.db.DBManager for more details.
4.2.3. UI Implementation
1. Car inventory list
Car inventory list exhibits the images of all the cars in the inventory. You can switch between pages and click the image of a certain car to see its detailed information (or drag it to the Car detail view area directly)
This part mainly includes: Dojo animate transition (fadeIn / fadeOut), Dojo drag&drop, Dojo xhr transport, Dojo Fisheye widget etc.
Please refer to index.jsp and indexController.js(imgController) for more details.
2. Car detail view
Car detail view displays detailed information about the selected car, including car name, price, description, index, etc. Car detail view also provides a slide show that displays different car images. To add the current car to the shopping cart, you can either click the “Add to Cart” button or drag the corresponding image of the car to the shopping cart directly
This part mainly includes: Dojo ContentPane, Dojo animate transition (fadeIn / fadeOut), Dojo drag&drop, Dojo currency API, Dojo JSON, etc.
Please refer to index.jsp and indexController.js(detailController) for more details.
3. Shopping cart
Shopping cart contains information about the cars that you have selected, including car index, name, price, quantity, and total price. To add a car to the shopping cart, you can drag the corresponding image of the car from the Car inventory list or the Car detail view into the shopping cart. Another way to add a car to the shopping cart is to click the Add To Cart button in the Car detail view.
This part mainly includes: Dojo ContentPane, Dojo Currency/Number API, Dojo JSON, Dojo Style, Dojo xhr transport, etc.
Please refer to index.jsp and indexController.js(shoppingCartController) for more details.
4. Order and shipment form completion
When checking out, you need to fill in the shipment and Credit card information forms. In this part, dijit.form.DateTextbox / ValidationTextbox are used because they provide customized validation rules as well as localized warning messages.
After completing the forms, you can click the Checkout button to submit the order. Here, Dojo Dialog widget is used to promote the transaction confirmation and error information.
Please refer to checkout.jsp and checkOutController.js for more details.
4.2.4. Server side XMLHttpRequest processor
DojoServlet processes all the XMLHttpRequest sent through Dojo xhr from client side, such as:
1. Setting CharacterEncoding for both the request and the response as UTF-8;
2. Deducing locale from the request session:
locale = request.getSession().getAttribute(“locale”)
Note:
This demo provides two ways for locale switching. Therefore, simply deducing locale like
Locale locale = request.getLocale(); is not enough because this way only deduces the best matched locale between the client browser and the web container, without considering the user selected language (from the dropdown list). This is simplified by getting the locale parameter from the session (see 4.2.1) because this parameter is the uniform locale on both the server side and the client side.
Please refer to dojo.g11n.demo.servlet.DojoServlet for more details.
4.2.5. Persistence controller & DB
DBManager manages DB connection, data query and updating. Car profiles are stored in DB with different language versions, so car profile query is locale specific.
Dojo Car Store uses embedded Derby 10.1.3.1 by default (DojoGlobalizationDemo.war/DB/DojoCarStoreDB). You can also choose Derby client mode or DB2 instead, please refer to Appendix B for detailed steps.
Note: Derby database uses Unicode by default. When creating databases, tables, and inserting data, please make sure that they are encoded as UTF-8. Please refer to dojo.g11n.demo.db.DBManager for more details.
4.2.6. Web Server g11n configuration.
Dojo Car Store uses POST XMLHttpRequest (only UTF-8 encoding) to submit client data that contains locale specific literal, and then uses request.setCharacterEncoding(“UTF-8”) to get the submitted data correctly.
Note: If you use GET XMLHttpRequest and append the data parameters to URL, please make sure that the Web server parses the URL using the correct encoding, because request.setCharacterEncoding(“UTF-8”) only deals with the request body but not the URL itself. For example, in Tomcat server.xml, there will be a configuration item named URIEncoding. Please set its value to UTF-8, so that Web server will use UTF-8 to parse URL parameters.
5. Limitations
The Dojo Car Store is for demo purpose only, so all the data is fictional. If occasionally you find the page is not rendered correctly, it may be caused by a browser cache problem. Please restart your browser and try again. If the problem still exists, please check your server and database.
To install the Hello World sample and demo application, first download dojo-g11n-helloworld.zip and DojoGlobalizationDemo.war from http://TODO. The dojo-g11n-helloworld.zip file contains the Dojo G11N Hello World sample, and the DojoGlobalizationDemo.war file containes the Dojo Car Store and Dojo G11N samples.
1. Apache Tomcat 5.5 + Java Development Kit 5.0 (Sun or IBM)
a. Make sure that your Java Development Kit 5.0 environment is ready.
b. Download Apache Tomcat 5.5 from Apache Tomcat Home and install it
(Suppose the installation directory of Tomcat is {TOMCAT_HOME}).
c. Copy DojoGlobalizationDemo.war to the directory {TOMCAT_HOME}/webapps.
2. (Optional) WebSphere Application Server Community Edition 1.1
1. DB2
a. Create a database in UTF-8 encoding.
b. Create tables and insert data using db.sql under DojoGlobalizationDemo.war/DB/.
c. Get java DB2 driver(db2jcc.jar, db2jcc_license_cu.jar), like in windows, they will be under
C:\Program Files\IBM\SQLLIB\java, and add them to DojoGlobalizationDemo.war/ WEB-INF/lib
d. Update the configuration in db.properties under DojoGlobalizationDemo.war/DB/, for example,
#DB2 configuration
driver=com.ibm.db2.jcc.DB2Driver
url=jdbc:db2://9.181.106.125:50000/DOJODEMO
user=db2admin
password=passw0rd
Or
Derby client mode 10.1.3.1
a. Add derbyclient.jar to DojoGlobalizationDemo.war/ WEB-INF/lib (you can get derbyclient.jar from Derby Home Please choose version 10.1.3.1)
b. Update the configuration in db.properties under DojoGlobalizationDemo.war/DB/, for example,
#client mode derby configuration
driver=org.apache.derby.jdbc.ClientDriver
url=jdbc:derby://localhost:1527/DojoCarStoreDB;create=true
user=user
password=password
2. WebSphere Application Server Community Edition 1.1
a. Download WAS CE from IBM WAS CE Home and install it (suppose the WAS CE installation directory is {WAS_CE_HOME}. In Windows, it may be C:\Program Files\IBM\WebSphere\AppServerCommunityEdition).
b. Launch the WAS CE server from the Windows start menu or {WAS_CE_HOME}\bin\startup.bat.
c. Launch the administrator console at https://localhost:8443/console
d. Click Deploy New on the left Console Navigation pane, locate the DojoGlobalizationDemo.war, leave all the options with default values, and install it.
e. Switch to Web App WARs on the left Console Navigation pane, and make sure that the newly installed DojoGlobalizationDemo/DojoCarStore/0.9/war application is running.
1. Access Dojo Globalization Hello World by extracting dojo-g11n-helloworld.zip, for example, in to the {Dojo_G11N_HW_DIR} directory, and open the Dojo_G11N_HW_DIR}/HelloWorld.html file in your browser offline.
This section introduces the first Hello World for Dojo Globalization. This Hello World application is pure HTML plus Dojo, therefore you can access it either offline or online. Please refer to Section 2.4 for detailed steps of accessing it.
After you have accessed the Hello World application for Dojo Globalization, you can switch to different locales, you will see the literal changes of Hello World, for example,
en-us:
Screen shot goes here
zh-cn:
Screen shot goes here
2. Access the Dojo Car Store application through http://localhost:8080/DojoGlobalizationDemo/DojoCarStore
3. Access the Dojo Globalization Sample through http://localhost:8080/DojoGlobalizationDemo/DojoG11NSample.html or extract the DojoGlobalizationDemo.war file, for example into the {DojoGlobalizationDemo_DIR}directory, and open the {DojoGlobalizationDemo_DIR}/DojoG11NSample.html file in your browser offline.
This section introduces the first Hello World for Dojo Globalization. This Hello World application is pure HTML plus Dojo, therefore you can access it either offline or online. Please refer to Section 2.4 for detailed steps of accessing it.
Use the following steps to create an application similar to the Hello World application for Dojo globalization:
1. Include dojo bootstrap – dojo.js, and declare the locales that will be used later.
/* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */
.geshifilter {font-family: monospace;}
.geshifilter .imp {font-weight: bold; color: red;}
.geshifilter .kw1 {color: #000066; font-weight: bold;}
.geshifilter .kw2 {color: #003366; font-weight: bold;}
.geshifilter .kw3 {color: #000066;}
.geshifilter .co1 {color: #009900; font-style: italic;}
.geshifilter .coMULTI {color: #009900; font-style: italic;}
.geshifilter .es0 {color: #000099; font-weight: bold;}
.geshifilter .br0 {color: #66cc66;}
.geshifilter .st0 {color: #3366CC;}
.geshifilter .nu0 {color: #CC0000;}
.geshifilter .me1 {color: #006600;}
.geshifilter .re0 {color: #0066FF;}
2. Declare packages for later use.
dojo.require("dojo.date.locale");
dojo.require("dojo.string");
……
3. Register a resource bundle module for the hello world application.
dojo.registerModulePath("my.helloworld","../../helloWorldResource");
4. Actions to take when you switch locales:
- Set global dojo locale.
dojo.locale = lastIndexOf("locale=") >= 0 ?
substring(lastIndexOf("locale=") + "locale=".length) : "en-us"; // default locale is en-us
- Load JSON resource bundle for hello world.
dojo.requireLocalization("my.helloworld", "helloworld");
resourceBundle = dojo.i18n.getLocalization("my.helloworld", "helloworld");
- Format date using dojo.date.locale api, and format template strings using dojo.string api.
dojo.string.substitute(resourceBundle.contentStr,
[dojo.date.locale.format(new Date(), {selector:'date', formatLength:'long'})]);
- Update UI.
dojo.byId('content').innerHTML = ……