我可以将 html 放入带有 Twig 的 Symfony 表单按钮中吗? [英] Can I put html inside a Symfony form button with Twig?

查看:26
本文介绍了我可以将 html 放入带有 Twig 的 Symfony 表单按钮中吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 html 放入带有树枝的表单按钮中,例如:

I'm trying to put html inside a form button with twig like:

{{ form_widget(form.jiraStatus, {
        'label': '<i class="fa fa-bug"></i>Bug',
        'attr':{'class': 'btn btn-large btn-default btn-block' }
}) }}

但是这样做,渲染的按钮显示如下:

But doing this, the rendeded button shows like this:

<button type="submit" name="SolveTask[taskTypesFormObj][bugStatus]"
    class="btn btn-large btn-default btn-block">
    &lt;i class=&quot;fa fa-bug&quot;&gt;&lt;/i&gt;Bug
</button>

如您所见,按钮内的 html 已编码.我尝试使用原始过滤器,但效果是一样的.有没有办法做到这一点?

As you can see, the html inside the button is encoded. I tried to use the raw filter, but the effect is the same. There is a way to do this?

谢谢!

推荐答案

可以,但您必须自定义 您的表单主题.

Yes, but you'll have to customise your form theme.

注意:此答案已被编辑以与 Symfony 2.8 3.x 和 4.x 兼容.对于旧版本,请查看编辑历史.

Note: This answer has been edited to be compatible with Symfony 2.8 3.x and 4.x. For older versions, please see the edit history.

在按钮中支持图标的一个好方法是使用表单扩展.首先创建一个表单扩展类,它定义了一个可以在表单中使用的新属性icon:

A nice way to support icons in buttons is using form extensions. First create a form extension class that defines a new property icon that you can use in your forms:

<?php

namespace Foo\BarBundle\Form\Extension;

use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\OptionsResolver\OptionsResolver;

class ButtonTypeIconExtension extends AbstractTypeExtension
{
    /**
     * @param FormBuilderInterface $builder
     * @param array                $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->setAttribute('icon', $options['icon']);
    }

    /**
     * @param FormView      $view
     * @param FormInterface $form
     * @param array         $options
     */
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $view->vars['icon'] = $options['icon'];
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(['icon' => null]);
        $resolver->setDefined(['icon']);
    }

    /**
     * Returns the name of the type being extended.
     *
     * @return string The name of the type being extended
     */
    public function getExtendedType()
    {
        return ButtonType::class; // Extend the button field type
    }
}

在您的 services.yml(或 xml 文件)中注册此扩展.别名必须与上述 getExtendedType() 方法返回的字符串相对应.

Register this extension in your services.yml (or xml file). The alias must correspond with the string returned by the above getExtendedType() method.

# Form extension for adding icons
foobar.form_extension.icon:
    class: Foo\BarBundle\Form\Extension\ButtonTypeIconExtension
    tags:
        - { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\ButtonType }

接下来,覆盖您的form_div_layout.html.twig.(请参阅上面的链接)您现在可以使用 icon 作为这些主题中的变量.对于按钮,我们覆盖 button_widget 块:

Next, override your form_div_layout.html.twig. (See link above) You can now use icon as a variable in these themes. For buttons we override the button_widget block:

{% block button_widget -%}
    {% set attr = attr|merge({class: (attr.class|default('') ~ ' btn')|trim}) %}
    {% if label is empty -%}
        {%- if label_format is not empty -%}
            {% set label = label_format|replace({
                '%name%': name,
                '%id%': id,
            }) %}
        {%- else -%}
            {% set label = name|humanize %}
        {%- endif -%}
    {%- endif -%}
    {% if icon|default %}
        {% set iconHtml = '<i class="fa ' ~ icon ~ '"></i> ' %}
    {% else %}
        {% set iconHtml = '' %}
    {% endif %}
    <button type="{{ type|default('button') }}" {{ block('button_attributes') }}>{{ iconHtml|raw }}{{ label|trans({}, translation_domain) }}</button>
{%- endblock button_widget %}

最后,您可以在模板中使用图标选项:

Finally, you can use the icon option in your template:

{{ form_widget(form.jiraStatus, {
    'icon': 'fa-bug',
    'label': 'Bug',
    'attr':{'class': 'btn btn-large btn-default btn-block' }
}) }}

或者在你的表单类中:

    $builder
        ->add('jiraStatus', SubmitType::class, [
                'label' => 'Bug',
                'icon' => 'fa-bug',
                'attr' => [
                    'class' => 'btn btn-large btn-default btn-block',
                ],
            ]
        );

