Login Register

Locale and Resource Bundle

You must set djConfig.locale in all files to the same as the locale used by the server code.
You must always use resource bundles to store the strings displayed to users.
You may use djConfig.locale to set the default locale and extra locales, and use only dojo.requireLocalization without the locale parameter.
You should make a build to include resource bundles in the locales that you use.

Locale Setting in Dojo

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 personalization

If 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('_', '-');
%>

...


Resource Bundle Files

You must always use resource bundles to store the strings displayed to users.

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.

Using Resource Bundle

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.



Builds

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 use

Resource 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.



Translation

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}

Example of Resource bundle

Hi,
I would appreciate an example of a resource bundle file that corresponds to your file structure. On the page "Formatting and Validation", I found the following example:

{
FILE_NOT_FOUND_IN_DIR: "File '${0}' is not found in directory '${1}'.";
}

However, that is not valid javascript.
thanks,
Ben

it's valid, except for the semi-colon

(I'll fix the semi-colon part...) What needs to be emphasized is that resource bundles are JavaScript data structures, not statements. What you see here is essentially a definition for an object. If you wrapped it in parenthesis and/or put an assignment before it, it would be perfectly valid. Think of the resource bundles as JSON.

Must set djConfig.locale in all files to the same as the locale

The assumptions here are not correct; Dojo can determine the browser's locale in most or all browsers. The default is not en-US but whatever locale that particular browser supports; when you download Firefox or IE, you generally get to choose an edition for a particular locale. Generally speaking, you're stuck with that locale. (As mentioned in the docs about locales, the browser preferences setting is for HTTP headers only)

djConfig is for setting a locale to something other than what the browser wants. Users may not have a browser installed that suits their locale the way they'd like, or perhaps someone else is using their machine? If you have a server with personalization features or a web app which might offer a locale choice, this can be made effective by inserting a djConfig.locale setting on each Dojo page. So, I think setting djConfig.locale is a should or a may.

information on locales may be redundant with specifying a locale

locale directories MUST be specified in lower-case

locales in Dojo are case in-sensitive, but the docs for dojo.requireLocalization state (I believe) that the subdirs like zh-cn must be lowercase so that they can be compared with normalized locales.

As noted in http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-... Dojo is actually following an RFC spec as HTML does... unlike Java :-)

Your big blue roots are showing :)

Dojo uses JSON files for resource bundles, but JSON files are not well supported by many current translation tools like Translation Manager and CHKPII.

Having once worked on the other side of the fence from TM/2 and CHKPII, I can safely say that this phrase is meaningless to non-IBMers (as TM/2 and CHKPII are not available to the world at large) and should be pulled from The Book of Dojo.

The open source world largely uses gettext format (PO template files) as the standard translation format. It would be nice to see something like Translate Toolkit (http://translate.sourceforge.net/) be taught how to round-trip Dojo's resource bundles to PO.

IBM references removed

Yeah, sorry, this documentation did originate in IBM. Removed to make it a bit more general. So there is still talk about including support for XLIFF translation, though PO does seem much more popular in OSS. We could provide tools to round-trip with the PO format or integrate with specific tools. We're open to suggestions (and contributions!)

"Should make a build to include resource bundles" section.

The "Should make a build to include resource bundles in the locales that you use" section is confusing. Does it mean that your build process should automatically create empty resource bundles for all locales that might be encountered? The sentence "Without optimization..." is also confusing. What is meant by optimization here?

On a related note, I'm getting 404 errors saying ".../nls/en-us/myfile.js" and ".../nls/en/myfile.js" (I only have /nls/myfile.js defined), which looks rather ugly in my console. Does this mean every time I create a new resource bundle, I need to create en and en-us versions of it too (and en-xx versions for every possible English speaking country)? Or can the dojo.i18n.getLocalization() function be modified to quietly ignore these 404 errors?

404 errors are handled

they're caught and handled in JS, but the fact is they still occur on the server, and that's what you're seeing in firebug. They're harmless, but annoying if you look at the console, and the fact that there's an extra web hit or two to the server can be a performance problem. Dojo has to search for them at development time, since it doesn't know which locales are present on the server. So, that's where the builds come in. When you run the build process, it flattens out the locale search path so each full locale has its own separate file. Dojo makes one request to the server, it's always there, and all the data comes down in one request.

This is also explained here: http://www.dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-...