0
# Pluralization
1
2
Advanced pluralization system supporting multiple languages with complex plural rules and locale-aware plural form selection.
3
4
## Capabilities
5
6
### Locale Management
7
8
Get or set the current locale for pluralization rules.
9
10
```javascript { .api }
11
/**
12
* Get or set current locale for pluralization
13
* @param {string} newLocale - Optional new locale to set
14
* @returns {string} Current locale string
15
*/
16
locale(newLocale);
17
```
18
19
**Usage Examples:**
20
21
```javascript
22
const Polyglot = require('node-polyglot');
23
24
const polyglot = new Polyglot({
25
phrases: {
26
'items_zero': 'No items',
27
'items_one': 'One item',
28
'items_other': '%{smart_count} items'
29
},
30
locale: 'en'
31
});
32
33
// Get current locale
34
console.log(polyglot.locale()); // "en"
35
36
// Set new locale
37
polyglot.locale('ru');
38
console.log(polyglot.locale()); // "ru"
39
40
// Locale affects pluralization behavior
41
polyglot.t('items', { smart_count: 2 }); // Uses Russian plural rules
42
43
// Reset to English
44
polyglot.locale('en');
45
polyglot.t('items', { smart_count: 2 }); // "2 items"
46
```
47
48
### Static Transform Phrase
49
50
Static method for phrase transformation without creating a Polyglot instance.
51
52
```javascript { .api }
53
/**
54
* Static method for phrase transformation without instance creation
55
* @param {string} phrase - Phrase to transform with pluralization delimiters
56
* @param {Object|number} substitutions - Substitution values or smart_count shortcut
57
* @param {string} locale - Locale for pluralization rules (default: 'en')
58
* @returns {string} Transformed phrase with pluralization and interpolation applied
59
*/
60
Polyglot.transformPhrase(phrase, substitutions, locale);
61
```
62
63
**Usage Examples:**
64
65
```javascript
66
const Polyglot = require('node-polyglot');
67
68
// Basic usage with English
69
const result1 = Polyglot.transformPhrase(
70
'You have %{smart_count} messages |||| You have one message',
71
{ smart_count: 1 },
72
'en'
73
);
74
console.log(result1); // "You have one message"
75
76
const result2 = Polyglot.transformPhrase(
77
'You have %{smart_count} messages |||| You have one message',
78
{ smart_count: 5 },
79
'en'
80
);
81
console.log(result2); // "You have 5 messages"
82
83
// Using number shortcut
84
const result3 = Polyglot.transformPhrase(
85
'%{smart_count} items |||| one item',
86
1,
87
'en'
88
);
89
console.log(result3); // "one item"
90
91
// Russian pluralization (3 forms)
92
const result4 = Polyglot.transformPhrase(
93
'%{smart_count} товар |||| %{smart_count} товара |||| %{smart_count} товаров',
94
2,
95
'ru'
96
);
97
console.log(result4); // "2 товара" (uses middle form for 2-4)
98
99
// Arabic pluralization (6 forms)
100
const arabicPhrase = 'zero |||| one |||| two |||| few |||| many |||| other';
101
const result5 = Polyglot.transformPhrase(arabicPhrase, 2, 'ar');
102
console.log(result5); // "two" (Arabic has special form for exactly 2)
103
104
// Without locale (defaults to 'en')
105
const result6 = Polyglot.transformPhrase(
106
'%{smart_count} files |||| one file',
107
1
108
);
109
console.log(result6); // "one file"
110
```
111
112
## Pluralization System
113
114
### Plural Form Delimiter
115
116
Phrases with multiple plural forms are separated by `||||` (four vertical bars).
117
118
```javascript
119
// English: 2 forms (singular/plural)
120
'%{smart_count} items |||| one item'
121
122
// Russian: 3 forms (1, 2-4, 5+)
123
'%{smart_count} товар |||| %{smart_count} товара |||| %{smart_count} товаров'
124
125
// Arabic: 6 forms (0, 1, 2, 3-10, 11-99, 100+)
126
'zero items |||| one item |||| two items |||| few items |||| many items |||| other items'
127
```
128
129
### Smart Count
130
131
The `smart_count` option triggers pluralization and provides the count value.
132
133
```javascript
134
const polyglot = new Polyglot({
135
phrases: {
136
'messages': '%{smart_count} messages |||| one message'
137
}
138
});
139
140
// Different smart_count values
141
polyglot.t('messages', { smart_count: 0 }); // "0 messages"
142
polyglot.t('messages', { smart_count: 1 }); // "one message"
143
polyglot.t('messages', { smart_count: 2 }); // "2 messages"
144
polyglot.t('messages', { smart_count: 100 }); // "100 messages"
145
146
// Number shortcut (equivalent to { smart_count: n })
147
polyglot.t('messages', 0); // "0 messages"
148
polyglot.t('messages', 1); // "one message"
149
polyglot.t('messages', 2); // "2 messages"
150
```
151
152
### Supported Languages
153
154
Built-in pluralization rules for multiple language families:
155
156
```javascript { .api }
157
/**
158
* Supported plural types with their language mappings
159
*/
160
interface DefaultPluralRules {
161
pluralTypes: {
162
/** Arabic: 6 forms (0, 1, 2, few, many, other) */
163
arabic: (n: number) => number;
164
165
/** Bosnian/Serbian: 3 forms like Russian */
166
bosnian_serbian: (n: number) => number;
167
168
/** Chinese/Japanese/Korean: 1 form (no pluralization) */
169
chinese: (n: number) => number;
170
171
/** Croatian: 3 forms like Russian */
172
croatian: (n: number) => number;
173
174
/** French: 2 forms (1 vs 2+) */
175
french: (n: number) => number;
176
177
/** German/English: 2 forms (1 vs other) */
178
german: (n: number) => number;
179
180
/** Russian: 3 forms (1, 2-4, 5+) */
181
russian: (n: number) => number;
182
183
/** Lithuanian: 3 forms with special rules */
184
lithuanian: (n: number) => number;
185
186
/** Czech/Slovak: 3 forms (1, 2-4, 5+) */
187
czech: (n: number) => number;
188
189
/** Polish: 3 forms with complex rules */
190
polish: (n: number) => number;
191
192
/** Icelandic: 2 forms with special rules */
193
icelandic: (n: number) => number;
194
195
/** Slovenian: 4 forms (1, 2, 3-4, 5+) */
196
slovenian: (n: number) => number;
197
198
/** Romanian: 3 forms (1, 0 or 2-19, 20+) */
199
romanian: (n: number) => number;
200
201
/** Ukrainian: 3 forms like Russian */
202
ukrainian: (n: number) => number;
203
};
204
205
pluralTypeToLanguages: {
206
arabic: ['ar'];
207
bosnian_serbian: ['bs-Latn-BA', 'bs-Cyrl-BA', 'srl-RS', 'sr-RS'];
208
chinese: ['id', 'id-ID', 'ja', 'ko', 'ko-KR', 'lo', 'ms', 'th', 'th-TH', 'zh'];
209
croatian: ['hr', 'hr-HR'];
210
german: ['fa', 'da', 'de', 'en', 'es', 'fi', 'el', 'he', 'hi-IN', 'hu', 'hu-HU', 'it', 'nl', 'no', 'pt', 'sv', 'tr'];
211
french: ['fr', 'tl', 'pt-br'];
212
russian: ['ru', 'ru-RU'];
213
lithuanian: ['lt'];
214
czech: ['cs', 'cs-CZ', 'sk'];
215
polish: ['pl'];
216
icelandic: ['is', 'mk'];
217
slovenian: ['sl-SL'];
218
romanian: ['ro'];
219
ukrainian: ['uk', 'ua'];
220
};
221
}
222
```
223
224
### Language-Specific Examples
225
226
```javascript
227
const Polyglot = require('node-polyglot');
228
229
// Russian (3 forms)
230
const ruPolyglot = new Polyglot({
231
phrases: {
232
'files': '%{smart_count} файл |||| %{smart_count} файла |||| %{smart_count} файлов'
233
},
234
locale: 'ru'
235
});
236
237
ruPolyglot.t('files', 1); // "1 файл" (ends in 1, not 11)
238
ruPolyglot.t('files', 2); // "2 файла" (2-4, not 12-14)
239
ruPolyglot.t('files', 5); // "5 файлов" (5+ or 11-14)
240
241
// French (2 forms: 1 vs 2+)
242
const frPolyglot = new Polyglot({
243
phrases: {
244
'items': '%{smart_count} élément |||| %{smart_count} éléments'
245
},
246
locale: 'fr'
247
});
248
249
frPolyglot.t('items', 1); // "1 élément"
250
frPolyglot.t('items', 2); // "2 éléments"
251
252
// Chinese (no pluralization)
253
const zhPolyglot = new Polyglot({
254
phrases: {
255
'books': '%{smart_count} 本书' // Only one form needed
256
},
257
locale: 'zh'
258
});
259
260
zhPolyglot.t('books', 1); // "1 本书"
261
zhPolyglot.t('books', 5); // "5 本书"
262
263
// Arabic (6 forms)
264
const arPolyglot = new Polyglot({
265
phrases: {
266
'days': 'لا أيام |||| يوم واحد |||| يومان |||| %{smart_count} أيام |||| %{smart_count} يوم |||| %{smart_count} يوم'
267
},
268
locale: 'ar'
269
});
270
271
arPolyglot.t('days', 0); // "لا أيام" (zero)
272
arPolyglot.t('days', 1); // "يوم واحد" (one)
273
arPolyglot.t('days', 2); // "يومان" (two)
274
arPolyglot.t('days', 5); // "5 أيام" (few: 3-10)
275
```
276
277
### Custom Plural Rules
278
279
You can provide custom pluralization rules when creating a Polyglot instance.
280
281
```javascript { .api }
282
/**
283
* Custom plural rules structure
284
*/
285
interface CustomPluralRules {
286
pluralTypes: {
287
[typeName: string]: (count: number) => number;
288
};
289
pluralTypeToLanguages: {
290
[typeName: string]: string[];
291
};
292
}
293
```
294
295
**Usage Example:**
296
297
```javascript
298
// Custom rule for a fictional language with 4 forms
299
const customRules = {
300
pluralTypes: {
301
fictional: function(n) {
302
if (n === 0) return 0; // zero form
303
if (n === 1) return 1; // singular form
304
if (n <= 10) return 2; // few form (2-10)
305
return 3; // many form (11+)
306
}
307
},
308
pluralTypeToLanguages: {
309
fictional: ['fic']
310
}
311
};
312
313
const polyglot = new Polyglot({
314
phrases: {
315
'widgets': 'no widgets |||| one widget |||| %{smart_count} widgets |||| many widgets'
316
},
317
locale: 'fic',
318
pluralRules: customRules
319
});
320
321
polyglot.t('widgets', 0); // "no widgets"
322
polyglot.t('widgets', 1); // "one widget"
323
polyglot.t('widgets', 5); // "5 widgets"
324
polyglot.t('widgets', 15); // "many widgets"
325
```