-
Notifications
You must be signed in to change notification settings - Fork 9
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
Semantics of locales argument to MessageFormat #18
Comments
I don"t think i understand your question. You pass locale list that is used to resolve formatters used by the message. If you want it to be just one locale, you can pass one locale. (And realize that if it doesn"t resolve intl API will fallback on default - so it still is a two element list just that second locale is implicit) |
Consider for instance some point in your code where you"re currently calling |
What I meant specifically are cases where the selected locale directly influences the interpretation of the message itself. For example:
In other words: Formatting a message written for one locale with a different resolved locale (especially for plural rules) can create very bad artifacts, up to rendering wrong values. I"ve seen these kinds of bugs in real code. Most developers and translators I"ve worked with aren"t familiar with the finer details of cross-locale formatting issues (understandably). |
That"s correct, but that is the nature of language fallbacking. What your second snippet states, is analogous to as if the developer passed: const source = ... // string source of the message as above
const mf = new Intl.MessageFormat(source, ["fr-CA"]);
const notifications = mf.resolveMessage({ count: 0, totalAmount: 0 });
// If locale ended up resolved to en-CA: "You have 0 items in your cart for a total of 0"
// If locale ended up resolved to fr-CA: "You have one [sic!] item in your cart for a total of 0"
notifications.toString(); Your suggestion to only allow for a single locale feels to me like a common fallacy that I observe within the localization system"s community - the idea that a single locale is better because it doesn"t allow for fallback. const source = ... // string source of the message as above
const mf = new Intl.MessageFormat(source, "en-CA"); // <-- notice single locale
const notifications = mf.resolveMessage({ count: 0, totalAmount: 0 }); // <-- here PluralRules didn"t have data for `en-CA`.
assert(notifications, undefined); // or throw exception And I have never seen such system. API designers therefore first limit fallback to avoid mistakes, and then relax the error scenario to avoid exceptions. If you, therefore, are not ready to error out on misalignment, then, IMO, you are in fact always operating on fallback lists. Your single locale case becomes a list of The only difference between such case and what we"re proposing is that in our case you allow to build Assuming you agree with my position, my recommendation is to start using chained language negotiation. What should happen depends on how we design internal language negotiation of MessageFormat. There are generally two options (with some nuance). Option 1 is that internal matching is "simple". In such model if I pass If is the case, then as a consumer of our API you need to get the right fallback: const messageLocale = `en-CA`;
const availablePluralLocales = Intl.PluralRules.availableLocales();
const supportedLocales = negotiateLanguages(messageLocale, availablePluralLocales);
if (supportedLocales.length === 0) {
// handle lack of any match
}
assert(supportedLocales, [en-US, en-GB, en]);
const source = ... // string source of the message as above
const mf = new Intl.MessageFormat(source, supportedLocales);
const notifications = mf.resolveMessage({ count: 0, totalAmount: 0 }); In this case we "moved" the negotiation completely to the customer side. There"s a "mixed" approach model, where some level of negotiation happens internally. Where and how is debatable, but we"ll need to make such decision for all transitive Intl APIs. MessageFormat is just the first and likely most complex chained Intl API. In the mixed model, for example, we could say that In such scenario, it"s enough that you pass To visualize the problem, I think it"s better to not use So, what if the message is in If we do what you suggest, we end up either erroring out, or falling back on some internal In the model we propose, we allow the customer to inject additional better fallback between preferred locale and this implicit last fallback, or erroring out. For example, if the message has a date, we could say "Customer speaks french and german, the message is in French, so please, try to use french to format the date, but if you don"t have any french, please, format the date to german, and embed it in this french message. If you don"t have either french or german, then do X" where "X" means to either use last fallback, or error out. Does that make sense? In other words, instead of asking if And if your solution is to use implicit last fallback, then such |
Besides the language fallbacking mentioned by @zbraniecki above, the original message you propose is also a bit problematic:
Specifically, the |
Definitely! In the past, I literally added hard validations to some i18n tooling I maintained to force My primary argument here is that creating the appearance that I"m sure there are others (and yes, erroring if none of the explicitly requested locales provides message-affecting data like plural rules is one of them). But as the README of this proposal proves (to me at least), assuming that nobody makes the mistake of baking assumptions about exact plural rules into the message template is a questionable bet. |
That"s a great point. I also want to suggest that we should fix it. PRs welcome :)
I think I"m leaning toward such solution. In our lingo we would call it "selector" vs "formatter". Formatter should operate the way other formatters do, but we should take your feedback and evaluate how selector locale fallback should work.
Please, do not imply what has not been stated. Nobody claims that.
I agree with your problem statement. I disagree with your solution proposed. |
Revisiting and re-reading this, I"m tempted to conclude that we should continue to support an array Also, as relevant prior art, |
It seems that
MessageFormat
is fundamentally different from things likeNumberFormat
because the message text argument is very much locale-specific but doesn"t participate in option resolution. Would it be more meaningful to either only accept a single locale in the options or to allow specifying different message templates based on which locale is supported by the host environment?The text was updated successfully, but these errors were encountered: