Zend_Translate, gettext et les pluriels

Zend_Translate gère les pluriels, mais la documentation officielle donne peu de détails sur la manière de procéder avec l'adaptateur gettext. Pour vous faire gagner un peu de temps, voici ce que vous devez savoir pour une traduction Française.

Dans votre fichier .po, vous devez ajouter dans l'entête :

"Plural-Forms: nplurals=2; plural=n>1;\n"

Ensuite, sur les termes où vous avez besoin du pluriel, vous devez utiliser la syntaxe suivante :

msgid "hour"
msgid_plural "hour_plural"
msgstr[0] "heure"
msgstr[1] "heures"

Quelques explications sur cette syntaxe un peu particulière :

nplurals c'est pour indiquer qu'en français il y a deux formes : le singulier et le pluriel.

Ensuite l'expression qui suit (après le point-virgule) est utilisée pour déterminer l'index du tableau msgstr à utiliser. n est le nombre d'éléments passé. Si il est inférieur ou égal à 1, l'expression renvoie false (soit zéro en C). Si il est supérieur à 1, cette expression est évaluée à true (soit un en C). En Français, on utilise le singulier pour un élément ou aucun (aucune heure, une heure) et le pluriel dans les autres cas (trois heures).

Vous devez spécifier 2 identifiants pour les messages : un pour le singulier, le deuxième pour le pluriel. J'utilise un suffixe _plural au lieu de reprendre le terme Anglais au pluriel car certains mots anglais sont invariants (comme sheep par exemple). Ensuite, msgstr se comporte un peu comme un tableau, ou le premier élément correspond au singulier et le deuxième au pluriel.

Notez que PoEdit ne gère pas les pluriels (ou alors c'est bien caché). Si vous travaillez sur Windows, BetterPOEditor a l'air d'être une bonne alternative.

Une fois que le fichier .mo a été compilé en .po, vous pouvez l'utiliser dans vos scripts de vue :

// Affiche 1 heure
echo $this->translate(array('hour', 'hour_plural', 1));
// Affiche 3 heures
echo $this->translate(array('hour', 'hour_plural', 3));
// Affiche 0 heure
echo $this->translate(array('hour', 'hour_plural', 0));

En fait, il suffit de passer un tableau avec l'ID du singulier, l'ID du pluriel et le nombre d'éléments en lieu et place de l'ID du message qu'on passe habituellement.

Reste un problème avec les nombres réels. Si on est inférieur à 2, à priori (je ne m'appelle pas Maître Capello), on devrait utiliser le singulier (ex. 0,5 heure, 1,5 heure). Hors pour l'instant, Zend_Translate utilise le pluriel.... Affaire à suivre.

Mise à jour : On peut corriger le problème des fractions avec :

Zend_Translate_Plural::setPlural(function($number) { return $number < 2 ? 0 : 1; }, 'fr');

Add new comment