Page MenuHomePhabricator

Add support for ordinal numbers
Open, MediumPublicFeature

Description

Right now, MediaWiki has no way to localize '1st', '2nd', '3rd', etc. The CLDR database includes rules for creating ordinal numbers but these rules are not currently extracted or utilized by the cldr extension.

The rules are ruleset type="digits-ordinal-indicator" in core/common/rbnf. Here is a sample for English:

<ruleset type="digits-ordinal-indicator" access="private">
    <rbnfrule value="0">th;</rbnfrule>
    <rbnfrule value="1">st;</rbnfrule>
    <rbnfrule value="2">nd;</rbnfrule>
    <rbnfrule value="3">rd;</rbnfrule>
    <rbnfrule value="4">th;</rbnfrule>
    <rbnfrule value="20">→→;</rbnfrule>
    <rbnfrule value="100">→→;</rbnfrule>
</ruleset>

See also:

Details

Reference
bz57903
Related Changes in Gerrit:

Event Timeline

bzimport raised the priority of this task from to Medium.Nov 22 2014, 2:41 AM
bzimport set Reference to bz57903.
bzimport added a subscriber: Unknown Object (MLST).

This is being requested for the KeepGoing feature in MobileFrontend (https://www.mediawiki.org/wiki/Extension:MobileFrontend/KeepGoing). We're probably just going to change the requirements for now.

Change 678307 had a related patch set uploaded (by Jon Harald Søby; author: Jon Harald Søby):

[mediawiki/core@master] Add ordinal transformation as GRAMMAR for English

https://gerrit.wikimedia.org/r/678307

Test wiki created on Patch Demo by Jon Harald Søby using patch(es) linked to this task:

https://patchdemo.wmflabs.org/wikis/34a3f67b1f/w/

Aklapper changed the subtype of this task from "Task" to "Feature Request".Feb 4 2022, 12:23 PM
Aklapper removed a subscriber: wikibugs-l-list.

Test wiki on Patch demo by Jon Harald Søby using patch(es) linked to this task was deleted:

https://patchdemo.wmflabs.org/wikis/34a3f67b1f/w/

I'm afraid the approach proposed in https://gerrit.wikimedia.org/r/c/mediawiki/core/+/678307 with {{GRAMMAR:ordinal|<number>}} transforming into 1st/2nd etc. will not work for many languages, e.g. Greek, Spanish and Russian, because the ordinal suffix depends also on the grammatical gender of the noun that you're counting.

For example: [please excuse translation mistakes, I don't speak any of these languages]

EnglishGreekSpanishRussian
5th century5ος αιώνας5.º siglo5-й век
5th millennium χιλιετία5.º milenio5-е тысячелетие
1st edit επεξεργασία1.ª edición1-я правка
1st article1ο άρθρο1.ᵉʳ artículo1-я статья

(and for centuries in particular, there are often specific typographical conventions that differ from normal ordinal numbers, the usual way to write these phrases in Spanish and Russian would be "siglo V" and "V век")

So what you really need here is something that works like {{PLURAL:}}, with just the rules for each case defined by MediaWiki, and the text specified in each message translation. It could look like $1{{ORDINAL:$1|st|nd|rd|th}} edit / $1{{ORDINAL:$1|st|nd|rd|th}} article in English, $1.{{ORDINAL:$1|ª}} edición / $1.{{ORDINAL:$1|ᵉʳ|º}} artículo in Spanish, and so on.

This is quite ugly in the English source (in a rare case where English grammar is more complex than most other languages), but this is a fairly rare use case, so I think it would be acceptable.

The ordinal rules are available in CLDR, which is where we already get the plural rules (e.g. https://www.unicode.org/cldr/charts/47/supplemental/language_plural_rules.html), so the code currently implementing {{PLURAL:}} could probably be adapted to implement {{ORDINAL:}} too. It should be straightforward but it may be tedious, since there's a lot of code and it's split across several libraries (and note that you should support this in JS code too).

I suppose there's also things like Japanese, which I know has a complicated set of "what is the correct counter-words for this type of subject?" questions to answer, beyond just gender.

So what you really need here is something that works like {{PLURAL:}}, with just the rules for each case defined by MediaWiki, and the text specified in each message translation. It could look like $1{{ORDINAL:$1|st|nd|rd|th}} edit / $1{{ORDINAL:$1|st|nd|rd|th}} article in English, $1.{{ORDINAL:$1|ª}} edición / $1.{{ORDINAL:$1|ᵉʳ|º}} artículo in Spanish, and so on.

It doesn't seem hard to just turn {{ORDINAL:$1}} to ˙1st`/2nd/etc. For some other languages you'd have to provide more information, so maybe for Greek it would be {{ORDINAL|$1|<gender>}}. That would mean the parserfunction takes different parameters in different languages; we have that with GRAMMAR already. It would also mean having to have per-language logic, which is hard to maintain (although we also have that with GRAMMAR already). Something something wikifunctions?

The status quo, given that we don't have this option today, is to approach it entirely differently:

  • Extract the number and generalize the label (e.g. a label like "Messages" with a badge holding a number "N"). This makes the number the most important part, accessible, readable. Given the small form, this also suits itself to stronger design elements (like a red background) that would be unsuitable for a localisable long-form sentence containing a number somewhere in it.
  • Re-phrase with plural, e.g. "You are about to delete N emails." or "You have N new messages". This is not as bold as extraction, but is still more accessible and places greater importance on the exact number, both in terms of grammar and sentence structure. It tends to force you into "Simple" English phrasing.
  • Omit, if the number isn't significant to the end-user or is apparent by other means already.
  • Specialize. When the ordinal number matters, it is likely to carry special meaning. Approaching this from the technical side as "just an ordinal" number may miss an important oppertunity for a more meaningful human interation, as well as a higher quality translation. For example, consider a system where we notify the user at certain milestones (1st, 10th, 100th edit). Rather than encoding this as a generic message saying "This was your Nth edit" with a conditional trigger, we can recognise these as meaningfully distinct milestones. "You've just published your first edit! Welcome!". "That was your 10th edit, please keep at it!", "100 edits and counting, you're awesome!". Note how only one of these was phrased without a literal number and ordinal suffix (100 edits instead of 100th edit; and "first" instead of "1st", as the latter connotates with ranking and ordering). Translators can choose what seems natural in their language for a given number and personal context of what just happened, instead of being forced to embed a parameterized number and generalize.

Many of the above are not merely alternatives, but preferred approaches even if we did have the option to embed an ordinal number today. I say this with some copium of course, because we don't have that option today. But, I do think it is rare for a number to "matter" (worth including) and yet not be worth elevating or simplifying in one of the above ways for greater usability/accessibilty or a higher quality translation.

Actual example:

But, I do think it is rare for a number to "matter" (worth including) and yet not be worth elevating or simplifying in one of the above ways for greater usability/accessibilty or a higher quality translation.

One use-case where the number does matter is T95553.

So what you really need here is something that works like {{PLURAL:}}, with just the rules for each case defined by MediaWiki, and the text specified in each message translation. It could look like $1{{ORDINAL:$1|st|nd|rd|th}} edit / $1{{ORDINAL:$1|st|nd|rd|th}} article in English, $1.{{ORDINAL:$1|ª}} edición / $1.{{ORDINAL:$1|ᵉʳ|º}} artículo in Spanish, and so on.

It doesn't seem hard to just turn {{ORDINAL:$1}} to ˙1st`/2nd/etc. For some other languages you'd have to provide more information, so maybe for Greek it would be {{ORDINAL|$1|<gender>}}. That would mean the parserfunction takes different parameters in different languages; we have that with GRAMMAR already. It would also mean having to have per-language logic, which is hard to maintain (although we also have that with GRAMMAR already). Something something wikifunctions?

I wonder if a secondary argument is really necessary. In the situations @matmarex presents (this includes T95553), the translator knows the gender beforehand. Obviously, this assumes we always structure the messages like this (i.e., one "concept" per message). On the contrary, some users / third-party wikis might prefer fancy "September 4th, 2025" dates instead of "4 September 2025". Unless we let translators handle each month by a separate message (cons: redundancy, more work for translators), we would need support for languages where the suffix, unlike for English, varies by month. Is there such a language, though? I wasn't sure myself, so I asked ChatGPT, which couldn't identify even one case. (It used a page on Meta-Wiki which otherwise looks like a useful resource.)

Change #678307 abandoned by Hashar:

[mediawiki/core@master] Add ordinal transformation as GRAMMAR for English

https://gerrit.wikimedia.org/r/678307

Change #678307 restored by Thcipriani:

[mediawiki/core@master] Add ordinal transformation as GRAMMAR for English

https://gerrit.wikimedia.org/r/678307

I think the actual roadblock for this feature from languages like Russian is not gender but that in many contexts, what’s needed is not just different gender, but also different forms (5-й век, but в 5-м веке, в 1910-х годах). This sort of thing leads me to the opinion that where the ordinals are needed, they should be actually just written down like $1{{ORDINAL:$1|st|nd|rd|th}} (I guess English can be {{ORDINAL:$1|}} if we want to be a bit biased there), since that’s the only way that would provide the flexibilty for different languages. Anything else would eventually break down as message authors rarely think about what cases would make sense in other languages even without {{ORDINAL:}}.

On a related note, Azerbaijani has just implemented this via GRAMMAR (T426082), and this is how @jhsoby wanted to make it work for English in 678307.

But if this doesn't work for all languages (demonstrated above), what about supporing both ORDINAL and GRAMMAR and letting each language (translators) implement and use what works the best?

  • ORDINAL - for languages where it also depends on the context (Spanish - $1.{{ORDINAL:$1|ᵉʳ|º}} artículo)
  • GRAMMAR - for languages where it depends only on the cardinal (English - {{GRAMMAR:ordinal|$1}} article)
  • nothing - for languages with trivial suffix (German - $1. Artikel)