-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Retrieve available locale name #30
Comments
Considering you are using Cldr.setAvailableBundlesHack = function(availableLocales) {
availableLocales.splice(availableLocales.indexOf("root"), 1);
this._availableBundleMapQueue = availableLocales;
};
Promise.all([
request.get('path/to/cldr-data/availableLocales.json'),
request.get('path/to/cldr-data/supplemental/likelySubtags.json')
]).then(function ([ localesResponse, likelySubtagsResponse ]) {
// Load required data.
Cldr.load(likelySubtagsResponse.data);
Cldr.setAvailableBundlesHack(localesResponse.data.availableLocales);
let bundle = new Cldr(navigator.langugage).attributes.bundle;
return Promise.all([
request.get(`path/to/cldr-data/main/${bundle}/numbers.json`),
request.get(`path/to/cldr-data/main/${bundle}/currency.json`)
]).then(function ([ numbersResponse, currencyResponse ]) {
Cldr.load(numbersResponse.data, currencyResponse.data);
return new Cldr(locale);
});
}).then(function (cldr) {
// use cldr.get()
}); Considering you are using unresolved data. Then, you must load Did I answer your question? Please, just let me know. I'm keeping this issue opened for discussion on whether .setAvailableBundles should be implemented. |
I think |
I'd like to add a vote to add this functionality, too. And to also make sure it is easily accessible from a user of As a developer, I really don't want to have to deal with mapping my supported locales over to the proper cldr filenames; I'd love it if cldrjs/globalize would automatically tell me which files to load to support a given locale string. The above code does seem to work for me (in node.js), although I'm not getting a match for two locale strings which should have proper mappings. Is this a CLDR data issue?
@rxaviers I'm a little unclear on the "unresolved data" comments above. Do I need to worry about loading all of the parent chains, as well? For example, I notice that |
@bryanforbes and @dpolivy, I know it may sound unrelated. But, could you both share with me your development stack? I mean, how do you organize your files, what tooling do you use to bundle the built files for production? This might shed more light into how to address this problem. Thanks |
@rxaviers See globalizejs/globalize#460 as a starting point. At the moment, I am working to globalize our server-side components built on node.js and express. We use Starting at a high level, our core site is built on Windows (Classic ASP), and as such uses Windows LCIDs for determining date/currency handling. Each user has an LCID associated with their profile. Our Mobile site/apps are built on node.js. So, step one for me is mapping Windows LCIDs to proper locale strings (and ISO currency codes). I just wrote a simple .NET application to iterate through our supported LCIDs, and output the Name and ISO Currency Code to a JSON file that maps LCIDs to those values. In node, I am building an internal i18n module that:
Hopefully that makes sense. The challenges I have had so far are that I just want to specify "here are the locales we support", and have |
Please, see my reply about Globalize-only things in here: https://gist.github.com/rxaviers/fbca34ead79440b7f16f. (cc @kborchers)
Thanks, it did help. Knowing your environment and that you're using Globalize and Cldrjs on the server side (on Node.js) helps shaping my answer below. Let's first define "load the right CLDR files" as (a) for each supported locale, load the right bundle, and (b) for each bundle, load the right set of JSON files (e.g., gregorian calendar, numbers, etc). For (b), it's easy. You'll need to load at least the files of this table https://github.com/jquery/globalize/#2-cldr-content for Globalize. For (a), it's important to notice that cldrjs (or Globalize) doesn't do I/O to avoid diverging from its original scope (more details in globalizejs/globalize#405 (comment)). Therefore, it doesn't load the data. But, it expects developer to load the data and feed the library on it. Having said that, I understand your problem, I will give some suggestions below, and I'm open for feedback. On the server-side, you can
Cldr = require("cldrjs");
Cldr.load(require("cldr-data").entireSupplemental());
Cldr.load(require("cldr-data").entireMainFor("en", "es", "zh"));
var en = new Cldr("en"); Above, it will load the entire supplemental data plus the entire main data (calendars, numbers, etc) for the English, Spanish, and Chinese locales. (replace cldrjs by Globalize if you will) If you have a limited set of supported locales, it's not hard to use the above code to load the data you need and then use cldrjs or Globalize. If your supported set of locales is almost the entire CLDR (or the entire CLDR), you could: Cldr.load(require("cldr-data").all()); Does that work for you? If not, what are your supported locales? To know what the CLDR available locales are, see https://github.com/unicode-cldr/cldr-core/blob/master/availableLocales.json. Currently, Unicode publish two different coverages: modern (the default installed with I'm trying to avoid the long explanation. Because, there's no direct mapping between a desirable locale and a bundle. It depends on the given available bundles. See details in https://github.com/rxaviers/cldrjs/blob/master/doc/bundle_lookup_matcher.md and I'll be happy to answer to any questions. As you can see, there are a lot of improvements to be done in our docs and help improving them (or any other contribution) is very much appreciated :).
Assume you're using resolved data unless you're building the data yourself (via Unicode tools). Therefore, you don't need to worry about loading the chain yourself.
This is a bug that needs a fix #29. |
Thanks, this is really helpful! The approach to loading looks a little simpler than what I am currently doing (basically, Now, it seems that I need to map my I suppose I could just load all bundles. What's the "cost" of doing that, if they're never used? Just some startup perf and memory to keep the structures around? |
Yeap, if you want to map your
CLDR doesn't include data for If you consider it's safe to have
Globalize doesn't export the cldrjs object. Because, there's no point on doing so for normal usecase. :) |
@dpolivy I have also added one more comment at https://gist.github.com/rxaviers/fbca34ead79440b7f16f (gist doesn't notify) |
I agree with your philosophy here, in that developers shouldn't worry about setting up bundles, and the library shouldn't do an I/O. But that gap still needs to be bridged in a way that's easily accessible to the typical developer, who may not be an i18n specialist, and just needs to check a box that says "allow date/number/currency formatting based on a user's locale". I expect most developers approach this in terms of having a list of locale strings (language-region subtags) -- or even LCIDs in the Windows case -- and just expecting it to work. How do other companies/products that use CLDR data do the mapping from language-region subtags to bundles? Or do they just load all of the data, so it's a non-issue? If there were a One other thing I'm still not clear about -- will I need to load any parent bundles in addition to language specific ones? e.g., if I load en-GB, do I also need en for it to work properly? Or does that not matter since I'm using cldrjs. I also added a comment in the gist. |
Sorry for the delay in getting back to you. It's been a crazy week! I and a co-worker are currently developing https://github.com/dojo/i18n to wrap Globalize to provide an automatic loading mechanism for language and localization information. The current proposed API is: let i18n = new I18n({
locale: 'en-GB' // this is optional; if not provided, the system locale will be used
});
i18n.load().then(() => {
// use any functions based on CLDR data
i18n.formatCurrency(1, 'USD' /* options object can follow */);
});
i18n.loadBundle('widgets/messages/Dialog').then((bundle) => {
// use messages defined in the bundle
bundle.get('close' /* variable arguments follow */);
// or use them from i18n
i18n.getMessage('widgets/messages/Dialog' /* variable arguments to follow */);
}); This loading mechanism is pretty simple for The loading mechanism for message bundles becomes a bit trickier. I want to allow The tricky part is determining which unresolved bundles to load. Let's say a library or application has the following locales translated and they are unresolved:
The loading mechanism will obviously need a way to know which locales are translated (to be determined), but once it has that information, how can it take the user's locale and determine which bundles to fetch to load into Globalize? Cldrjs has a very well-defined mechanism for determining which unresolved data to use, but it's not public. We have had this conversation on IRC a while back and the Obviously there are some other things to figure out (where the available locales for bundles get stored, how to have separate available locale lists for different bundles, etc.), but the big sticking point for me (as a developer of a loading mechanism for unresolved data) is knowing which bundles to load. You said:
I'd argue that developers should need to know how to set up their message bundles, but that their message bundles should Just Work™ when they say to load a named bundle. A developer shouldn't need to know which unresolved data to fetch to load into Globalize, something should do that for them. And that's the API I'm writing. I hope you can see how this would greatly benefit developers. |
I agree. I'm open to suggestions. I believe this gap will be filled by higher level libraries (perhaps with narrower scope) that uses cldrjs underneath.
The mapping from a language-region (or in a general sense, a locale) to a bundle is well defined and more details can be found here https://github.com/rxaviers/cldrjs/blob/master/doc/bundle_lookup_matcher.md. The question about how other companies/products handle the data is a very good (and broad) question. I'd love to have input and some solid data here. As far as I can tell there are two different worlds: implementations for backend vs. frontend, where requirements for each are quite different. Examples of implementations for backend are ICU (for C or Java) and its wrappers (for Ruby, Python, Perl, PHP, etc); and as far as I know, ICU expects CLDR data to be available under a given location and a well defined structure and it handles the loding by itself; the data is usually in the LDML format and unresolved; large space and multiple access to this data aren't problems in such environment. In the other hand, implementations for frontend have different requirements; the fewer the accesses the better, therefore CLDR data is usually preferred resolved. Some frontend implementations like the ibm-js/ecma402 polyfil handles the loading by narrowing the choices: it uses AMD and expects the CLDR data to be located in a certain way. Other frontend imlementations like the andyearnshaw/Intl.js preprocesses the data and distribute kinda compiled bundles only (https://github.com/andyearnshaw/Intl.js/blob/master/locale-data/jsonp). Cldrjs is a CLDR traverser. Its goal is to support a wide set of different environments (including backend and frontend ones) and its goal is to abstract some of the nuances of the UTS#35 speciciation to facilitate the creation of libraries that use CLDR data.
Assume you don't need to worry about loading the chain yourself unless you're building the data yourself (via Unicode tools). To understand the difference between resolved vs. unresolved data: unresolved data optimizes space; resolved data optimizes access. Unresolved data avoids duplication (for example, all duplicate fields of en-GB lives in its parents: en or root). |
@bryanforbes, I'm very excited for dojo/i18n.
Feel free to submit a new issue or PR with ideas (potentially describing a desired API) for this particular problem. All that occurs me is either exposing parent_lookup publicly or being able to use an event for that. For example, I am wondering if cldrjs could trigger an event called var hasFetched = {};
Cldr.on("parentLookup", function(locale) {
if(!hasFetched[locale]) {
fetch(locale) && hasFetched[locale] = true;
}
});
Off-topic, but this could be of interest: globalizejs/globalize#436
I agree. Off-topic, but dojo/i18n could eventually be listed under Globalize's examples. Please, submit a PR when you have something to show. |
In the
cldr-data
packages isavailableLocales.json
. This tells users what locales are available within the data. I would like to use this to determine which locale files to load on the fly, however I don't see a way to seed theCldr
available locales or use an array of locale names to get the effective locale name based on the user's locale. Essentially, I'd like to do something like this:Using this technique, I could use this to see the
globalize
data as well and create a promise-based API for loading only the locale information needed at any given time.The text was updated successfully, but these errors were encountered: