or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdinstance-management.mdphrase-management.mdpluralization.mdtranslation-interpolation.md

pluralization.mddocs/

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

```