yiisoft / yii2-twig

Yii 2 Twig extension.
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
136 stars 61 forks source link

Form rendering incorrect with yii2-twig 2.5.0 / twig 3.9 #158

Open lunetics opened 3 weeks ago

lunetics commented 3 weeks ago

What steps will reproduce the problem?

Update yii2-twig to v2.5.0 (support for twig 3.9 -> see https://github.com/yiisoft/yii2-twig/pull/154 )

What's expected?

Forms are rendered correctly

What do you get instead?

The form is rendered, but after the fields. e.g. instead of

<form>
<input foo... />
<input bar... />
</form>

it renders:

<input foo.../>
<input bar... />
<form></form

following twig form code is used:

{% set form = active_form_begin({'action':path(['/account/register'])}) %}
{{ form.field(customer,'email').validator('email').emailInput() | raw }}
{{ form.field(customer,'newpassword').validator('^.{8,}$').label('signup.form.password.label'|i18n).passwordInput({'autocomplete':'new-password'}) | raw }}
{{ active_form_end() }}

I'm not proficient in yii2, but from what I discovered, it happends in yii\widgets\ActiveForm::run() method. https://github.com/yiisoft/yii2/blob/52e4a3e645eaece47c3f9dddac7c1771a5bd7804/framework/widgets/ActiveForm.php#L225

        $content = ob_get_clean();
        $html = Html::beginForm($this->action, $this->method, $this->options);
        $html .= $content;

        if ($this->enableClientScript) {
            $this->registerClientScript();
        }

        $html .= Html::endForm();

The $content is empty (I assume because of the ob_get_clean() behaviour in twig 3.9? resulting in returned $html string: <form id="customer-signup-form" action="/account/register" method="post" data-form></form>

Since I'm new into this yii2 project, I have limited knowledge of the inner workings

Additional info

Q A
Yii version 2.0.50
Yii Twig version 2.5.0
Twig version 3.10
PHP version 8.1
Operating system Linux
samdark commented 3 weeks ago

@diffy0712 can you look into it?

diffy0712 commented 3 weeks ago

Hello,

I had a quick look and unfortunately this test was not covering this case and did not fail on the latest fix for twig3.9 support. This for sure needs to be handled. I think I can add another test, which would fail on the same error.

The problem is indeed the 'ob_get_clean' call again, which in case of the 'end_page' could be moved outside of twig's render (the previous fix for the twig3.9 support pr), but in this case it cannot be done as the form can be anywhere in the content. I figured that any 'Widget' which relies on the ob to have the content to override will fail similarly.

I try to come up with a solution for this one and keep you guys updated.

Until then, you can fix the package version to 2.4.3, which will prevent the 'unsupported twig version' from installing and was merged in this pr. composer require "yiisoft/yii2-twig:2.4.3"

schmunk42 commented 3 weeks ago

I think I can add another test, which would fail on the same error.

That would be great as a first step.

lunetics commented 3 weeks ago

Thanks for looking into it. I'm currently debugging another case, will do a seperate ticket for that.