Skip to content

[Form] Revamp the docs about form theming and customization#21785

Open
javiereguiluz wants to merge 6 commits intosymfony:6.4from
javiereguiluz:forms_4
Open

[Form] Revamp the docs about form theming and customization#21785
javiereguiluz wants to merge 6 commits intosymfony:6.4from
javiereguiluz:forms_4

Conversation

@javiereguiluz
Copy link
Copy Markdown
Member

This is part of the ongoing effort to revamp Form docs (see #21784).

This PR updates everything aobut themes, theming, rendering and customization.

As usual, git diff is useless because the new docs change everything compared to the old docs.


If you're rendering each field manually, make sure you don't forget the
``_token`` field that is automatically added for CSRF protection.
When rendering fields manually, always include ``{{ form_rest(form) }}``
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This not should be in the section Rendering Forms instead of Rendering Individual Field Parts. It is not about the individual parts of fields.


Functions
~~~~~~~~~
Twig Form Functions
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the field_* functions also need to be added to this function reference, so that all functions are documented. This will help solve twigphp/Twig#4753.

Note that we will need to have stable references for all of them (as done for existing ones) to allow the Twig documentation to link to them.

{# render a field row, but display a label with text "foo" #}
{{ form_row(form.name, {'label': 'foo'}) }}

The second argument to ``form_row()`` is an array of variables. The templates
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loosing the documentation for the second argument means that those sections don't document the signature fully.

As the Symfony reference of Twig function delegates all form functions to this page, this makes the reference incomplete. Either the form page needs to keep a complete reference documentation for Twig functions, or they need to be covered in the dedicated reference documentation.

``date``, etc) and the ``part`` corresponds to *what* is being rendered (e.g.
``label``, ``widget``, etc.)
Not sure what the block name should be? Inspect the rendered HTML. The field's
``id`` attribute (e.g., ``user_email``) gives you the form and field names.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Easier solution: check the Form panel in the web profiler. It lists all block prefixes that are used in the lookup of a block as part of the display of the variables.

use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
Sometimes you need different rendering for the same field type in different
contexts. Use the ``block_prefix`` option to skip the default block naming rules
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this does not actually skip the default naming rule. It adds one more prefix in the list (if your form theme does not define styles for that block prefix, it might still end up using the default one)

.. configuration-block::

.. code-block:: yaml
Creating a Theme in the Same Template
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section should have a warning to document the fact that this relies on the fact that you can have blocks in a child templates that are not rendered during the rendering of a template (when they don't override blocks of the parent). However, if your template does not extend another template (common when using reusable partials), you cannot create a form theme in the same template, as any block you create would be placed in a location that is actually rendered (which will likely break due to not having the expected variables, and won't produce the expected result in any case, even if you are lucky with the context)


.. code-block:: twig
{% form_theme form _self %}
{% use 'form_div_layout.html.twig' with text_widget as base_text_widget %}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simpler than using block renaming: use parent() without renaming the parent block.


{% block form_errors %}
{% if errors|length > 0 %}
{% if compound %}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is confusing. The root form is not the only compound form. Those are different concepts.

.. _`foundation_6_layout.html.twig`: https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Twig/Resources/views/Form/foundation_6_layout.html.twig
{% endblock %}

The ``compound`` variable distinguishes between form-level errors (the entire
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not true. A compound form is a form that can have children. The root form is always a compound form (otherwise, it would be impossible to add a child for the CSRF token), but other forms can be compound as well (non exhaustive list):

  • CollectionType
  • ChoiceType (and all its children) in expanded mode
  • DateTimeType, DateType and TimeType for any widget other than single_text
  • all cases of editing a nested object

$twig->formThemes([
'form/my_theme.html.twig',
]);
**Reusing built-in blocks in same-template themes:**
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This document of custom form themes is missing another feature: reusing the theme rendering for the parent type (to be exact, the previous block prefix in the list of block prefixes that are candidates during the block selection, which takes block_name and block_prefix into account in addition to the type hierarchy).

If you call form_*(form) inside the _* block of the form theme (with the current form as argument, not a child, and with the same *, not a different field part), the theme renderer will resolve blocks using the next candidates in the list. that's the way to call the rendering of the parent type (without having to hardcode what block is providing this rendering in the form theme)

@javiereguiluz
Copy link
Copy Markdown
Member Author

Christophe, thanks a lot for your amazing review 😍 I did all the recommended changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants