Problem
The current localization system (FlowLocalizations) uses simple string interpolation with {count} or {} placeholders for numeric values. This doesn't support grammatical plural forms, which differ across languages.
For example, the key tabs.home.transactionsCount with value "{count} transactions" always shows the same noun form regardless of the count:
- English: "1 transactions" ❌ (should be "1 transaction")
- Polish: "1 transakcji" ❌ (should be "1 transakcja", and "2 transakcje" for few)
- Russian: "1 транзакций" ❌ (should be "1 транзакция", and "2 транзакции" for few)
This affects all 14 supported languages — some have simple singular/plural (English, German), while others have complex plural rules (Polish, Russian, Czech, Arabic).
Proposed Solution
Add CLDR-based plural category resolution to FlowLocalizations.getTransalation():
-
New static method _pluralCategory(num n, String langCode) that returns the appropriate CLDR plural category (one, few, many, two, zero, other) based on the language and count value.
-
Modified num handling in getTransalation(): When replace is a num, the system checks for a suffixed key (e.g., key.one, key.few, key.many) before falling back to the base key.
-
Plural form keys in l10n JSON files: Languages can optionally define suffixed keys for each plural form. If a suffixed key doesn't exist, the base key is used (fully backward-compatible).
CLDR Rules Coverage (all 14 Flow languages)
| Language |
Code |
Categories |
Rule |
| Polish |
pl |
one/few/many |
one (1), few (2-4 excl. 12-14), many (rest) |
| Russian |
ru |
one/few/many |
one (%10=1, %100≠11), few (%10=2-4, %100≠12-14), many |
| Ukrainian |
uk |
one/few/many |
same as Russian |
| Belarusian |
be |
one/few/many |
same as Russian |
| Czech |
cs |
one/few/other |
one (1), few (2-4), other |
| Arabic |
ar |
zero/one/two/few/many/other |
full CLDR Arabic rules |
| French |
fr |
one/other |
one (0-1), other |
| Persian |
fa |
one/other |
one (0-1), other |
| English |
en |
one/other |
one (1), other |
| German |
de |
one/other |
one (1), other |
| Italian |
it |
one/other |
one (1), other |
| Spanish |
es |
one/other |
one (1), other |
| Turkish |
tr |
one/other |
one (1), other |
| Mongolian |
mn |
one/other |
one (1), other |
Example JSON (Polish)
"tabs.home.transactionsCount": "{count} transakcji",
"tabs.home.transactionsCount.one": "{count} transakcja",
"tabs.home.transactionsCount.few": "{count} transakcje",
"tabs.home.transactionsCount.many": "{count} transakcji"
Backward Compatibility
- If no suffixed keys exist for a language, the base key is used as before
- No changes needed in calling code — the
.t(context, count) API is unchanged
- Languages can incrementally add plural forms for any key
Problem
The current localization system (
FlowLocalizations) uses simple string interpolation with{count}or{}placeholders for numeric values. This doesn't support grammatical plural forms, which differ across languages.For example, the key
tabs.home.transactionsCountwith value"{count} transactions"always shows the same noun form regardless of the count:This affects all 14 supported languages — some have simple singular/plural (English, German), while others have complex plural rules (Polish, Russian, Czech, Arabic).
Proposed Solution
Add CLDR-based plural category resolution to
FlowLocalizations.getTransalation():New static method
_pluralCategory(num n, String langCode)that returns the appropriate CLDR plural category (one,few,many,two,zero,other) based on the language and count value.Modified
numhandling ingetTransalation(): Whenreplaceis anum, the system checks for a suffixed key (e.g.,key.one,key.few,key.many) before falling back to the base key.Plural form keys in l10n JSON files: Languages can optionally define suffixed keys for each plural form. If a suffixed key doesn't exist, the base key is used (fully backward-compatible).
CLDR Rules Coverage (all 14 Flow languages)
Example JSON (Polish)
Backward Compatibility
.t(context, count)API is unchanged