Symfony2中的HTML表单标签而不是纯文本

时间:2011-09-26 07:18:43

标签: php symfony

我正在尝试实现这样的事情:

<div>
    <input type="checkbox" name="checkbox" id="checkbox_id" />
    <label for="checkbox_id">I agree to the <a href="/tos">Terms of Service</a></label>
</div>

我最接近实现这一点的是:

<div>
    {{ form_widget(form.agreeWithTos) }}
    <label for="{{ form.agreeWithTos.vars.id }}">I agree to the <a href="#">Terms of Service</a></label>
</div>

有更好的方法吗?必须指定{{form.agreeWithTos.vars.id}}是不优雅的。 :)

9 个答案:

答案 0 :(得分:11)

使用我的表单主题中的以下代码解决了这个问题:

{# ---- form-theme.html.twig #}
{% block checkbox_row %}
{% spaceless %}
<div>
    {{ form_errors(form) }}

    <label class="checkbox" for="{{ form.vars.id }}">
        {{ form_widget(form) }}
        {{ label|default(form_label(form)) | raw }}
    </label>
</div>
{% endspaceless %}
{% endblock %}

然后在表单模板中使用:

{% form_theme form '::form-theme.html.twig' %}

{{form_row(form.termsOfServiceAccepted, {
        'label' : 'I have read and agree to the <a href="#">Terms and conditions</a>'
    })
}}

这样,来自表单主题的块将应用于页面上的任何复选框。如果您还需要使用default-theme,则可以添加参数以启用特殊渲染:

{# ---- form-theme.html.twig #}
{% block checkbox_row %}
{% spaceless %}
    {% if not useTosStyle %}
        {{ parent() }}
    {% else %}
        {# ... special rendering ... #}
    {% endif %}
{% endspaceless %}
{% endblock %}

将像这样使用:

{% form_theme form '::form-theme.html.twig' %}

{{form_row(form.termsOfServiceAccepted, {
        'useTosStyle' : true,
        'label' : 'I have read and agree to the <a href="#">Terms and conditions</a>'
    })
}}

答案 1 :(得分:3)

我一直在打扰我,然后有一个尤里卡时刻。最简单的方法 - BY FAR - 是创建一个Twig扩展。

这是我的Twig代码:

{# twig example #}
{% block form_label %}
    {% set label = parent() %}
    {{ label|unescape|raw }}
{% endblock %}

和PHP:

<?php
new Twig_SimpleFilter('unescape', function($value) {
    return html_entity_decode($value);
});

一对夫妇注意到:

  • 这可以解除之前所有转义的代码。你必须在必要时重新逃脱。
  • 这需要您自己的自定义表单主题中的目标表单主题的extends标记,您可以在后续表单中使用该标记。将twig代码放在自定义表单主题中,并用这个替换对其他表单主题/主题的引用。

总的来说,这是我能够找到的最大和最好结果的最少代码行。它还具有超便携性和干燥性:您可以扩展任何表单主题,标签将更改,而无需更改其余代码。

答案 2 :(得分:2)

另一个非常简单的方法是直接在呈现表单的模板中覆盖表单主题。使用{% form_theme form _self %}就像这样简单:

{% form_theme form _self %}

{% block form_label %}
    {{ label | raw }}
{% endblock %}

{{ form_start(form) }}

请参阅文档中的相应部分:

https://symfony.com/doc/current/form/form_customization.html#method-1-inside-the-same-template-as-the-form

  

自定义[...]块的最简单方法是直接在实际呈现表单的模板中对其进行自定义。

     

通过使用特殊的{%form_theme form _self%}标记,Twig在同一模板中查找任何被覆盖的表单块。 [...]

     

此方法的缺点是,在其他模板中呈现其他表单时,无法重复使用自定义表单块。换句话说,在进行特定于应用程序中单个表单的表单自定义时,此方法最有用。如果要在应用程序中的多个(或所有)表单中重用表单自定义,请继续阅读下一部分。

答案 3 :(得分:1)

我认为您正在寻找form theming。这样你就可以在一个独立的文件中设置表单的每个部分的样式,无论如何你想要的,然后只用“优雅”的方式,用{{ form_row(form) }}逐行或用{{ form_widget(form) }}逐行渲染。这取决于你如何设置它。

答案 4 :(得分:1)

另一种方法是使用简单的Twig替换:

{% set formHtml %}
   {{ form(oForm) }}
{% endset %}

{{ formHtml|replace({'[link]': '<a href=" ... ">', '[/link]': '</a>'})|raw }}

在您的表单中,您需要执行以下操作:

$formBuilder->add('conditions', CheckboxType::class, [
        'label' => 'Yes, I agree with the [link]terms and conditions[/link].'
    ]
);

当然,您可以将[link]更改为其他任何内容。请注意,您不使用HTML标记;-)

答案 5 :(得分:1)

感谢contribution,您可以从 Symfony 5.1 开始使用label_html

{{ form_label(
    form.privacy,
    'I accept the <a href="' ~ path('privacy') ~ '">privacy terms</a>.', 
    {
        'label_html': true,
    },
) }}

答案 6 :(得分:0)

因此形成主题非常复杂。我发现的最简单的事情就是只删除字段标签(Symfony表单类中的.newInstance()),然后在twig html中添加html标签。

答案 7 :(得分:0)

您可以通过其他方式利用表单主题:您可以将form_label()标记移到<{strong>外面的<{1}}函数。

创建自定义表单主题,对于复选框,仅将<label>标记移到form_label函数之外:

{% block checkbox_row %}
    <label>{{ form_label(form) }}</label>
    {{ form_errors(form) }}
    {{ form_widget(form) }}
{% endblock checkbox_row %}

{% block checkbox_label %}
    {{ label }}
{% endblock checkbox_label %}

现在,在您的teplate中,覆盖复选框的label,从而有效地将HTML注入标签功能:

{% form_theme form 'yourtheme.html.twig' _self %}

{% block _your_TOS_checkbox_label %}
    I agree with <a href="#" target="_blank">terms and conditions</a>
{% endblock _your_TOS_checkbox_label %}

答案 8 :(得分:0)

Symfony 4.2

TWIG:

{% block main %} 
   .... 
   {% form_theme form _self %}
...
 {{ form_row(form.policy, {'label': 'security.newPassword.policy'|trans({"%policyLink%":policyLink, "%termsLink%":termsLink})}) }}
   ...
{% endblock %}

{% block checkbox_radio_label %}
    <label{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}>
        {{- widget|raw }} {{ label|unescape|raw }}
    </label>
{% endblock checkbox_radio_label %}

PHP:

use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;

class AppExtension extends AbstractExtension
{
    public function getFilters()
    {
        return [
            new TwigFilter('unescape', function ($value) {
                return html_entity_decode($value);
            }),
        ];
    }
}