Créer son propre ViewHelper avec Fluid

Publié le

Aujourd’hui, je me suis penché sur la création de formulaires avec Fluid. Les formulaires sont bien pratiques comme vous le savez, puisqu’il permettent aux internautes d’intéragir avec une application. Fluid offre une quantité importante de ViewHelpers (ou aides de vue) pour générer le code HTML souhaité.

Pour la création de formulaires, les ViewHelpers se situent dans un sous dossier « Form » (Classes/ViewHelpers/Form). Chaque fichier situé dans ce dossier, permet de créer un type d’élément (ou champ) de formulaire : bouton radio, menu déroulant, champ de type textarea, bouton submit, etc.

Prenons l’exemple d’un champ de sélection :

<f:form.select name= »region » options= »{1: ‘Alsace’, 2: ‘Aquitaine’, 3:’Auvergne’} »  />

Il s’agit ici d’un exemple classique. On indique des couples valeur/titre, comme dans un tableau associatif en javascript. Si l’on souhaite injecter des valeurs provenant directement de la base de données, il faudra interroger le repository du modèle concerné avec la méthode findAll() par exemple ; dans ce cas là, ce n’est pas un tableau que l’on passe mais un objet.

Dans le contrôleur :
$regions = $this->regionRepository->findAll();
$this->view->assign(‘regions’, $regions);

Dans un gabarit Fluid :
<f:form.select name= »region » options= »{regions} » optionValueField= »uid » optionLabelField= »title » />

Notez que l’on spécifie ici les paramètres optionValueField et optionLabelField pour indiquer respectivement le champ utilisé pour la valeur de chaque option et l’intitulé. C’est obligatoire pour éviter d’avoir à la place un label composé du nom du modèle et de l’uid, ce qui ne voudrait pas dire grand chose.

Ainsi, on aurait donc le code suivant généré dans le navigateur :

<select name= »tx_monextension_nomplugin[region] »>
<option value= »1″>Alsace</option>
<option value= »2″>Aquitaine</option>
<option value= »3″>Auvergne</option>
etc…
</select>

Ce qu’il nous manque tout de même, c’est une option vide ou personnalisée dans notre menu de sélection pour  inviter l’utilisateur à faire un choix dans le menu déroulant. Or, si l’on regarde le ViewHelper « Tx_Fluid_ViewHelpers_Form_SelectViewHelper », rien n’indique la possibilité d’ajouter une option personnalisée  avant la liste.

J’ai vu une « feature request » à ce sujet sur Forge. Ca serait bien utile, non ?
Oui et non. En fait, le problème peut-être contourné très facilement et proprement !

Nous allons faire une sorte de « Xclass ». Alors, ce genre de manipulation ici est plutôt recommandé dans Fluid, contrairement aux extensions TYPO3 où il y a toujours un risque ; on recommande d’ailleurs l’exploitation de hooks mais je m’égare… revenons à nos moutons. Bref, la création de ViewHelpers est encouragée et dans notre cas, c’est indispensable.

Sachez que l’implémentation est aisée. Nous allons recopier la structure des dossiers du ViewHelper « Tx_Fluid_ViewHelpers_Form_SelectViewHelper » dans notre extension.

Nous avons donc :
mon_extension/Classes/ViewHelpers/Form/SelectViewHelper.php
Dans ce fichier, nous allons créer une classe étendue de Tx_Fluid_ViewHelpers_Form_SelectViewHelper. Elle portera le nom de notre extension : Tx_MonExtension_ViewHelpers_Form_SelectViewHelper. La notation UpperCamelCase doit être respectée. Comme vous le voyez, le nom indique le chemin vers le fichier.

Nous allons ensuite modifier la fonction initializeArguments pour ajouter notre argument personnalisé. En effet, nous allons indiquer à Fluid la valeur que nous souhaitons ajouter à notre liste d’options. Fluid doit donc être au courant du paramètre attendu et de son format.

/**
* Initialize arguments.
*
* @return void
*/
public function initializeArguments() {
parent::initializeArguments();

$this->registerArgument(‘defaultOption’, ‘string’, ‘Value to prepend to the options’, FALSE);
}

parent::initializeArguments() permet d’initialiser les arguments de la classe parent.

Ensuite, nous allons modifier la fonction getOptions. Cette fonction retourne un tableau associatif, composé des options du champ de sélection. Le code ci-dessous permet d’ajouter la valeur de notre argument ‘defaultOption’ à la liste d’options provenant du repository.

/**
* Get parent options plus the new one
* Render the option tag
*
* @return array an associative array of options, key will be the value of the option tag
*
*/
protected function getOptions() {
return array($this->arguments[‘defaultOption’]) + parent::getOptions();
}

Ces deux fonctions doivent être contenues dans la classe Tx_MonExtension_ViewHelpers_Form_SelectViewHelper.

Exemple :

class Tx_MonExtension_ViewHelpers_Form_SelectViewHelper extends Tx_Fluid_ViewHelpers_Form_SelectViewHelper {

// methodes

}

Ensuite, comme nous appelons le ViewHelper de notre extension, nous devons spécifier un nouvel espace de nom dans notre gabarit.

{namespace monext=Tx_MonExtension_ViewHelpers}

Puis :

<monext:form.select name= »region » options= »{regions} » optionValueField= »uid » optionLabelField= »title » defaultOption= »Sélectionnez une région » />

Deux remarques :
– monext:form.select a remplacé f:form.select. L’intitulé monext est arbitraire. Vous faites comme bon vous semble. La seule contrainte, c’est de faire le lien avec l’espace de nom (namespace).
– On a utilisé le paramètre « defaultOption » pour passer la valeur par défaut. A titre personnel, j’utilise plutôt Tx_Extbase_Utility_Localization. Il s’agit d’un helper qui permet de lire les fichiers locallang. J’assigne ensuite la valeur retournée en tant que valeur de l’argument « defaultOption ».

Au final :

<select name= »tx_monextension_nomplugin[region] »>
<option value= »0″>Sélectionnez une région</option>
<option value= »1″>Alsace</option>
<option value= »2″>Aquitaine</option>
<option value= »3″>Auvergne</option>
etc…
</select>

Comme vous le voyez, c’est simple mais encore faut-il savoir par où commencer ! C’était le but de cet article. Si vous souhaitez progresser sur le sujet, je vous recommande l’installation de l’extension sjr_offers qui contient plusieurs ViewHelpers.

N’hésitez pas à commenter cet article 🙂

Publicités