Let's assume that you've gotten with the times and expanded on
your magic genie module from the "Building a Magic Genie Example
Module" in Chapter 2 to
produce a psychic
module. Let's
assume that your default language is English, and you've determined
that the first additional language you should support is
Spanish.
Like any other module, your psychic readings module should simply be a source file contained in a typical directory structure:
dtdg/ psychic/ Psychic.js /* Lots of useful stuff in here */
Not surprisingly, an incredible utility provided by your
psychic
module is the ability to
predict the future. As such, users of your module might stick it in
a page and use it like so:
<script type="text/javascript"> dojo.require("dtdg.psychic"); dojo.addOnLoad(function( ) { dtdg.psychic.predictFuture( ); }); </script>
Although there's an awful lot of real
magic that happens in the predictFuture
function, the part that
we're interested in at the moment is where a String
value actually gets written to the
screen because that's where the internationalization work happens.
As it turns out, the output from your module gets written out with
the following logic:
dojo.byId("reading").innerHTML = predictFuture( /* magic */ );
As a first stab at internationalization, start out with plain
old English and plain old Spanish, ignoring any particular dialects.
Given this decision, the nls
directory might look something like the following:
dtdg/ psychic/ Psychic.js nls/ readings.js /* The default English translation bundle */ es/ readings.js /* The Spanish translation bundle */ en/ /* The default English translation folder is empty, so Dojo looks one level up for it in the nls/ directory */
By convention, each of the .js files
containing translation information is called a
bundle. The convention used is that the default
translation bundle appears in the top level of the nls
directory, but not in a
language-specific directory. The basic rationale for this convention
is that you always want a default translation to be available in the
nls
directory, which is the most
logical place for it, and there's no value in including an exact
copy of the default translation bundle in its own directory,
(en
in this case) because that
would just be one more thing to keep up with.
Here's an excerpt from each of the readings.js files that shows some of the strings that are translated as part of the final reading.
First, the default readings.js file:
{ /* ... */ reading101 : "You're a Libra, aren't ya darling?", reading102: "Can you please tell me your first name only, and your birthday please?", reading103: "Yep, that's the Daddy." /* ... */ }
And now, the es/readings.js file:
{ /* ... */ reading101 : "¿Eres un Libra, no, mi corazón?", reading102: "¿Me puedes dar el nombre y tu cumpleaños por favor?", reading103: "SÃ, el es papá" /* ... */ }
One of the beautiful things about localizing your application with Dojo is the simple manner in which you provide the listing of tokens.
It's time to put it all together and show just how easy it is to support multiple languages, but first, have a look at the relevant functions, listed in Table 6-1, that are involved in the process.
Table 6-1. Localization functions
Name | Comment |
---|---|
| Returns an |
| Returns the canonical form of a locale. |
| Loads translated
resources in the same manner as |
Whereas you previously might have looked up reading102
value from a hash value like
psychic.reading102
, you now do it
with help from the toolkit. If you've provided a translation for a
particular user's locale, everything "just works." Looking up
symbols for your various translations is as simple as the following
generic piece of logic:
/* Require in Dojo's i18n utilities first... */ dojo.require("dojo.i18n"); /* Then, require in your various translations */ dojo.requireLocalization("psychic", "readings"); function predictFuture( ) { /* Deep inside of your predictFuture function somewhere... */ var future= dojo.i18n.getLocalization("psychic", "readings").reading597; return future; }
Note that you can change your value of dojo.locale
if you'd like to test out
various translations. A good place to change this value is in
djConfig
block. Here's an example
of how you might test out your Spanish translation from a local
installation:
<head> <script type="text/javascript" src="your/path/to/dojo.js" djConfig="dojo.locale:'es'"> </script> </head> <!-- All of your internationalized modules now use the Spanish translation -->
Warning
Just like any other module or resource, don't call dojo.i18n.getLocalization
as part of an
object property definition; instead, call dojo.i18n.getLocalization
in a dojo.addOnLoad
block:
dojo.addOnLoad(function( ) { //Returns a localized Object var foo = {bar : dojo.i18n.getLocalization( /* ...*/)} });
A nuance you may want to be aware of is that if your default locale is a variant of English and you are testing the Spanish localization, both the nls/es/readings.js and the nls/readings.js bundles are loaded. In fact, the default bundle that is contained in the nls/ directory will always be loaded. You can use Firebug's Net to verify this behavior for yourself.
Although this particular example didn't involve any dialects
of either language, note that dialects are most certainly taken into
account when loading localized bundles. For example, if your locale
was en-us and there had been an en-us bundle
provided, Dojo would have attempted to load both the
en-us bundle and the en
bundles, flattening them into a single collection for you to query
via your various dojo.i18n.getLocalization
calls. The
working assumption is that when defining locale specific symbols for
English, you want to provide as much general information as possible
in the en bundle and then override or fill in
gaps inside of the dialect specific bundles such as
en-us.
As a final yet very important observation about internationalization, note that the Dojo build tools provided in Util can automatically take care of the myriad details associated with minimizing the number of synchronous calls and data redundancy when you perform a custom build of your module. It may not seem like much at first, but the build tools combine what could be lots of small resource files together and avoid all of the lookups and the latency that goes along with them. In terms of a snappy page load, it can really make all the difference. Util and the build tools are discussed in Chapter 16.
Get Dojo: The Definitive Guide now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.