skolmer / es2015-i18n-tag

ES2015 template literal tag for i18n and l10n (translation and internationalization)
http://i18n-tag.kolmer.net
MIT License
190 stars 13 forks source link

Nested templates example not a good solution for plurals #23

Open jkoudys opened 7 years ago

jkoudys commented 7 years ago

Pluralisation rules vary between languages, e.g. in English, 0 is plural, 1 is singular, and 2+ are plural, but in French, 0 is singular. Plural rules should instead rely on defaults set in the locale.

I'm okay with continuing to use a nested template, for consistency of the pattern, but rather than simply relying on the count, it would be useful to have a method for checking if a pluralisation rule applies in the current locale. I've seen plural-translate functions in other implementations (e.g. gettext-based libs for PHP that say t2('You have %s apple', 'You have %s apples'), but the nested approach gives a bit more flexibility without sacrificing readability.

How about:

import t, { isPlural } from 'es2015-i18n-tag';
const appleBasket = ['macintosh', 'red delicious', 'honeycrisp'];
foo(isPlural(appleBasket.length) ? t`You have ${appleBasket.length} apples in your basket.` : t`You have ${appleBasket.length} apple in your basket.`);

I've done a 500-string translation file in 17 languages with different translators, and for the most part this reading is very natural and they were able to understand which pluralisation form to use. It does get a bit sketchy for languages like Russian which can have 3 plural forms, of course. Perhaps isPlural could return an int, not a boolean, which would by truthy enough that the basic ternary above would work, but leave the door open for higher plural forms.

This could be configurable for the singleton, so if they locale doesn't have the plurals available, you could override them.

Thoughts? I could get started on a PR on this right away since I have a project which needs to get some new translations up ASAP. I was looking at i18next before, but I found there approach to be very es5; I wrote a workalike to some translations functions a PHP app was using so they could share translations files ( https://github.com/jkoudys/janeswalk-web/blob/master/modules/janeswalk/utils/translate.js ), but I'd much rather support a lib that helps the community.

skolmer commented 7 years ago

Hi @jkoudys, good catch I haven't thought about that yet. I would welcome a PR on this topic. At the moment there is no language specific logic in this library. Thanks for your support!

skolmer commented 7 years ago

How about using https://github.com/rxaviers/cldr-data-npm or a similar package to get the CLDR plural rules for this feature?

skolmer commented 7 years ago

There is a polyfill for Intl.PluralRules

artsyca commented 6 years ago

https://alistapart.com/article/pluralization-for-javascript < This article describes several requirements and approaches to pluralization; There are further challenges apart from the basic forms of pluralization, some languages require pluralization using ranges.