Symfony form theme avoid block output and use custom variables in block

772 views Asked by At

A. I want to render a form and use a form theme. But the block I created is outputted directly before my doctype the hidden input field is created. But I only want that its render in the form(form) function.

B. Also I can't use the {{ template }} variable inside the block or other variables created outside the block? Template variable is created by the controller.

{# FORM THEME #}
{% form_theme form _self %}
{% block _my_form_example__token_widget %}
    {% set type = type|default('hidden') %}
    <input data-test="is-this-render" type="{{ type }}" {{ block('widget_attributes') }} value="{{ 
    render_esi(
            controller(
                    'MyController:Form:token',
                    { 'form': template }  {# template variable can't be accessed here?? #}
             )
     ) }}" />
{% endblock %}

<!doctype html>
<html>
<head>
    <title>Basic Form</title>
</head>
<body>
    <h1>Basic Form {{ template }}</h1>{# This output works #}
    {{ form(form) }}
</body>
</html>

This output the following:

<input data-is-rendered="test" type="hidden"  value="...." /> <!-- this should not be here -->
<!doctype html>
<html>
    <head>
    <title>Basic Form</title>
</head>
<body>
    <h1>Basic Form template_variable_content</h1><!-- {{ template }} works here -->

    <form ....>
    <!-- ... --->
    <input data-is-rendered="test" type="hidden"  value="...." /> <!-- Render Correct when no template variable is used -->
    <!-- ... --->
    </form>
</body>
</html>
1

There are 1 answers

2
Reid Johnson On BEST ANSWER

I think you have misunderstood the use of blocks in Twig. When a template uses extends to extend another template, you can use the block tag to define areas that will replace certain named areas in the parent template.

Because you're template does not extend another template, your use of the block tag simply tells Twig that you would like child templates to be able to replace that portion of your template by defining a block named "_my_form_example__token_widget".

In the Symfony documentation for form theming, you will notice that they begin the example with the all important extends tag.

{% extends 'base.html.twig' %}

{% form_theme form _self %}

{% block integer_widget %}
    <div class="integer_widget">
        {% set type = type|default('number') %}
        {{ block('form_widget_simple') }}
    </div>
{% endblock %}

{% block content %}
    {# ... render the form #}

    {{ form_row(form.age) }}
{% endblock %}

Even though the base template that their example file is extending has nothing to do with the form themes, just the fact that it is a child template switches the block tags from defining areas to be replaced and makes them define areas that can be used to replace. Simply making your template extend a base should solve all of your described problems with using this block.

I would really suggest, though, that you use the described method for creating an external file to hold your theme, though, so that you can more easily keep your forms consistent across pages and keep all your form theming stuff in a central location where you, and anyone else who might work on your code, will be able to find it later.