# Pluralization

# Introduction

Languages vary in how they handle plurals of nouns or unit expressions (“hour” vs “hours”, and so on). Some languages have two forms, like English; some
languages have only a single form; and some languages have multiple
forms. This component uses Unicode CLDR Plural Rules to determine the form of a word in a given number. CLDR uses short, mnemonic tags for these plural categories:

  • zero
  • one (singular)
  • two (dual)
  • few (paucal)
  • many (also used for fractions if they have a separate class)
  • other (general plural form; also used if the language has only one form or if the required form is not defined. This form is required)

See Language Plural Rules for the categories for each language in CLDR.

These categories are used to provide localized units, with a more natural ways of expressing phrases that vary in plural form, such as “1 hour” vs “2 hours”. While they cannot express all the intricacies of natural languages, they allow for more natural phrasing than constructions like 1 hour(s)”.

Pluralization is carried out using the OblikStudio/php-pluralization library.

# TC\ComponentLibrary\Util\Pluralization

# pluralPhraseName

Returns phrase names in the required plural form.

public static function pluralPhraseName($number, $phrases, \XF\Language $language = null): string

# Arguments

Argument Type Default value Description
number int|float Number for pluralization.
phrases string[]|string Names of phrases for different forms of pluralization.
If a string is specified, it will be the name of the phrase in the form other, and names for other forms will be formed by adding the suffixes _zero, _one, _two, _few and _many.
The other form is required.
language XF\Language XF::language() The language object for which pluralization is being performed.

# Examples

# Getting the phrase name from a list
/**
 * If the current language is English and count($items) == 1, “there_is_one_item” will be returned,
 * otherwise “there_are_x_items”. Other forms are not used by English, but may be used by other languages.
 */
$phraseName = \TC\ComponentLibrary\Util\Pluralization::pluralPhraseName(
    count($items),
    [
        'zero'  => 'there_are_zero_items',
        'one'   => 'there_is_one_item',
        'two'   => 'there_are_two_items',
        'few'   => 'there_are_few_items',
        'many'  => 'there_are_many_items',
        'other' => 'there_are_x_items'
    ]
);
# Getting the name of a phrase without specifying a list of phrases
/**
 * Unlike the previous example, here is not a list of named phrases, but the name of one phrase for the “other” form. Other phrases will
 * be formed by adding a suffix to it with the name of the form: “there_are_x_items_zero”, “there_are_x_items_one”, “there_are_x_items_two”,
 * “there_are_x_items_few”, “there_are_x_items_many”.
 */
$phraseName = \TC\ComponentLibrary\Util\Pluralization::pluralPhraseName(count($items), 'there_are_x_items');

# phrasePlural

Returns a phrase in the required plural form.

public static function phrasePlural($number, $phrases, array $params = [], bool $allowHtml = true, \XF\Language $language = null): \XF\Phrase

# Arguments

Argument Type Default value Description
number int|float Number for pluralization.
phrases string[]|string Names of phrases for different forms of pluralization.
If a string is specified, it will be the name of the phrase in the form other, and names for other forms will be formed by adding the suffixes _zero, _one, _two, _few and _many.
The other form is required.**
params array [] An array of phrase parameters.
allowHtml bool true Enable/disable HTML escaping in a phrase.
language XF\Language XF::language() The language object for which pluralization is being performed.
# Examples
$phrase = \TC\ComponentLibrary\Util\Pluralization::pluralPhraseName(
    count($items),
    'there_are_x_items',
    ['count' => count($items)]
);

# getCardinal

Returns the name of the plural form for the specified language.

public static function getCardinal($number, \XF\Language $language = null, array $availableCardinals = []): string

# Arguments

Argument Typr Default value Description
number int|float Number for pluralization.
language XF\Language XF::language() The language object for which pluralization is being performed.
availableCardinals string[] [] List of available plural forms. If the required plural form is not available, other will be returned.

# getLanguageCode

Returns the language code for the OblikStudio/php-pluralization library.

public static function getLanguageCode(\XF\Language $language): string

# Argument

Argument Type Description
language XF\Language The language object for which the code will be returned.

# getPluralization

Returns the pluralization class from the OblikStudio/php-pluralization library for the specified language.

public static function getLanguageCode(\XF\Language $language): string

# Arguments

Argument Type Description
language XF\Language The language object for which the pluralization class will be returned.

# Pluralization in templates

# tc_phrase_plural

# Arguments

Argument Type Default value Description
number int|float Number for pluralization.
phrases string[]|string Names of phrases for different forms of pluralization.
If a string is specified, it will be the name of the phrase in the form other, and names for other forms will be formed by adding the suffixes _zero, _one, _two, _few and _many.
The other form is required.
params array [] An array of phrase parameters.

# Examples

# Getting the phrase name from a list
{{ tc_phrase_plural(
    count($items),
    {
        'zero': 'there_are_zero_items',
        'one': 'there_is_one_item',
        'two': 'there_are_two_items',
        'few': 'there_are_few_items',
        'many': 'there_are_many_items',
        'other': 'there_are_x_items'
    },
    {'count': count($items)}
) }}
# Getting the name of a phrase without specifying a list of phrases
{{ tc_phrase_plural(count($items), 'there_are_x_items', {'count': count($items)}) }}

# Pluralization in phrases

In addition to pluralization via PHP and a function in templates, it is possible to set pluralization rules directly in phrases. To do this, you need to create a similar construction in the phrase:

{plural
  number="{number}"
  zero="…"
  one="…"
  two="…"
  few="…"
  many="…"
  other="…"
  123="…"
  precision="0"
}

# Arguments

Argument Description
number Number for pluralization. Required parameter.
precision The number of decimal places in the displayed number.
other The value for the form other. Also used if the required form is not available. Required parameter.
Name of any form The value for the specified form.
Any number A value for a specific number.

# Examples

Let's create a phrase named test_plural_phrase for the English language:

There {plural
           number="{count}"
           0="are no books"
           one="is #n book"
           other="are #n books"
         } on the table.

This phrase for the Russian language will look like this:

На столе {plural
           number="{count}"
           0="нет книг"
           1="одна книга"
           one="#n книга"
           few="#n книги"
           other="#n книг"
         }.

Next, display the phrase in the template:

<p>{{ phrase_dynamic('test_plural_phrase', {'count': 0}) }}</p>
<p>{{ phrase_dynamic('test_plural_phrase', {'count': 1}) }}</p>
<p>{{ phrase_dynamic('test_plural_phrase', {'count': 2}) }}</p>
<p>{{ phrase_dynamic('test_plural_phrase', {'count': 5}) }}</p>
<p>{{ phrase_dynamic('test_plural_phrase', {'count': 10}) }}</p>
<p>{{ phrase_dynamic('test_plural_phrase', {'count': 11}) }}</p>
<p>{{ phrase_dynamic('test_plural_phrase', {'count': 101}) }}</p>

Result for English:

There are no books on the table.

There is 1 book on the table.

There are 2 books on the table.

There are 5 books on the table.

There are 10 books on the table.

There are 11 books on the table.

There are 101 books on the table.

Result for Russian:

На столе нет книг.

На столе одна книга.

На столе 2 книги.

На столе 5 книг.

На столе 10 книг.

На столе 11 книг.

На столе 101 книга.