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 %}
superb! I waited for it:)
Really great addition, the block prefixes aren't always easy to determine, can't wait to test this feature.
{% block _server_logins_entry_row %} {{ block('entry_row') }} {% endblock %}
{% block _domain_servers_entry_row %} {{ block('entry_row') }} {% endblock %}
Yay - away with this :D