New in Symfony 4.3: Simpler Form Theming
January 4, 2019
•
Published by
Javier Eguiluz
Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
Contributed by
Yonel Ceruto
in #29680.
Consider a Symfony application that contains a custom form field for a color picker that requires some JavaScript code to work. Although Symfony provides multiple options to customize how forms are rendered, the current best solution for simple use cases like this is not simple enough.
In order to make the form field truly reusable, its block name in the form theme
must be immutable. However, by default Symfony prefixes the block name with the
parent block prefix (e.g. _product_color_widget
, _user_color_widget
,
etc. instead of color_widget
)
The solution to this problem is simple but cumbersome:
Step 1. Create a new form type for the custom color widget (the class is almost empty because in this case there's no need to define any option or add any logic):
1 2 3 4 5 6 7
class ColorPickerType extends AbstractType
{
public function getParent(): string
{
return TextType::class;
}
}
Step 2. Update your forms to use this custom form type:
1 2
// ...
$builder->add('color', ColorPickerType::class);
The block_prefixes
option generated by Symfony for this type will be
form
, text
, color_picker
and _<parent_form_name>_color
. Thanks
to the unchanging color_picker
prefix, you can now define a custom template
for all the color pickers of the app using the same block name.
Step 3. Use the block prefix to customize the form field:
1 2 3 4 5
{# templates/form/fields.html.twig #}
{% block color_picker_widget %}
{{ form_widget(form, {'attr': {'v-model': 'color', '@focus': 'open'}}) }}
{# ... more custom code here ... #}
{% endblock %}
In Symfony 4.3 all this still works, but we've streamlined this use case. Thanks
to the new block_prefix
option, you can add any custom prefix to the list
of prefixes generated by Symfony for each form field.
Following the same example as above, there's no need to create the
ColorPickerType
class. You just need to follow these steps:
Step 1. Define a custom block prefix for the color form field:
1 2
// ...
$builder->add('color', null, ['block_prefix' => 'color_picker']);
Step 2. Use that custom block prefix in the form theme template:
1 2 3 4
{# templates/form/fields.html.twig #}
{% block color_picker_widget %}
{# ... #}
{% endblock %}
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
I waited for it:)
{{ block('entry_row') }}
{% endblock %}
{% block _domain_servers_entry_row %}
{{ block('entry_row') }}
{% endblock %}
Yay - away with this :D