Number pluralization 'one' category misused

Discourse misuses pluralization categories in translated strings, causing incorrect information to be displayed in non-English locales.

For example:

https://github.com/discourse/discourse/blob/b2cf725700255b9890986daed201f40127016524/config/locales/client.en.yml#L104-L106

This is translated to Russian as follows:

https://github.com/discourse/discourse/blob/8ff83d174ee518a2f04721d3b3088924e242e648/config/locales/client.ru.yml#L100-L104

Notice how the ‘one’ pluralization category hardcodes the digit 1. This is bad and wrong, I’ll let the CLDR spec for Plural Rules explain why:

These categories are only mnemonics – the names don’t necessarily imply the exact contents of the category. For example, for both English and French the number 1 has the category one (singular). In English, every other number has a plural form, and is given the category other. French is similar, except that the number 0 also has the category one and not other or zero, because the form of units qualified by 0 is also singular.

This is worth emphasizing: A common mistake is to think that “one” is only for only the number 1. Instead, “one” is a category for any number that behaves like 1. So in some languages, for example, one → numbers that end in “1” (like 1, 21, 151) but that don’t end in 11 (like "11, 111, 10311).

What this means for Discourse is that, in any other locale with pluralization rules like that (Russian is an example), wherever a number like 21, 31, etc. is supposed to be displayed, 1 will get shown instead. This is trivially reproduced by making a new account, switching the language to Russian, and waiting 21 minutes: the profile page will proudly proclaim that the account was created one minute ago.

This bug has been there since literally the first release. It’s all over the source files, too.

2 Likes

That’s not true. We deeply care about I18n. And there even is a topic regarding the correct usage of %{count} variable in translations: Always use %{count} variable when translating pluralized strings

Yes, we could do a better job by using %{count} instead of 1 in the English locale, so that translators don’t have to think about replacing the 1 with %{count} when there language requires it. Unfortunately it’s not that easy to do this for existing copy, because it would invalidate a lot of translation work…

Thanks for your passionate post about I18n. I hope you stay around a little bit longer and help us make translations even better. For example, you could sign up at Transifex and improve the existing Russian translations.

8 Likes