Category map

The category map plural format

The category map spells plurals out as structure: the message key holds a map, and each CLDR category (one, few, many, other…) is a subkey with its own string. Nothing hides inside a syntax; every form is a plain value a person can read and a diff can show.

This page covers the shape, the Rails lineage, and the same plural in JSON and YAML; a flat format like properties cannot express it.

Examples

The same plural, three languages

The map gains entries as the language demands them; a reviewer sees at a glance which forms exist and which are missing.

en · two entries
"items": {
  "one": "# item",
  "other": "# items"
}
pl · four entries
"items": {
  "one": "# artykuł",
  "few": "# artykuły",
  "many": "# artykułów",
  "other": "# artykułu"
}
ar · six entries
"items": {
  "zero": "لا عناصر",
  "one": "عنصر واحد",
  "two": "عنصران",
  "few": "# عناصر",
  "many": "# عنصرًا",
  "other": "# عنصر"
}
en · Rails style
items:
  one: "%{count} item"
  other: "%{count} items"
pl
items:
  one: "%{count} artykuł"
  few: "%{count} artykuły"
  many: "%{count} artykułów"
  other: "%{count} artykułu"

In Rails locale files the interpolation is %{count}; the subkeys are the same CLDR names.

How it works

The library resolves the category

At runtime the framework maps the count to a CLDR category and looks up that subkey; Rails’ t(:items, count: 5) does exactly this. The file carries no selection logic at all, which is the point: the encoding is pure data, easy to generate, easy to validate, easy to review. The cost is that the key is no longer a plain string key, so tooling that does not know the convention sees a nested object where it expected a value.

Origin

Where it came from

Mapping plural categories to keys is the obvious move in any tree shaped format, but Rails made it a convention: the i18n gem shipped with Rails 2.2 in 2008 and looked up one and other subkeys from day one. From there the shape spread through YAML and JSON ecosystems and became the lingua franca of TMS exports, since it needs no parser beyond the file format itself.

Trade offs

Strengths and limits

strength

Readable and diffable

Each form is its own line; a review shows exactly which form changed, and a missing form is visibly missing.

strength

No syntax to break

There are no braces to unbalance; a translator can edit any form without touching the others.

limit

Needs a tree

Flat formats cannot hold a map under a key, and plurals only; gender or ordinal branching needs ICU.

In locamorph

How locamorph treats category maps

A value whose keys are all CLDR categories is recognized as one plural on import, in JSON and in YAML alike, so Rails locale files land as plurals rather than as four unrelated keys. On export, choosing the category map plural format writes this shape back.

Further reading

Rails files land as plurals

Import a Rails locale tree and the subkeys become per form fields, not stray keys; export writes them back in place.