Symfony2 et Twitter Bootstrap : insérer un input checkbox ou radio dans un label

Ayant récemment utilisé Twitter Bootstrap pour l’interface d’administration d’un projet en Symfony2, je me suis heurté à un problème basique à propos de la gestion des formulaires.

Pour aligner verticalement un input de type radio ou checkbox avec son label il faut inclure le premier dans le second :

<label class="checkbox">
    <input type="checkbox"> Check me out
</label>

Ce code peut paraître simple, mais produire ce même HTML avec Symfony2 l’est moins. En effet, pour afficher les formulaires, Symfony2 utilise des blocs de templates Twig. Chaque bloc correspond à un type de champs, à l’affichage des labels ou plus globalement à l’affichage du formulaire. On peut retrouver leur définition dans le fichier form_div_layout.html.twig.

Première méthode : redéfinir le bloc dans la template

La façon la plus simple d’écraser la définition du bloc est de le faire à l’intérieur de la template du formulaire concernée :

{% form_theme form _self %}

{% block checkbox_widget %}
    {% spaceless %}
        <label class="checkbox">
            <input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
            {{ form_label(form) }}
        </label>
    {% endspaceless %}
{% endblock %}

La première ligne indique à Twig de chercher à l’intérieur de la template si des fragments de blocs ne sont pas disponibles. Pour le reste du code, nul besoin d’explication. Il suffit de copier-coller le bloc défini dans form_div_layout.html.twig puis de réordonner le HTML.

Seconde méthode : redéfinir le bloc de façon globale

Si vous avez besoin d’appliquer ce fragment de template sur tous les formulaires de votre projet, il est plus simple de le définir à un seul endroit plutôt que de le copier-coller dans chaque template. Symfony permet de faire cela très rapidement et simplement.

Créer un fichier Resources/views/Form/fields.html.twig dans le répertoire de votre bundle avec le code ci-dessous :

{% block checkbox_widget %}
    {% spaceless %}
        <label class="checkbox">
            <input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
            {{ form_label(form) }}
        </label>
    {% endspaceless %}
{% endblock %}

Pour rendre Twig au courant de la présence de ce fichier il existe là encore deux méthodes.
La première suit l’exemple précédent, à savoir indiquer à Twig dans la template la location du fichier concerné :

{% form_theme form 'AcmeDemoBundle:Form:fields.html.twig' %}

La seconde, qui permet de ne plus avoir à modifier chaque template, consiste à indiquer à Twig l’emplacement du fichier concerné, mais cette fois dans le fichier de configuration de Symfony : app/config/config.yml.

twig:
    form:
        resources:
            - 'AcmeDemoBundle:Form:fields.html.twig'

Conclusion

Tout au long de cet article nous nous sommes intéressés aux checkbox. Le fonctionnement est identique pour les radios en adaptant les bons blocs.

Il n’est finalement pas très compliqué de modifier les templates de formulaires Symfony2. Cela requiert un minimum de connaissances quant à l’héritage des blocs Twig mais en quelques dizaines de minutes maximum il est possible de personnaliser un projet complet.

Commentaires

  1. Stand

    Clair et concis. Merci pour le tuto.

Ajouter un commentaire