zf2 – translatePlural example with Poedit

Martin Zellerphp, zf2 1 Comment

I’d like to explain how to use the translatePlural method along with the Zend Framework 2.
(I’m assuming that you have been configured Poedit and the Zend Framework so that it works with the normal translate method)

The use of translatePlural is actually quite simple. Let us first look at the normal translate method:

[php] echo $this->translate(‘example.key’);
[/php]

After parsing your code files with Poedit, you add your text for the key “example.key”. For example: “My sample text”.

Poedit adds the following lines to the appropriate *.po file:

[plain] msgid "example.key"
msgid "My sample text"
[/plain]

Now to translatePlural. An example:

NOTE: The sample is suitable for languages with one plural form as English or German. For languages with complex plural forms, for example, Russian, see the note at the bottom!

Suppose you want to echo the text “tooth” if $count is equal to 1 and “teeth” if $count is greater than 1:

[php] $count = rand(1,32); // Generates a random integer between 1 and 32 (inclusive)
echo $this->translatePlural(‘example.key.singular’, ‘example.key.plural’, $count);
[/php]

Simple. The first parameter is the text key for the text if $count is equal to 1 and the second parameter is for $count greater than 1.

What does NOT work:
If you add separate entries for the singular and the plural keys to Poedit, you’ll achieve nothing.

What you need to do:
You must configure Poedit so that it finds “translatePlural” in our project files and interprets it correctly!

Open Poedit and go to: Catalog > Properties
In the first tab you find an input option for “plural forms”.
Enter:

[plain] nplurals=2; plural=(n != 1);
[/plain]

So you say Poedit that we want to use a language with one plural form, in which everything that is not 1, should be plural. So exactly what we need for our example:
1 tooth, 2 teeth, 3 teeth …

Thus Poedit scans your code files right for “translatePlural” you have to add a new keyword in the third tab:
(The keyword “translate” you probably already added)

[plain] translatePlural:1,2
[/plain]

If you then do the update with Poedit, you’ll find input options like this:

poedit-translateplural

This is the result in the appropriate *.po file:

[plain] msgid "example.key.singular"
msgid_plural "example.key.plural"
msgstr[0] "tooth"
msgstr[1] "teeth"
[/plain]

Note for languages with complex plural forms:
Our example is suitable for languages, which has one plural form. The syntax for other languages can be found here:
Overview of plural form syntax

Hint: by default the Zend Framework works only with one plural form. For more complex plural forms you have to work with the optional TextDomain parameter of the method translatePlural. To understand why, have a look at some code of the TextDomain instance that is used by default:

[php] /**
* Returns a shared default plural rule.
*
* @return PluralRule
*/
public static function getDefaultPluralRule()
{
if (static::$defaultPluralRule === null) {
static::$defaultPluralRule = PluralRule::fromString(‘nplurals=2; plural=n != 1;’);
}

return static::$defaultPluralRule;
}
[/php]

Comments 1

  1. I know this is an old post, but it is kind of high ranked in google, so I thought I might add some additional details about ‘complex’ plural forms:

    In fact handling complex plural forms is just as simple as for any other plural form since the Zend Framework translation loader checks for plural rules in the processed files. MO/PO files store plural rules in a standardized format, but all standard loaders (Ini, PhpArray and PhpMemoryArray) also support them, although I didn’t find any documentation about this behavior.
    This means that you can define any plural forms definition in Poedit and the translator will handle it for you and there is no need to use any additional arguments for the translatePlural function.

    As a small fun fact I have discovered that the second parameter of the translatePlural function is only used if there is no translation available at all and it is directly returned if the number is not equal to one.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.