Customizing Forms
Forms in Sylius are flexible and extendable, allowing you to modify them to better fit your business needs.
Why would you customize a Form?
You might need to customize a form in Sylius to: ✅ Add new fields – e.g., a secondary phone number for customers. ✅ Modify existing fields – change labels, make them required, or adjust their CSS classes. ✅ Remove fields – get rid of unnecessary form fields.
How to customize a Form?
Let’s say you want to customize the Customer Profile Form by:
Adding a
secondaryPhoneNumber
field.Removing the
gender
field.Changing the label for
lastName
fromsylius.form.customer.last_name
toapp.form.customer.surname
.
Ensure Your Model Supports New Fields
Before adding a new field, make sure it exists in the model. For example, secondaryPhoneNumber
must be added to the Customer entity and properly mapped in your database. To learn how to do that, check this part of the doc.
Create a Form Extension
To find the base class of the form you want to extend, run:
php bin/console debug:container | grep form.type.customer_profile
This will return:
sylius.form.type.customer_profile
Sylius\Bundle\CustomerBundle\Form\Type\CustomerProfileType
sylius_shop.form.type.customer_profile
Sylius\Bundle\ShopBundle\Form\Type\CustomerProfileType
Remember: Using the form type that has been returned from the service with sylius.
prefix will apply the extension to both forms!
We need to extend Sylius\Bundle\ShopBundle\Form\Type\CustomerProfileType
.
Create a new form extension class:
<?php
declare(strict_types=1);
namespace App\Form\Extension;
use Sylius\Bundle\ShopBundle\Form\Type\CustomerProfileType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
final class CustomerProfileTypeExtension extends AbstractTypeExtension
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
// Adding new fields works just like in the parent form type.
->add('secondaryPhoneNumber', TextType::class, [
'required' => false,
'label' => 'app.form.customer.secondary_phone_number',
])
// To remove a field from a form simply call ->remove(`fieldName`).
->remove('gender')
// You can change the label by adding again the same field with a changed `label` parameter.
->add('lastName', TextType::class, [
'label' => 'app.form.customer.surname',
]);
}
public static function getExtendedTypes(): iterable
{
return [CustomerProfileType::class];
}
}
If you add a new label, remember to define it in your translation files (translations/messages.en.yaml
).
Register the Form Extension
If autoconfiguration is disabled, register the extension in config/services.yaml
:
services:
app.form.extension.type.customer_profile:
class: App\Form\Extension\CustomerProfileTypeExtension
tags:
- { name: form.type_extension }
If autoconfiguration is enabled, no manual registration is needed.
You can check if the extension is correctly registered by running:
php bin/console debug:form "Sylius\Bundle\ShopBundle\Form\Type\CustomerProfileType"
Update the templates:
Make sure your form templates reflect the new changes:
Render the new fields you added.
Remove the old fields you removed.
Now you need to find the correct hook that is associated with the form you want to customize.
To do this, go to the page containing the form and use your browser's developer tools to inspect it. Look for the comments surrounding the form.
< — BEGIN HOOK | name: "sylius_shop.account.profile_update.update.content.main.form" — >
It means the hook we want to customize is:
sylius_shop.account.profile_update.update.content.main.form
Create an appropriate twig for the secondaryPhoneNumber
field:
// templates/account/profile_update/update/content/main/form/secondary_phone_number.html.twig
<div>{{ form_row(hookable_metadata.context.form.secondaryPhoneNumber) }}</div>
Update the form hook with your new field template:
// config/packages/twig_hooks.yaml
sylius_twig_hooks:
hooks:
'sylius_shop.account.profile_update.update.content.main.form':
secondary_phone_number:
template: 'account/profile_update/update/content/main/form/secondary_phone_number.html.twig'
priority: 600
To remove the old field from the template, just find and disable the hook responsible for it:
// config/packages/twig_hooks.yaml
sylius_twig_hooks:
hooks:
'sylius_shop.account.profile_update.update.content.main.form.additional_information':
gender:
enabled: false
Then your final result should look like:

Customizing Forms That Are Already Extended
Some forms in Sylius are already extended in the core system. Example:
ProductVariantType
is extended byProductVariantTypeExtension
inSylius/Bundle/CoreBundle/Form/Extension/
.
If you want to add another extension to an already extended form, define the priority:
services:
app.form.extension.type.product_variant:
class: App\Form\Extension\ProductVariantTypeMyExtension
tags:
- { name: form.type_extension, extended_type: Sylius\Bundle\ProductBundle\Form\Type\ProductVariantType, priority: -5 }
Extensions with higher priority values run first.
Handling Dynamically Added Form Fields
Some form fields in Sylius are added dynamically using event listeners.
For example, the ProductVariantTypeExtension in CoreBundle
adds channelPricings
dynamically:
<?php
// ...
final class ProductVariantTypeExtension extends AbstractTypeExtension
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
// ...
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$productVariant = $event->getData();
$event->getForm()->add('channelPricings', ChannelCollectionType::class, [
'entry_type' => ChannelPricingType::class,
'entry_options' => function (ChannelInterface $channel) use ($productVariant) {
return [
'channel' => $channel,
'product_variant' => $productVariant,
'required' => false,
];
},
'label' => 'sylius.form.variant.price',
]);
});
}
// ...
}
How to Remove Dynamically Added Fields
To modify or remove dynamically added fields, you need to listen for the same event and adjust the form accordingly:
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$event->getForm()->remove('channelPricings');
});
Good to know
✅ You can apply all these form customizations directly in your application or as part of a Sylius plugin. ✅ If you're customizing forms frequently, using extensions is recommended to avoid overriding entire forms.
With this guide, you should have a solid understanding of how to customize forms in Sylius to match your project’s needs! 🚀
Last updated
Was this helpful?