Customizing Sylius Grids – Improved DX with Grid Mutators
In Sylius, grids handle back-office list rendering: data fetching, column definitions, filters, actions, and more.
Sylius E-commerce ships with a large number of ready-to-use grids that can be customized to fit your project’s needs.
Until now, customization mainly relied on YAML configuration overrides or Grid events. These approaches still work, but they quickly hit their limits when you need to introduce business logic or benefit from a more modern, pleasant API.
With the upcoming release of GridBundle 1.16 — which will be integrated into Sylius 2.3 — a new approach becomes the official solution: Grid mutators. The old methods are now deprecated and will be phased out.
A Grid mutator is a PHP class that modifies an existing grid before it is built. It uses the same GridBuilder as PHP grids, providing a typed, easily testable API that feels familiar to Symfony developers.
In this article, we’ll look at why this change was necessary, the benefits of Grid mutators, and how to start using them today to prepare for future Sylius upgrades.
Section intitulée a-bit-of-historyA bit of history
Historically, Sylius grids are declared in the GridBundle configuration.
Sylius provides configuration files for every grid. You can see one of the configuration files in this example.
Although still very powerful, these config files don’t let you apply logic to grids — like restricting data based on the user’s profile.
Section intitulée php-gridsPHP grids
For many years now, the Grid component has offered the ability to configure grids using the Grid builder.
<?php
namespace App\Grid;
use App\Entity\Book;
use Sylius\Bundle\GridBundle\Builder\Field\StringField;
use Sylius\Bundle\GridBundle\Builder\GridBuilderInterface;
use Sylius\Component\Grid\Attribute\AsGrid;
#[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('Title'),
StringField::create('author')
->setLabel('Author'),
)
;
}
}
As you can see, the DX is very close to a Doctrine QueryBuilder or a Symfony FormBuilder.
Section intitulée the-benefitsThe benefits:
- bringing grids closer to FormBuilder and QueryBuilder;
- a typed API;
- better autocompletion;
- simpler testing;
- no more YAML array manipulation.
What’s more, we can now add business logic.
Examples:
if (!$this->authorizationChecker->isGranted('ROLE_SUPER_ADMIN')) {
$gridBuilder->removeField('internalNotes');
}
or
if ($this->featureFlag->isEnabled('new_catalog')) {
$gridBuilder->addField(...);
}
Section intitulée customizing-a-gridCustomizing a grid
Let’s use the product grid shipped by Sylius as an example.
As a hands-on example, I’d like to remove the image field — first using the old approach, then the new official way.
Section intitulée by-modifying-the-package-configBy modifying the package config
Since Sylius E-commerce grids are currently configured in Symfony config, you can use a configuration file to customize them.
Use the YAML file provided by Sylius Standard and add the following configuration:
# config/packages/_sylius.yaml
sylius_grid:
grids:
sylius_admin_product:
fields:
image:
enabled: false

This is fairly simple in this basic case, but remember that this approach is deprecated in GridBundle 1.16.
To introduce the new way, let’s start by also using a Symfony config file, but this time with 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()]);
Here we’re using the App class provided by Symfony 7.4+ to modify the GridBundle config. There’s some boilerplate, but we can already see the removeField method that we’ll be able to use in Grid mutators.
This GridBuilder API isn’t limited to PHP config files — it’s exactly what Grid mutators leverage.
Section intitulée using-grid-mutatorsUsing Grid mutators
<?php
namespace App\Grid\Mutator;
use Sylius\Bundle\AdminBundle\Grid\ProductGridInterface
use Sylius\Bundle\GridBundle\Builder\GridBuilderInterface;
use Sylius\Component\Grid\Attribute\AsGridMutator;
use Sylius\Component\Grid\Mutator\GridMutatorInterface;
#[AsGridMutator(
grid: 'sylius_admin_product',
// or
grid: ProductGridInterface::NAME // constant added in Sylius 2.3
)]
class RemoveImageFromProductGridMutator implements GridMutatorInterface
{
public function __invoke(GridBuilderInterface $gridBuilder): void
{
$gridBuilder->removeField('image');
}
}
As you can see, we simply use a PHP attribute provided by GridBundle, which injects the GridBuilder directly.
Sylius 2.3 will let you switch between grid configuration in config files (deprecated) and PHP. You can use mutators in both cases, making the transition smoother. You’ll likely need to migrate your grid configuration overrides to Grid mutators — which brings us to the next chapter.
Section intitulée converting-gridsConverting grids
If you use custom grids — grids not directly provided by Sylius — you need to create a new service with the AsGrid attribute. To help with this conversion, use the official tool: the Sylius Grid Converter.
And what about Sylius grid overrides? At the time of writing, the mutator option doesn’t exist yet, but it’s coming very soon!
Section intitulée what-about-grid-eventsWhat about Grid events?
Grid events are the old solution for customizing grids with PHP instead of overriding the YAML config. You had to listen for the 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');
}
}
This looks similar to Grid mutators, but you’re directly manipulating the Grid definition object instead of the GridBuilder. The builder provides more helpers to build this definition. Another downside of this event listener is having to guess the event name.
As mentioned earlier, these Grid events are deprecated in Sylius GridBundle 1.16, so get rid of them.
Section intitulée conclusionConclusion
Grid mutators finally provide a clear, typed, and testable way to customize Sylius grids. By building on the GridBuilder, they offer a modern API familiar to Symfony developers and much better suited to today’s needs than the old YAML overrides or Grid events.
With the arrival of GridBundle 1.16 and Sylius 2.3, they become the new official approach for evolving grids. Adoption can happen progressively, since they’re compatible with both YAML-declared grids and the new PHP grids.
If you start migrating your configuration overrides and Grid events to Grid mutators today, the transition to future Sylius versions will be much smoother. You’ll also benefit from a more enjoyable API that’s easier to maintain and debug day-to-day.
Commentaires et discussions
Nos formations sur ce sujet
Notre expertise est aussi disponible sous forme de formations professionnelles !
Sylius
Cette formation vous permettra de comprendre les concepts métiers fondamentaux de Sylius, son architecture technique et plus encore.
Ces clients ont profité de notre expertise
Ouibus a pour ambition de devenir la référence du transport en bus longue distance. Dans cette optique, les enjeux à venir de la compagnie sont nombreux (vente multi-produit, agrandissement du réseau, diminution du time-to-market, amélioration de l’expérience et de la satisfaction client) et ont des conséquences sur la structuration de la nouvelle…
La nouvelle version du site naissance.fr développée s’appuie sur Symfony 2 et Elasticsearch. Cette refonte propose un tunnel d’achat spécialement développé pour l’application. Aujourd’hui, le site est équipé d’une gestion d’un mode d’envoi des faire-parts différé, de modification des compositions après paiement et de prise en charge de codes promotionnels…
LOOK Cycle bénéficie désormais d’une nouvelle plateforme eCommerce disponible sur 70 pays et 5 langues. La base technique modulaire de Sylius permet de répondre aux exigences de LOOK Cycle en terme de catalogue, produits, tunnel d’achat, commandes, expéditions, gestion des clients et des expéditions.