Consider dojo.requireLocalization(moduleName, bundleName, locale, availableFlatLocales).
What does dojo.requireLocalization("happy", "birthday") do? It depends...
In a development environment there will be no parameter provided for availableFlatLocales. The moduleName is resolved against the module prefix provide via djConfig.modulePaths.
Oddly a "/" is expected to terminate the path, with code explicitly adds one if it's missing. In this case "/happy" become "/happy/". But providing "/happy/" causes an extra "/", which causes failure with some servers. Specifically, i18n._requireLocalization invokes i18n._searchLocalePath with a search function which contains this code:
var syms = dojo._getModuleSymbols(moduleName);
var modpath = syms.concat("nls").join("/");
Don't provide a trailing slash in your modulePaths definitions:
var djConfig = {
useXDomain: false,
baseUrl: "http://localhost:52987",
modulePaths: {
"happy": "/happy", // do not add a "/" to the end
"dojo.nls.dojolab_en-us": "/scripts/dojolab_en-us"
}
};
If it *is not* considered an xdomain path...
dojo._xdRealRequireLocalization is a pointer to the original implementation of dojo.requireLocalization, which is later replaced with a wrapper. When not an xdomain path the original/real code is executed, which itself is a thin wrapper for i18n._requireLocalization.
Consider i18n._requireLocalization(moduleName, bundleName, locale, availableFlatLocales).
If no locale is provided dojo.locale is assumed. A bundle is constructed with the name moduleName.nls.bundleName. In this case the bundle is "happy.nls.birthday".
In a development environment availableFlatLocales is not provided. When availableFlatLocales is provided a "best locale" calculation finds the closest match to the locale (en-us may resolve to en), otherwise the actual locale is used.
If the bundle is not found in the list of loaded modules, the bundle is added to the list of loaded modules via dojo.provide. A module path is calculated by appending a "nls" after the symbol path. In this case that would be "/happy/nls" (or "/happy//nls" if you did not heed my warning).
It now attempts to get the localization files for the locale. If the locale is "en-us" this means searching for "ROOT", "en", "en-us".
If "happy.nls.birthday.ROOT" is not already registered as a loaded module it is registered and the associated script is loaded. In this case it looks for "/happy/nls/birthday.js". It repeats for en and en-us, loading "/happy/nls/en/birthday.js", "/happy/nls/en-us/birthday.js". The resulting bundle contains a property for each of ROOT, en, en-us. In this case the bundle has no ROOT and no en values because resources were only provided for en-us:
{"ROOT":undefined,"en":undefined,"en_us":{"HappyBirthday":"Happy Birthday!"}}
Requesting localization for "en-us" results in three trips to the server to construct a bundle containing resources for ROOT, en, en-us.
Is it possible to do this in one request?
Consider i18n._preloadLocalizations(bundlePrefix, localesGenerated).
This method also invokes _searchLocalePath, but with down=true so instead of looking for ROOT, en, en-us it reverse the search order. It first looks for and loads the "dojo.nls.dojolab_en-us" module. If no module path is provided for "dojo.nls.dojolab_en-us" or "dojo.nls" it finds "dojo" and resolves to the CDN, in this case "http://o.aolcdn.com/dojo/1.5.0/dojo/nls/dojolab_en-us.js".
Provide a module path for "dojo.nls" or "dojo.nls.dojolab_en-us" or explicitly include the localization files with a <script>.
If i18n._preloadLocalizations finds a localization file it immediately stops searching for more. The assumption being that the en-us file must contain the full spectrum of resource text and does not need to get any data from en or ROOT. This happens because i18n._preloadLocalizations assumes the most specific localization file contains all the resources. This method is reserved for compiled code and rightly so. The specific localization file contains resources for multiple namespaces when generated via the build:
dojo.provide("dojo.nls.dojolab_en-us");
dojo.provide("dijit.nls.loading");
dijit.nls.loading._built = true;
dojo.provide("dijit.nls.loading.en_us");
dijit.nls.loading.en_us = {
"loadingState": "Loading...",
"errorState": "Sorry, an error occurred"
};
dojo.provide("dijit.nls.common");
dijit.nls.common._built = true;
dojo.provide("dijit.nls.common.en_us");
dijit.nls.common.en_us = {
"buttonOk": "OK",
"buttonCancel": "Cancel",
"buttonSave": "Save",
"itemClose": "Close"
};
When dojo.requireLocalization is invoked a bundle is created via a callback to dojo._loadPath, which eval's the localization file and passes the result to the callback. The callback adds this result to the bundle. That doesn't make sense when resources are bundled together, as with the build resources. In that case dojo._loadPath is invoked indirectly from _preloadLocalizations via dojo.require and no callback is provided.
Observation -- compiled resources are modules and are loaded via dojo.require and not dojo.requireLocalization.
When not in an xdomain environment it appears to be the case that the only way to eliminate multiple trips to the server for resources is to perform a custom build. I suspect the same is true for xdomain loading, in which case the conclusion is that in order to avoid multiple trips to the server for a resource it is necessary to perform a custom build.
If it *is* an xdomain path...
not sure yet.
No comments:
Post a Comment