Description
Jmix has no standard mechanism for displaying count-dependent text. Messages that combine a number with a noun — "5 rows", "1 record", "3 errors" — require different word forms depending on the number and the locale. Russian, Polish, Czech, Arabic and other languages have complex plural rules that cannot be handled by a single fixed word form.
The current state is inconsistent: one module has a working but non-standard workaround, several modules contain grammatical errors in Russian translations, and one module handles plurals only for English.
ICU4J (already present in jmix-bom) provides standard plural rules for all locales via CLDR data. The goal is to replace all ad hoc solutions with a single consistent mechanism.
Affected areas
Refactoring required (works correctly, but non-standard)
Pagination — jmix-flowui
The pagination component correctly handles Russian plural forms, but the solution is hardcoded: four separate message keys represent the four Russian plural categories, and the selection logic is implemented in Java using modular arithmetic. This needs to be replaced with the standard ICU mechanism while preserving the correct output.
Bug fixes (incorrect output for numbers other than 5–20)
Bulk editor — jmix-bulkeditor
"Записей будет изменено: %s" and "Записей успешно изменено: %s" use a fixed genitive plural form. For the numbers 1, 21, 31, etc. the output is grammatically incorrect: "Записей успешно изменено: 1".
Grid export — jmix-gridexport
"экспортировано только %s строк" — same issue. "экспортировано только 1 строк" is incorrect.
Message templates — jmix-messagetemplates
"Импортировано %s записей" — same pattern. "Импортировано 1 записей" is incorrect.
Improvement (correct for English, broken for other locales)
Full calendar — jmix-fullcalendar
The "more events" link uses a JavaScript ternary: count === 1 ? '' : 's'. This correctly produces "1 event" / "5 events" in English, but does not work for any other locale.
Expected behavior
All messages that combine a number with a countable noun should produce grammatically correct output for the current user locale, for any number. The solution should be applicable to new messages in the same way as existing message keys — without custom Java logic per message or per module.
Developer experience: before / after
Example: a developer wants to show "Selected N rows".
Before — no reusable mechanism, so the pagination anti-pattern is copied: 4 message keys per message and a switch in Java.
// Java: plural selection hardcoded (copied from SimplePagination)
String key;
if (count == 1) {
key = "myView.selectedRows.singular1";
} else if (count % 100 > 10 && count % 100 < 20) {
key = "myView.selectedRows.plural1";
} else {
switch (count % 10) {
case 1: key = "myView.selectedRows.singular"; break;
case 2: case 3: case 4: key = "myView.selectedRows.plural2"; break;
default: key = "myView.selectedRows.plural1";
}
}
String text = messages.formatMessage(MyView.class, key, count);
# messages_ru.properties — 5 keys
myView.selectedRows.singular1=Выбрана %s строка
myView.selectedRows.singular=Выбрана %s строка
myView.selectedRows.plural2=Выбрано %s строки
myView.selectedRows.plural1=Выбрано %s строк
The plural rules live in Java and are hardcoded for Russian. Other locales cannot fix their output by translation alone — e.g. pt_BR renders "21 linha", cs renders "2 řádků", and Arabic forms (dual, many) cannot be expressed at all.
After — one key per message, no Java logic. ICU picks the CLDR category for the current locale.
String text = messages.formatMessage(MyView.class, "myView.selectedRows", count);
# messages_ru.properties — one key, ICU plural syntax (4 Russian forms)
myView.selectedRows=Выбрано {0, plural, one {# строка} few {# строки} many {# строк} other {# строк}}
# messages.properties (EN) — 2 forms
myView.selectedRows=Selected {0, plural, one {# row} other {# rows}}
# messages_cs.properties — 3 forms, now expressible
myView.selectedRows={0, plural, one {# řádek} few {# řádky} other {# řádků}}
Each translation lists only its own categories; pt_BR, cs and ar become correct by translation alone, and new locales work out of the box.
Impact
Eliminates grammatical errors visible to Russian-speaking users in several framework screens. Provides a reusable mechanism for application developers to handle plural forms in their own messages.
Description
Jmix has no standard mechanism for displaying count-dependent text. Messages that combine a number with a noun — "5 rows", "1 record", "3 errors" — require different word forms depending on the number and the locale. Russian, Polish, Czech, Arabic and other languages have complex plural rules that cannot be handled by a single fixed word form.
The current state is inconsistent: one module has a working but non-standard workaround, several modules contain grammatical errors in Russian translations, and one module handles plurals only for English.
ICU4J (already present in
jmix-bom) provides standard plural rules for all locales via CLDR data. The goal is to replace all ad hoc solutions with a single consistent mechanism.Affected areas
Refactoring required (works correctly, but non-standard)
Pagination —
jmix-flowuiThe pagination component correctly handles Russian plural forms, but the solution is hardcoded: four separate message keys represent the four Russian plural categories, and the selection logic is implemented in Java using modular arithmetic. This needs to be replaced with the standard ICU mechanism while preserving the correct output.
Bug fixes (incorrect output for numbers other than 5–20)
Bulk editor —
jmix-bulkeditor"Записей будет изменено: %s" and "Записей успешно изменено: %s" use a fixed genitive plural form. For the numbers 1, 21, 31, etc. the output is grammatically incorrect: "Записей успешно изменено: 1".
Grid export —
jmix-gridexport"экспортировано только %s строк" — same issue. "экспортировано только 1 строк" is incorrect.
Message templates —
jmix-messagetemplates"Импортировано %s записей" — same pattern. "Импортировано 1 записей" is incorrect.
Improvement (correct for English, broken for other locales)
Full calendar —
jmix-fullcalendarThe "more events" link uses a JavaScript ternary:
count === 1 ? '' : 's'. This correctly produces "1 event" / "5 events" in English, but does not work for any other locale.Expected behavior
All messages that combine a number with a countable noun should produce grammatically correct output for the current user locale, for any number. The solution should be applicable to new messages in the same way as existing message keys — without custom Java logic per message or per module.
Developer experience: before / after
Example: a developer wants to show "Selected N rows".
Before — no reusable mechanism, so the pagination anti-pattern is copied: 4 message keys per message and a
switchin Java.The plural rules live in Java and are hardcoded for Russian. Other locales cannot fix their output by translation alone — e.g.
pt_BRrenders "21 linha",csrenders "2 řádků", and Arabic forms (dual, many) cannot be expressed at all.After — one key per message, no Java logic. ICU picks the CLDR category for the current locale.
Each translation lists only its own categories;
pt_BR,csandarbecome correct by translation alone, and new locales work out of the box.Impact
Eliminates grammatical errors visible to Russian-speaking users in several framework screens. Provides a reusable mechanism for application developers to handle plural forms in their own messages.