Skip to content

Message: fix selectOrdinal. #639

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

Closed
wants to merge 1 commit into from

Conversation

nkovacs
Copy link
Contributor

@nkovacs nkovacs commented Oct 15, 2016

The plural fuction used for messages only supported cardinals,
not ordinals. This meant that selectOrdinal used the cardinal
rules, not the ordinal rules.

If the type option passed to Globalize.pluralGenerator is "both",
the returned function accepts a second parameter. If this
parameter is true, the function will return the ordinal category
instead of the cardinal category.
This is how messageformat.js expects the plural function to work.

This introduces a minor BC break, because supplemental/ordinals.json must be loaded (I've fixed all the examples), although the documentation does suggest you need both.

The plural fuction used for messages only supported cardinals,
not ordinals. This meant that selectOrdinal used the cardinal
rules, not the ordinal rules.

If the type option passed to Globalize.pluralGenerator is "both",
the returned function accepts a second parameter. If this
parameter is true, the function will return the ordinal category
instead of the cardinal category.
This is how messageformat.js expects the plural function to work.
@rxaviers
Copy link
Member

Related to #563

@nkovacs
Copy link
Contributor Author

nkovacs commented Nov 21, 2016

Regarding your question there:

About plural requiring cardinal + ordinal data... I want to avoid that. I'm wondering if {plural, ... could use a cardinal formatter, and {selectordinal, ... could use a ordinal formatter?

Here are two example messages:

  • This is the {cat, selectordinal, one{#st} two{#nd} few{#rd} other{#th} } category.
  • This is the {cat, plural, one{#st} two{#nd} few{#rd} other{#th} } category.

The problem is that messageFormatterRuntimeBind sees this:

  • function (d) { return "This is the " + plural(d.cat, 0, pluralFuncs.en, { one: function() { return number(d.cat) + "st";}, two: function() { return number(d.cat) + "nd";}, few: function() { return number(d.cat) + "rd";}, other: function() { return number(d.cat) + "th";} }, 1) + " category."; }
  • function (d) { return "This is the " + plural(d.cat, 0, pluralFuncs.en, { one: function() { return number(d.cat) + "st";}, two: function() { return number(d.cat) + "nd";}, few: function() { return number(d.cat) + "rd";}, other: function() { return number(d.cat) + "th";} }) + " category."; }

I've highlighted the 1 in the first message which indicates to the plural function that it should use ordinals.
This would be difficult to find with a regexp; I'd have to parse the javascript properly to make it 100% correct, and that's just overkill.
With the custom compiler in #563, it should be much easier to do this. So, with that in mind, do you think it would be best to abandon this, and implement it with a separate ordinal formatter as part of #563?

@rxaviers rxaviers added this to the 1.3.0 milestone Mar 17, 2017
@rxaviers rxaviers removed this from the 1.3.0 milestone May 29, 2017
@rxaviers rxaviers added this to the 1.4.0 milestone Jun 15, 2017
@dantman
Copy link
Contributor

dantman commented Jul 11, 2018

So is this going to be fixed? I was just writing tests after integrating Globalize based message handling and realized that selectordinal doesn't actually work. Should I have not picked Globalize to handle i18n messages?

@rxaviers
Copy link
Member

This introduces a minor BC break, because supplemental/ordinals.json must be loaded (I've fixed all the examples), although the documentation does suggest you need both.

Thanks for bringing this up. It indeed could break existing apps. We could conditionally-enable it only if such CLDR data is loaded, which would prevent to break existing apps, but internal logic would be a little convoluted and error handling in case someone intends to use ordinal but forgot to load it wouldn't be as great. Today I gave this approach a try, but in the end wasn't happy with the outcome. I'm sorry this took so long.

With the custom compiler in #563, it should be much easier to do this...

Yeap, that's the way we should proceed. I apologize for closing (instead of merging) this PR after so long. Sorry for the frustration.

@rxaviers rxaviers closed this Jul 13, 2018
@rxaviers
Copy link
Member

@dantman in the meantime, an approach that could be used (not as a replacement, but as an alternative solution) is to use select and pass the ordinal value via pluralGenerator:

Globalize.loadMessages({
  en: {
    foo:
      "This is the {ordinal, select, one{1st} two{2nd} few{3rd} other{{count}th} } category"
  }
});
let ordinalGenerator = Globalize.pluralGenerator({ type: "ordinal" });

[1, 2, 3, 4, 10].map(count =>
  Globalize.formatMessage("foo", { count, ordinal: ordinalGenerator(count) })
);
//  > [
//    "This is the 1st category",
//    "This is the 2nd category",
//    "This is the 3rd category",
//    "This is the 4th category",
//    "This is the 10th category"
//  ]

@dantman
Copy link
Contributor

dantman commented Jul 13, 2018

@rxaviers Not an option in my situation. I'm using this in a system where messages and variable values are input by a user. I cannot tweak a variable input to go through a generator.

@rxaviers
Copy link
Member

Would you be interested in continue @nkovacs's custom compiler change? (or help @nkovacs in case he is still interested pursuing this)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants