Partons du principe que l’on souhaite lister les erreurs de validation lors de l’utilisation d’un formulaire avec Symfony 4.
Ça ne sert pas à grand chose mais cet exemple permet de récupérer « l’équivalent » simplifié des données qui remontent dans le profiler de Symfony pour les violations de contraintes sur les champs de ce formulaire.
Pour faire du « debug » rapide, j’utilise simplement un dump() des erreurs directement côté Twig pour m’assurer que les contraintes s’appliquent bien en testant visuellement le formulaire.
J’ai donc déclaré une fonction « macro » utilisée de façon récursive et exécutée pour boucler sur les objets FormErrorsIterator de chaque champ enfant (et enfant(s) d’enfant …).
Note: « _self » désigne le template courant et permet une utilisation immédiate.
Pour Symfony, tout type de champ de formulaire est également un formulaire, il existe donc la notion de formulaire parent et enfant.
La récursivité pour cet exemple provient simplement du fait que j’ai décidé d’afficher l’ensemble des violations de contraintes présentes au sein du root form ici appelé « myRootForm » (variable déclarée pour le formulaire global) :
{% macro form_errors(forms) %} {% for form in forms %} {% for formError in form.vars.errors %} {{ dump(formError.cause.propertyPath, formError.cause.constraint, formError.cause.message) }} {% endfor %} {% if form.children is not empty %} {# Use macro recursively #} {{ _self.form_errors(form.children) }} {% endif %} {% endfor %} {% endmacro %} {# Use macro immediately after declaration in the same template #} {{ _self.form_errors(myRootForm.children) }}
Ce « dump » affiche le propertyPath (le champ concerné), le type de contrainte objet, et le message d’erreur personnalisé ou proposé par défaut.
Les contraintes personnalisées (custom constraints) proposées par Symfony, éventuellement mises en place sur un projet, remontent également dans les boucles.
Pour utiliser votre macro où vous le souhaitez, il suffit de la déclarer dans un template dédié aux déclarations des fonctions macros et ensuite de faire un import de ce template dans un autre template pour pouvoir l’utiliser :
{# Import macro in another template #} {% from 'macros.html.twig' import form_errors %} {# Use macro #} {{ form_errors(myRootForm.children) }} {# ------------------------------------------- #} {# Or import macro like this #} {% import "macros.html.twig" as macros %} {# Use macro in the same way #} {{ macros.form_errors(myRootForm.children) }}
Vous pouvez consulter la documentation concernant les macros Twig.
Voilà, c’est déjà fini !