注意:通常最好在模板中添加图标,因为图标是展示的问题,而您的表单类应该真正与业务逻辑有关.

Note: Is is generally better to add the icon in the template since icons are a matter of presentation, and your form classes should really be about buisness logic.

让它更通用:

通过在 getExtendedType() 中返回 ButtonType 的 FQCN,我们告诉 Symfony 我们正在扩展从 ButtonType 继承的所有可能的表单元素,例如 SubmitType.不幸的是,我们无法使用任何类型来定位所有可能的表单元素,但我们可以添加一个额外的扩展来定位 FormType.所有表单字段(如输入框和选择元素)都继承自此类型.因此,如果您希望它同时使用表单域 按钮,我建议如下:

By returning the FQCN of ButtonType in getExtendedType() we tell Symfony that we are extending all possible form elements that inherit from ButtonType such as SubmitType. Unfortunately there is no type we can use to target all possible form elements but we can add an extra extension that targets FormType. All form fields like input boxes and select elements inherit from this type. So if you want it to work with both form fields and buttons, I suggest the following:

创建一个抽象类abstract class AbstractIconExtension extends AbstractTypeExtension,内容与上面完全相同,但省略了getExtendedType 方法.然后创建两个从此类扩展的类(例如 FieldTypeIconExtensionButtonTypeIconExtension),它们只包含 getExtendedType 方法.一个返回FormType的FQCN,另一个返回ButtonType的FQCN:

Create an abstract class abstract class AbstractIconExtension extends AbstractTypeExtension with exactly the same content as above but leave out the getExtendedType method. Then create two classes that extend from this class (e.g. FieldTypeIconExtension and ButtonTypeIconExtension) which only contain the getExtendedType method. One returning the FQCN of FormType and the other returning the FQCN of ButtonType:

Foo/BarBundle/Form/Extension/ButtonTypeIconExtension.php:

<?php

namespace Foo\BarBundle\Form\Extension;

use Symfony\Component\Form\Extension\Core\Type\ButtonType;

class ButtonTypeIconExtension extends AbstractIconExtension
{
    /**
     * Returns the name of the type being extended.
     *
     * @return string The name of the type being extended
     */
    public function getExtendedType()
    {
        return ButtonType::class;  // extend all buttons
    }
}

Foo/BarBundle/Form/Extension/FieldTypeIconExtension.php:

<?php

namespace Foo\BarBundle\Form\Extension;

use Symfony\Component\Form\Extension\Core\Type\FormType;

class FieldTypeIconExtension extends AbstractIconExtension
{
    /**
     * Returns the name of the type being extended.
     *
     * @return string The name of the type being extended
     */
    public function getExtendedType()
    {
        return FormType::class;  // extend all field types
    }
}

使用相应的别名在您的服务中注册这两个类:

Register these two classes in you services using the corresponding alias:

# Form extensions for adding icons to form elements
foobar.form_extension.button_icon:
    class: Foo\BarBundle\Form\Extension\ButtonTypeIconExtension
    tags:
        - { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\ButtonType }
foobar.form_extension.form_icon:
    class: Foo\BarBundle\Form\Extension\FieldTypeIconExtension
    tags:
        - { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType }

现在您也可以在表单主题的其他位置使用 icon 变量.例如,要将图标添加到标签,您可以覆盖 form_label 块:

Now you can use the icon variable in other places in your form themes as well. For instance, to add icons to labels you can override the form_label block:

{% block form_label -%}
    {% if label is not sameas(false) -%}
        {% if not compound -%}
            {% set label_attr = label_attr|merge({'for': id}) %}
        {%- endif %}
        {% if required -%}
            {% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
        {%- endif %}
        {% if label is empty -%}
            {%- if label_format is not empty -%}
                {% set label = label_format|replace({
                    '%name%': name,
                    '%id%': id,
                }) %}
            {%- else -%}
                {% set label = name|humanize %}
            {%- endif -%}
        {%- endif -%}
        {% if icon|default %}
            {% set iconHtml = '<i class="fa ' ~ icon ~ '"></i> ' %}
        {% else %}
            {% set iconHtml = '' %}
        {% endif %}
        <label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ iconHtml|raw }}{{ label|trans({}, translation_domain) }}</label>
    {%- endif %}
{%- endblock form_label %} 

然后在表单类中的该字段的标签上添加一个图标:

And then add an icon to the label of that field in your form class:

$builder
    ->add('mytextfield', TextType::class, [
            'label' => 'My fancy text field',
            'icon' => 'fa-thumbs-o-up'
        ]
    );

这篇关于我可以将 html 放入带有 Twig 的 Symfony 表单按钮中吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