Accéder au contenu principal

5min.

Customiser les grilles Sylius – DX améliorée avec les Grid mutators

This blog post is also available in 🇬🇧 English: Customizing Sylius Grids – Improved DX with Grid Mutators.

Dans Sylius, les grilles sont responsables de l’affichage des listes du back-office : récupération des données, définition des colonnes, filtres, actions…

Sylius E-commerce fournit un grand nombre de grilles prêtes à l’emploi, qu’il est possible de personnaliser pour répondre aux besoins de votre projet.

Jusqu’à présent, cette personnalisation reposait principalement sur des surcharges de configuration YAML ou sur les Grid events. Ces approches fonctionnent toujours, mais elles atteignent rapidement leurs limites dès que l’on souhaite introduire de la logique métier ou bénéficier d’une API plus moderne et plus agréable à utiliser.

Avec la sortie du GridBundle 1.16, qui sera intégré à Sylius 2.3, une nouvelle approche devient la solution officielle : les Grid mutators. Les anciennes méthodes sont désormais dépréciées et disparaîtront progressivement.

Un Grid mutator est une classe PHP chargée de modifier une grille existante avant sa construction. Il s’appuie sur le même GridBuilder que les grilles PHP, offrant ainsi une API typée, facilement testable et familière pour les développeurs Symfony.

Dans cet article, nous verrons pourquoi cette évolution était nécessaire, quels sont les avantages des Grid mutators et comment commencer à les utiliser dès aujourd’hui afin d’anticiper les futures migrations de Sylius.

Section intitulée un-peu-d-histoireUn peu d’histoire

Historiquement, les grilles de Sylius sont déclarées dans la configuration du GridBundle.

Sylius fournit des fichiers de configuration pour toutes ses grilles dont vous pouvez voir l’un des fichiers de configuration dans cet exemple.

Bien qu’elles soient encore très puissantes, on ne peut pas appliquer d’intelligence à ces grids, comme retreindre les données selon le profil de l’utilisateur.

Section intitulée les-grilles-phpLes grilles PHP

Mais depuis de nombreuses années, le composant Grid propose de configurer les grilles en utilisant le Grid builder.

<?php

namespace App\Grid;

use App\Entity\Book;
use Sylius\Bundle\GridBundle\Builder\Field\StringField;
use Sylius\Component\Grid\Attribute\AsGrid;
use Sylius\Component\Grid\Builder\GridBuilderInterface;

#[AsGrid(
    name: 'app_book',
    resourceClass: Book::class
)]
final class UserGrid
{
    public function __invoke(GridBuilderInterface $gridBuilder): void
    {
        $gridBuilder
            ->orderBy('title', 'asc')
            ->withFields(
                StringField::create('title')
                    ->setLabel('Titre'),
                StringField::create('author')
                    ->setLabel('Auteur'),
            )
        ;
    }
}

Comme vous pouvez le voir, la DX est très proche d’un Doctrine QueryBuilder ou d’un Symfony FormBuilder.

Section intitulée les-avantagesLes avantages :

  • rapprocher les grilles des FormBuilder et QueryBuilder ;
  • bénéficier d’une API typée ;
  • améliorer l’autocomplétion ;
  • simplifier les tests ;
  • éviter les manipulations de tableaux YAML.

De plus, nous sommes maintenant capables d’ajouter de la logique métier.

Exemples :

if (!$this->authorizationChecker->isGranted('ROLE_SUPER_ADMIN')) {
    $gridBuilder->removeField('internalNotes');
}

ou encore

if ($this->featureFlag->isEnabled('new_catalog')) {
    $gridBuilder->addField(...);
}

Section intitulée customiser-une-grilleCustomiser une grille

Reprenons pour exemple la grille des produits fournie par Sylius.

Je vous propose, à titre d’exemple, de retirer le champ image en voyant d’abord les anciennes méthodes, puis la nouvelle façon officielle.

Section intitulée en-modifiant-dans-la-config-du-packageEn modifiant dans la config du package

Comme les grilles de Sylius E-commerce sont actuellement définies dans la configuration Symfony, nous pouvons utiliser un fichier de configuration pour customiser celle-ci.

Nous pouvons ainsi utiliser ce fichier YAML fourni par Sylius Standard et ajouter la configuration suivante :

# config/packages/_sylius.yaml
sylius_grid:
    grids:
        sylius_admin_product:
            fields:
                image:
                    enabled: false

Liste des produits sans les images

C’est relativement simple dans ce cas basique, mais, je le rappelle cette façon est dépréciée sur le GridBundle 1.16.

Pour introduire la nouvelle façon, commençons d’abord en utilisant également un fichier de configuration Symfony mais cette fois avec un fichier PHP.

