我正在尝试实现这样的事情:
<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}}是不优雅的。 :)
答案 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) }}
请参阅文档中的相应部分:
自定义[...]块的最简单方法是直接在实际呈现表单的模板中对其进行自定义。
通过使用特殊的{%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);
}),
];
}
}