phpBB

Development Wiki

Plural Rules

From phpBB Development Wiki

Short Example

The english language is very simple when it comes to plurals.

You have 0 elephants, 1 elephant, or 2+ elephants. So basically you have 2 different forms: one singular and one plural.


But for some other languages this is quite more difficult. Let's take the Bosnian language as another example:

You have [1/21/31] slon, [2/3/4] slona, [0/5/6] slonova and [7/8/9/11] ... and some more difficult rules.

The problem with the old system of plurals was, that you would have needed to specify them all, and get a loop in there.


As we are not the first developers facing this problem, it was not really hard to find a suitable solution. We decided, to use the system from https://developer.mozilla.org/en/Localization_and_Plurals

Plural Rules

So we defined the following 16 rules for plurals. First point is the language family, afterwards there are a number of rows with the following format: <key> - <rule>: <example-numbers>

PLEASE NOTE: 0 can be handled special case. If you add a key 0 to your array, that will be used in case of 0 independent of the plural rule.

Rule #0

  • Families: Asian (Chinese, Japanese, Korean, Vietnamese), Persian, Turkic/Altaic (Turkish), Thai, Lao
  • 1 - everything: 0, 1, 2, ...

Rule #1

  • Families: Germanic (Danish, Dutch, English, Faroese, Frisian, German, Norwegian, Swedish), Finno-Ugric (Estonian, Finnish, Hungarian), Language isolate (Basque), Latin/Greek (Greek), Semitic (Hebrew), Romanic (Italian, Portuguese, Spanish, Catalan)
  • 1 - 1
  • 2 - everything else: 0, 2, 3, ...

Rule #2

  • Families: Romanic (French, Portuguese, Brazilian Portuguese)
  • 1 - 0, 1
  • 2 - everything else: 2, 3, ...

Rule #3

  • Families: Baltic (Latvian)
  • 1 -0
  • 2 - ends in 1, not 11: 1, 21, ... 101, 121, ...
  • 3 - everything else: 2, 3, ... 10, 11, 12, ... 20, 22, ...

Rule #4

  • Families: Celtic (Scottish Gaelic)
  • 1 - is 1 or 11: 1, 11
  • 2 - is 2 or 12: 2, 12
  • 3 - others between 3 and 19: 3, 4, ... 10, 13, ... 18, 19
  • 4 - everything else: 0, 20, 21, ...

Rule #5

  • Families: Romanic (Romanian)
  • 1 - 1
  • 2 - is 0 or ends in 01-19: 0, 2, 3, ... 19, 101, 102, ... 119, 201, ...
  • 3 - everything else: 20, 21, ...

Rule #6

  • Families: Baltic (Lithuanian)
  • 1 - ends in 1, not 11: 1, 21, 31, ... 101, 121, ...
  • 2 - ends in 0 or ends in 10-20: 0, 10, 11, 12, ... 19, 20, 30, 40, ...
  • 3 - everything else: 2, 3, ... 8, 9, 22, 23, ... 29, 32, 33, ...

Rule #7

  • Families: Slavic (Bosnian, Croatian, Serbian, Russian, Ukrainian)
  • 1 - ends in 1, not 11: 1, 21, 31, ... 101, 121, ...
  • 2 - ends in 2-4, not 12-14: 2, 3, 4, 22, 23, 24, 32, ...
  • 3 - everything else: 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 26, ...

Rule #8

  • Families: Slavic (Slovak, Czech)
  • 1 - 1
  • 2 - 2, 3, 4
  • 3 - everything else: 0, 5, 6, 7, ...

Rule #9

  • Families: Slavic (Polish)
  • 1 - 1
  • 2 - ends in 2-4, not 12-14: 2, 3, 4, 22, 23, 24, 32, ... 104, 122, ...
  • 3 - everything else: 0, 5, 6, ... 11, 12, 13, 14, 15, ... 20, 21, 25, ...

Rule #10

  • Families: Slavic (Slovenian, Sorbian)
  • 1 - ends in 01: 1, 101, 201, ...
  • 2 - ends in 02: 2, 102, 202, ...
  • 3 - ends in 03-04: 3, 4, 103, 104, 203, 204, ...
  • 4 - everything else: 0, 5, 6, 7, 8, 9, 10, 11, ...

Rule #11

  • Families: Celtic (Irish Gaeilge)
  • 1 - 1
  • 2 - 2
  • 3 - is 3-6: 3, 4, 5, 6
  • 4 - is 7-10: 7, 8, 9, 10
  • 5 - everything else: 0, 11, 12, ...

Rule #12

  • Families: Semitic (Arabic)
  • 1 - 1
  • 2 - 2
  • 3 - ends in 03-10: 3, 4, ... 10, 103, 104, ... 110, 203, 204, ...
  • 4 - ends in 11-99: 11, ... 99, 111, 112, ...
  • 5 - everything else: 100, 101, 102, 200, 201, 202, ...
  • 6 - 0

Rule #13

  • Families: Semitic (Maltese)
  • 1 - 1
  • 2 - ends in 01-10: 0, 2, 3, ... 9, 10, 101, 102, ...
  • 3 - ends in 11-19: 11, 12, ... 18, 19, 111, 112, ...
  • 4 - everything else: 20, 21, ...

Rule #14

  • Families: Slavic (Macedonian, Bulgarian)
  • 1 - ends in 1: 1, 11, 21, ...
  • 2 - ends in 2: 2, 12, 22, ...
  • 3 - everything else: 0, 3, 4, ... 10, 13, 14, ... 20, 23, ...

Rule #15

  • Families: Icelandic
  • 1 - ends in 1, not 11: 1, 21, 31, ... 101, 121, 131, ...
  • 2 - everything else: 0, 2, 3, ... 10, 11, 12, ... 20, 22, ...

How to use the rules

The first thing your language package needs, is a definition, which rule to use for your package. This is done in the language/xy/common.php language file at the beginning of the array, (Rule #1 is the rule for the English language and will be used as default, if you don't specify one):

'PLURAL_RULE'		=> 1,

I'm now using rule #13 as example:

It has the following rows:

  • 1 - 1
  • 2 - ends in 01-10: 2, 3, ... 9, 10, 101, 102, ...
  • 3 - ends in 11-19: 11, 12, ... 18, 19, 111, 112, ...
  • 4 - everything else: 20, 21, ...

While the English language only has 3 rows in its array:

	'EXAMPLE'	=> array(
		1 => '1 example',
		2 => '2 or more examples',
	),

You need to specify the zero-row and 4 rows for the "plurals":

	'EXAMPLE'	=> array(
		1 => '1 example',
		2 => '[0 or number ending with 01-10] examples',
		3 => '[number ending with 11-19] example',
		4 => 'even more examples',
	),

If you want to get a separate handling for 0, you can simple add the 0-case:

	'EXAMPLE'	=> array(
		0 => 'No example',
		1 => '1 example',
		2 => '[zero is not handled here anymore! Only number ending with 01-10] examples',
		3 => '[number ending with 11-19] example',
		4 => 'even more examples',
	),

If you forget a line the system will automatically use the row before. So if you forget to add the 3-row, it will use 2-row for 11-19 as well. If there is no previous row, it uses the last row of the array.


Ensure that your cases are ordered ascending, otherwise the system might act weird, if not all keys are present.

Credits

The system is based on Mozilla ( https://developer.mozilla.org/en/Localization_and_Plurals ), which uses the "Plural Rules and Families" from GNU gettext documentation ( http://www.gnu.org/software/gettext/manual/html_node/gettext_150.html#Plural-forms )