Symfony2: étendre globalement les options des FormType avec l'injection de dépendance

EDIT: Article mis à jour en utilisant les FormExtension que j'ai découvert dans les commentaires.

Dans la première version de Symfony, il existait une option 'help' dans les widgets des formulaires qui permettait d'ajouter un texte sous le champs. J'ai eu besoin de retrouver cette option dans les Type de Symfony2.

On va écarter tout de suite l'option de surcharger tous les types que propose Symfony2. Il est possible d'étendre n'importe quel Type dans Symfony2 grace aux FormExtensions.

<?php
namespace Acme\demoBundle\Form\Extension;
 
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
 
class HelpTypeExtension extends AbstractTypeExtension
{
    public function getExtendedType()
    {
        return 'form';
    }
 
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $view->vars = array_merge($view->vars, array('help' => $options['help']));
    }
 
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array('help' => null));
    }
}

Dans la méthode getExtendedType() j'ai choisi 'form' car je veux que mon Extension soit valable pour tous les Types; setDefaultOptions() permet d'ajouter l'option que je veux et buildView() me permet de passer cette option au template.

Pour utiliser ma nouvelle extension, il faut que je la déclare dans le fichier services.yml de mon bundle:

services:
    acmedemo.form.extension.help:
        class: Acme\DemoBundle\Form\Extension\HelpTypeExtension
        tags:
            - { name: form.type, alias: form }

Il ne reste plus qu'a customiser le thème de mes formulaires dans twig. Pour plus d'info lisez cette page du cookbook de symfony2.
Une fois de plus, je ne veux pas surcharger chaque template, je préfère une modification globale, je redéfinis donc le template form_row

{% block form_row %}
{% spaceless %}
    <div>
        {{ form_label(form) }}
        {{ form_errors(form) }}
        {{ form_widget(form) }}
        {% if form.vars.help is defined and form.vars.help is not null %}
            help: {{ form.vars.help }}
        {% endif %}
    </div>
{% endspaceless %}
{% endblock form_row %}

Et voilà, je peux maintenant ajouter l'option 'help' à mes définitions de champs:

$builder->add('meta_title', 'text', array(
    'label' => 'titre de la page',
    'help'  => 'Recommandé: 68 caractères'
));

 

Il y a 4 commentaires.

Ecrit par Ulrich le 24 avr. 2013

Article mis à jour, merci pour les commentaires.

Ecrit par jojolebg le 24 avr. 2013

Pourquoi ne pas utiliser les extensions de type ? http://symfony.com/fr/doc/2.1/cookbook/form/create_form_type_extension.html Ils en parlent dans la doc, c'est justement fait pour ce genre de cas.

Ecrit par Benjamin le 23 avr. 2013

Sinon il existe un truc qui s'appel les form type extension (http://symfony.com/doc/current/cookbook/form/create_form_type_extension.html) et qui permettent d'ajouter un comportement pour tout les FormType en beaucoup plus propre. La version de mopa pour le help https://github.com/phiamo/MopaBootstrapBundle/blob/master/Form/Extension/HelpFormTypeExtension.php

Réponse de Ulrich le 24 avr. 2013

Ah oui bien mieux, je n'avais pas vu cette page de la doc. Je vais corriger mon code et l'article du coup. merci

Ajouter un commentaire