@@ -1105,13 +1105,97 @@ define a **field configurator**, which is a class that updates the config of the
11051105field before rendering them.
11061106
11071107EasyAdmin defines lots of configurators for its built-in fields. You can create
1108- your own configurators too ( either to configure your own fields and/or the
1109- built-in fields). Field configurators are classes that implement
1110- ``EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldConfiguratorInterface ``.
1108+ your own configurators too, either to configure your own fields or to tweak the
1109+ built-in ones. A field configurator is a class that implements
1110+ ``EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldConfiguratorInterface ``::
11111111
1112- Once implemented, define a Symfony service for your configurator and tag it with
1113- the ``ea.field_configurator `` tag. Optionally you can define the ``priority ``
1114- attribute of the tag to run your configurator before or after the built-in ones.
1112+ interface FieldConfiguratorInterface
1113+ {
1114+ public function supports(FieldDto $field, EntityDto $entityDto): bool;
1115+ public function configure(FieldDto $field, EntityDto $entityDto, AdminContext $context): void;
1116+ }
1117+
1118+ ``supports() `` decides whether the configurator applies to a given field (for
1119+ example, by matching its FQCN or a custom option), and ``configure() `` mutates
1120+ the ``FieldDto `` to change any field option (template, value, form options, CSS
1121+ class, etc.). A configurator whose ``supports() `` method returns ``false `` is
1122+ silently skipped, so this is the first thing to check if your configurator does
1123+ not seem to do anything.
1124+
1125+ Here is a complete example that adds a CSS class on the index and detail
1126+ pages to every field flagged with a ``premium `` custom option::
1127+
1128+ namespace App\Admin\Configurator;
1129+
1130+ use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
1131+ use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
1132+ use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldConfiguratorInterface;
1133+ use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
1134+ use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto;
1135+
1136+ final class PremiumFieldConfigurator implements FieldConfiguratorInterface
1137+ {
1138+ public function supports(FieldDto $field, EntityDto $entityDto): bool
1139+ {
1140+ return true === $field->getCustomOption('premium');
1141+ }
1142+
1143+ public function configure(FieldDto $field, EntityDto $entityDto, AdminContext $context): void
1144+ {
1145+ if (!\in_array($context->getCrud()->getCurrentPage(), [Crud::PAGE_INDEX, Crud::PAGE_DETAIL], true)) {
1146+ return;
1147+ }
1148+
1149+ $existingCssClass = $field->getCssClass();
1150+ $field->setCssClass('' === $existingCssClass ? 'field-premium' : $existingCssClass.' field-premium');
1151+ }
1152+ }
1153+
1154+ The configurator only runs on fields that opt in via ``setCustomOption() `` in
1155+ your CRUD controller, so nothing else in the admin is affected::
1156+
1157+ use EasyCorp\Bundle\EasyAdminBundle\Field\MoneyField;
1158+
1159+ public function configureFields(string $pageName): iterable
1160+ {
1161+ return [
1162+ MoneyField::new('price')->setCustomOption('premium', true),
1163+ // ...
1164+ ];
1165+ }
1166+
1167+ Common alternatives for ``supports() `` are matching a field FQCN with
1168+ ``$field->getFieldFqcn() === YourField::class `` (useful when writing a
1169+ configurator for a :ref: `custom field <custom-fields >`) or matching a
1170+ property name with ``$field->getProperty() === 'propertyName' ``.
1171+
1172+ If your Symfony application uses the default services configuration (autowiring
1173+ and autoconfiguration enabled), the configurator is picked up automatically
1174+ thanks to the ``ea.field_configurator `` tag which EasyAdmin registers for any
1175+ service implementing ``FieldConfiguratorInterface ``. You don't need to tag the
1176+ service yourself.
1177+
1178+ If you disabled autoconfiguration, register the service manually:
1179+
1180+ .. code-block :: yaml
1181+
1182+ # config/services.yaml
1183+ services :
1184+ App\Admin\Configurator\PremiumFieldConfigurator :
1185+ tags :
1186+ - { name: ea.field_configurator }
1187+
1188+ The ``priority `` attribute of the tag controls when the configurator runs
1189+ relatively to the others. The built-in ``CommonPreConfigurator `` runs first
1190+ with priority ``9999 `` (it sets the default value, label, template, and virtual
1191+ flag of every field), and ``CommonPostConfigurator `` runs last with priority
1192+ ``-9999 `` (it formats the final value for display and applies the final
1193+ template). Your own configurator runs between them by default, alongside the
1194+ built-in per-type configurators. Use a custom priority if you need to override
1195+ a decision taken by another configurator::
1196+
1197+ tags:
1198+ - { name: ea.field_configurator, priority: -100 }
11151199
11161200.. _`PropertyAccess component` : https://symfony.com/doc/current/components/property_access.html
11171201.. _`PHP generators` : https://www.php.net/manual/en/language.generators.overview.php
0 commit comments