dimanche 3 février 2013

Gestion des pluriels avec le framework PHP Yii


Yii (pour Yes, it is) est un framework PHP open-source et gratuit amorcé par Qiang Xue en 2008. Axé sur la performance, basé sur une architecture MVC et suivant le paradigme de la programmation événementielle, il propose aussi la traduction de message, le formatage de la date et de l'heure, les différents formats de nombres et la localisation d'interface. Nous allons nous concentrer ici sur la façon dont Yii gère les pluriels dans la fonction de traduction des messages de sa version actuelle (1.1.13).

L'internationalisation avec Yii


Nous allons mettre en place une implémentation minimale du framework Yii qui ne contiendra qu'un contrôleur et une seule méthode.

L'internationalisation des textes dans Yii peut se faire depuis plusieurs sources :
  • un tableau associatif de clés/valeurs dans un ensemble de répertoires : c'est la solution par défaut qui utilise la classe CPhpMessageSource
  • une base de données contenant une table source et une table message : cette solution utilise la classe CDbMessageSource
  • une source GNU Gettext basée sur des fichiers .po ou leur pendant binaire .mo : cette solution est définie par la classe CGettextMessageSource
Chacune de ces méthodes peut utiliser cachingDuration, un paramètre qui mettra en cache le résultat de la traduction pour le temps indiqué.

Dans notre exemple, nous utiliserons un tableau associatif en PHP.

L'architecture des fichiers sera donc la suivante :
framework/
test/protected/controllers/SiteController.php
test/protected/messages/fr/test.php
test/index.php
Pour afficher correctement les caractères accentués encodés en UTF-8, il faut que le fichier de langue protected/messages/fr/test.php soit bien sûr encodé en UTF-8, et que le fichier index de votre application test/index.php indique l'encodage des caractères avec la ligne suivante :
header("Content-Type: text/html; charset=utf-8");
Le fichier test/protected/messages/fr/test.php contient le tableau associatif des clés de traduction dans la langue source (l'anglais par défaut) et de leurs valeurs traduites.
return array (
    'You have a message.' => 'Vous avez un message.',
);
Dans le contrôleur, on commence par indiquer la langue de consultation (ici, le français), puis on utilise la méthode t de la classe YiiBase (définie dans YiiBase.php) qui prend en paramètres la catégorie du message (ici, le nom du fichier contenant le tableau associatif sous messages/fr/, soit test), puis la clé (ou la chaîne dans la langue source).
echo Yii::t('test','You have a message.')
On obtient bien : Vous avez un message.

La pluralisation avec Yii


Revenons à notre problématique de pluralisation de message présenté dans un billet précédent (Des pluriels bien singuliers). Pour rappel, il existe selon les langues différentes formes de nombres grammaticaux, et pas seulement un singulier et un pluriel comme en français.

L'exemple que nous voulons couvrir est celui-ci : une interface peut afficher 0 message (ou Aucun message), 1 message (ou Un message), ou encore n messages, n étant un espace réservé pour être remplacé à la volée lors du traitement.

Le helper CChoiceFormat (que l'on trouve dans le répertoire framework/i18n/) permet d'exprimer simplement les différentes valeurs possibles d'un message grâce aux règles de pluralisation des langues déjà supportées par le framework, que l'on trouve dans le répertoire framework/i18n/data/, dans les fichiers consacrés à chaque langue et locale.

On y trouve par exemple celles du français dans fr.php :
'pluralRules' =>
    array (
        0 => '(n>=0&&n<=2)&&n!=2',
        1 => 'true',
    ),
C'est la classe CLocale qui y accède via sa méthode getPluralRules(). Cette méthode est appelée par la méthode t (utilisée plus haut) de la classe YiiBase et dont vous pouvez apprécier le code.

Pour en savoir plus sur les types de pluriels par langue, je vous renvoie au Common Locale Data Repository de l'Unicode. On y trouve explicitées les règles de pluralisation qui permettent d'établir les formules précédentes.

La compacité d'utilisation de ces règles est illustrée ici avec un seul mot.
for ($i=0; $i<3; $i++)
{
    echo Yii::t('test', "message|messages", $i);
}
Affiche pour les valeurs de 0 à 2 :
message
message
messages
Mais une expression plus parlante peut aussi être utilisée.
for ($i=0; $i<4; $i++)
{
    echo Yii::t('test', "Vous avez {n} message.|Vous avez {n} messages.", $i);
}
Affiche :
Vous avez 0 message.
Vous avez 1 message.
Vous avez 2 messages.
Vous avez 3 messages.
Il est aussi possible d'affiner les messages en utilisant directement une expression PHP ou bien une valeur.
for ($i=0; $i<3; $i++)
{
    echo Yii::t('test', "0#Vous n'avez aucun message.|1#Vous avez un message.|n>1#Vous avez plusieurs messages.", $i);
}
Affiche :
Vous n'avez aucun message.
Vous avez un message.
Vous avez plusieurs messages.

Internationalisation et pluralisation


L'étape suivante est bien entendu de gérer à la fois l'internationalisation et la pluralisation. Pour ce faire, il suffit d'utiliser le message complet avec ses variantes d'expressions dans la langue source (ici, l'anglais) et de l'utiliser comme clé dans le tableau des langues.

Avec un fichier de langue tel que celui-ci :
return array (
    "0#You don't have any message.|1#You have one message.|n>1#You have many messages." => "0#Vous n'avez aucun message.|1#Vous avez un message.|n>1#Vous avez plusieurs messages.",
);
Le contrôleur :
for ($i=0; $i<3; $i++)
{
    echo Yii::t('test', "0#You don't have any message.|1#You have one message.|n>1#You have many messages.", $i);
}
Affiche toujours en français :
Vous n'avez aucun message.
Vous avez un message.
Vous avez plusieurs messages.
Et en anglais (en commentant la ligne Yii::app()->setLanguage('fr');) :
You don't have any message.
You have one message.
You have many messages.

Le mot de la fin


Comme vous avez pu le constater sur ces quelques exemples, les développeurs du framework Yii ont su mettre en place une solution très élégante de la gestion des pluriels qui permet d'exprimer une grande complexité due à la variété des cas possibles tout en conservant une relative simplicité d'utilisation. Elle permet de couvrir une partie des différents types de pluriels entre des langues ayant des nombres grammaticaux différents, mais aussi de gérer simplement des affichages contextuels différents pour une même langue.

Lecture


Pour aller plus loin dans la connaissance du framework Yii, je vous conseille la lecture de ces deux ouvrages :
Yii Rapid Application Development

Yii Rapid Application Development, par Lauren J. O'Meara et James R. Hamilton III (2012, 340 pages)

Vous y découvrirez le développement d'une application complète sous forme de projets et de missions axées sur des fonctionnalités et des points-clés à la fois du framework et d'une application réelle.
Web Application Development with Yii and PHP

Web Application Development with Yii and PHP, par Jeffrey Winesett (2012, 332 pages)

Vous y trouverez une introduction au framework, mais surtout le développement pas à pas d'une application web complète.

Crédit photo : gringer


Handling plurals with the Yii PHP framework (en anglais)
Gestão dos plurais com o framework PHP Yii (en portugais)
Gestión de los plurales con el framework PHP Yii (en espagnol)

Aucun commentaire:

Enregistrer un commentaire