<?php
// config/packages/sylius_grid.php

$gridBuilder = GridBuilder::create('sylius_admin_product')
    ->removeField('image')

return App::config(['sylius_grid' => (new GridConfig())->addGrid($gridBuilder)->toArray()]);

Nous utilisons ici la classe App fournie par Symfony 7.4 (ou 8.x) pour modifier la configuration du GridBundle. Il y a de la fioriture dans ce fichier, mais nous voyons déjà l’usage de la méthode removeField du GridBuilder que nous allons pouvoir utiliser dans le Grid mutator.

Cette API de GridBuilder n’est pas réservée aux fichiers de configuration PHP. C’est justement elle qui est exploitée par les Grid mutators.

Section intitulée en-utilisant-les-grid-mutatorsEn utilisant les Grid mutators

<?php

namespace App\Grid\Mutator;

use Sylius\Bundle\AdminBundle\Grid\ProductGridInterface;
use Sylius\Component\Grid\Attribute\AsGridMutator;
use Sylius\Component\Grid\Builder\GridBuilderInterface;
use Sylius\Component\Grid\Mutator\GridMutatorInterface;

#[AsGridMutator(
    grid: 'sylius_admin_product', 
    // ou
    grid: ProductGridInterface::NAME // constante ajoutée sur Sylius 2.3
)]
class RemoveImageFromProductGridMutator implements GridMutatorInterface
{
    public function __invoke(GridBuilderInterface $gridBuilder): void
    {
        $gridBuilder->removeField('image');
    }
}

Comme vous pouvez le voir, nous utilisons simplement un attribut PHP fourni par le GridBundle qui nous injecte directement le GridBuilder.

Sylius 2.3 nous permettra de basculer entre sa configuration de grilles dans la config (dépréciée) et celle en PHP. Vous pouvez utiliser les mutators dans les deux cas, ce qui facilite la transition. Nous allons donc probablement devoir migrer nos surcharges de configuration de grilles vers des Grid mutators, ce qui nous amène au chapitre suivant.

Section intitulée convertir-les-grillesConvertir les grilles

Si vous utilisez des grilles customs, c’est-à-dire des grilles qui ne sont pas fournies par Sylius directement, vous devez créer un nouveau service qui comportera l’attribut AsGrid. Afin de vous faciliter cette conversion, il existe un outil officiel : le Sylius Grid Converter.

Et pour les surcharges de grilles Sylius ? A l’heure où j’écris ces lignes, l’option mutator n’existe pas encore, mais elle va arriver très prochainement !

Section intitulée et-les-grid-eventsEt les Grid events ?

Les Grid events sont l’ancienne solution pour customiser vos grilles si vous souhaitez utiliser du PHP plutôt que de surcharger la config en YAML. Il faut dans ce cas écouter l’évènement GridDefinitionConverterEvent.

namespace App\Grid;

use Sylius\Component\Grid\Event\GridDefinitionConverterEvent;
use Sylius\Component\Grid\Definition\Field;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;

#[AsEventListener(event: 'sylius.grid.admin_product', method: 'editFields')]
final class RemoveImageFromProductGridListener
{
    public function editFields(GridDefinitionConverterEvent $event): void
    {
        $grid = $event->getGrid();

        $grid->removeField('image');
    }
}

Cela ressemble beaucoup aux grids mutators, mais vous attaquez directement l’objet Grid definition et non le GridBuilder. Le builder fournit davantage de helpers pour vous aider à construire cette définition. Un autre inconvénient de cet event listener est qu’il faut deviner le nom de l’event.

Comme nous le disions plus haut, ces Grid events sont dépréciées dans Sylius GridBundle 1.16, alors débarrassez-vous en.

Section intitulée conclusionConclusion

Les Grid mutators apportent enfin une manière claire, typée et testable de personnaliser les grilles Sylius. En s’appuyant sur le GridBuilder, ils offrent une API moderne, familière aux développeurs Symfony et bien plus adaptée aux besoins actuels que les anciennes surcharges YAML ou les Grid events.

Avec l’arrivée de GridBundle 1.16 et de Sylius 2.3, ils deviennent la nouvelle approche officielle pour faire évoluer les grilles. L’adoption peut se faire progressivement, puisqu’ils sont compatibles aussi bien avec les grilles déclarées en YAML qu’avec les nouvelles grilles PHP.

Si vous commencez dès aujourd’hui à migrer vos surcharges de configuration et vos Grid events vers des Grid mutators, la transition vers les prochaines versions de Sylius sera largement simplifiée. Vous profiterez également d’une API plus agréable à utiliser, plus facile à maintenir et à déboguer au quotidien.

Commentaires et discussions

Ces clients ont profité de notre expertise