# A count's plural forms — one text per CLDR category

> A message with a whole-number hole (`$"{n} items"`) may take one text per plural category of its language — CLDR's `zero`, `one`, `two`, `few`, `many`, `other` — and the number chooses. The compile requires every category the language has and no other; a translation that does not change with the count may stay one text. A form that stands for exactly one number may say it in words ("منتج واحد") and leave the count out.

<!-- id: i18n-plurals · area: i18n · stability: stable · html: https://osysharp.com/reference/i18n/plurals/ -->

## Summary        {#summary}
The first whole-number hole of a message is its count. Its translation is either one text (the same for every count)
or an object with one text per category the language has:

| language | categories |
|---|---|
| English, Swedish, German, Danish, Norwegian, Finnish, Dutch | `one`, `other` |
| French, Spanish, Italian, Portuguese | `one`, `many`, `other` (`many`: a whole million and up) |
| Polish | `one`, `few`, `many`, `other` |
| Arabic | `zero`, `one`, `two`, `few`, `many`, `other` |
| Japanese, Chinese, Korean | `other` |

## Signature      {#signature}
```osy syntax
text "{count} items in your bag" => { one: "{count} vara i din kasse", other: "{count} varor i din kasse" };
```

## Description    {#description}
The rules are CLDR's, for whole numbers, and the same table runs in the browser and on the server. Polish, for
example: 1 is `one`; 2–4, 22–24, 32–34 … are `few`; 0, 5–21, 25–31 … are `many`. Every form must still use exactly the
source's placeholders — with one exception.

**A form for exactly one number may say it in words.** Arabic does not write "1 منتج" or "2 منتج": it says "منتج واحد"
(one product) and "منتجان" (two products, the dual), and the number is in the word. So a form whose category covers
exactly one count — Arabic `zero` (0), `one` (1) and `two` (2), English or Swedish `one` (1), Polish `one` (1) — may
leave the count out. Every other placeholder is still required, and so is the count in every other form: Arabic `few`
is 3–10, 103–110 …, and French `one` is both 0 and 1, so a form like that without the count would read the same for
different numbers. The refusal names the forms that may drop it.

English source text often cannot say `1 item` and `2 items` with one sentence; add an `en` locale file to give the
source language its own forms — it is a translation like any other.

**A number written against a mark or a letter is a label, not a count.** `$"Merged into #{number}."` names ticket 1042,
and `$"Escalated to L{level}."` names a level: neither is "how many", so neither chooses a plural form, and its
translation is ONE text. A count stands on its own — `{n} items`, `({n})` — and a count later in the same message
still chooses: in `$"#{number} has {count} replies"` it is `count`.

## Examples       {#examples}
```osy title="a count, and the two Swedish forms it takes" test app=i18n-plurals
[Route("/")]
[AllowAnonymous]
component Basket() {
  int count = 1;
  render { Text($"{count} bottles chilled"); }
}

translations sv {
  text "{count} bottles chilled" => { one: "{count} flaska kyld", other: "{count} flaskor kylda" };
}
```

```osy title="Arabic: one and two said in words, the rest show the count" test app=i18n-plurals-arabic
[Route("/")]
[AllowAnonymous]
component Basket() {
  int count = 2;
  render { Text($"{count} bottles chilled"); }
}

translations ar {
  text "{count} bottles chilled" => { zero: "لا زجاجات مبرّدة", one: "زجاجة واحدة مبرّدة", two: "زجاجتان مبرّدتان",
    few: "{count} زجاجات مبرّدة", many: "{count} زجاجة مبرّدة", other: "{count} زجاجة مبرّدة" };
}
```

```osy title="a ticket's number is a label: one text; the reply count still chooses" test app=i18n-plurals-labels
[Route("/")]
[AllowAnonymous]
component Ticket() {
  int number = 1042;
  int count = 3;
  render {
    Stack {
      Text($"Merged into #{number}.");
      Text($"#{number} has {count} replies");
    }
  }
}

translations sv {
  text "Merged into #{number}." => "Sammanslaget med #{number}.";
  text "#{number} has {count} replies" => { one: "#{number} har ett svar", other: "#{number} har {count} svar" };
}
```

## See also       {#see-also}
- [A language's words — locales/<language>.osy](https://osysharp.com/reference/i18n/translations/) — the file the forms are written in
- [Which words are translated — the compiler finds every text a reader sees](https://osysharp.com/reference/i18n/extraction/) — what makes a hole a count
