简体   繁体   English

Symfony2 自定义表单渲染器辅助函数

[英]Symfony2 custom form renderer helper function

I want to define a new twig function "form_field" which renders form_label , form_widget and form_errors .我想定义一个新的树枝函数“form_field”,它呈现form_labelform_widgetform_errors I don't want to override form_row because I already did that for a different purpose: form_row also wraps <div/> container required for my layout.我不想覆盖form_row因为我已经出于不同的目的这样做了: form_row还包装了我的布局所需的<div/>容器。 Specifically, I add bootstrap classes.具体来说,我添加了引导程序类。

Why do I need this?为什么我需要这个? Normally I use form_row but I have lots of form rows for which I want to place two ore more fields in the same line (eg "first name" and "last name").通常我使用form_row但我有很多表单行,我想在同一行中放置两个或更多字段(例如“名字”和“姓氏”)。 In those cases I define my wrapping <div/> manually, but I don't want to write the three function calls ( form_label , form_widget and form_errors ) everytime.在这些情况下,我手动定义了我的包装<div/> ,但我不想每次都编写三个函数调用( form_labelform_widgetform_errors )。

I tried to specify a custom function, but I get an exception when calling the twig functions there.我试图指定一个自定义函数,但在那里调用树枝函数时出现异常。 For this solution I need to know, how to call Twig functions from a custom function.对于这个解决方案,我需要知道如何从自定义函数调用 Twig 函数。

My second attempt was to adapt Symfony's solution for its own form helpers.我的第二次尝试是将 Symfony 的解决方案调整为它自己的表单助手。 I found this line in vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/FormExtension.php:我在 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/FormExtension.php 中找到了这一行:

new \Twig_SimpleFunction('form_widget', null, array('node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', 'is_safe' => array('html'))),

Looks like a function which actually just renders a block.看起来像一个实际上只是渲染一个块的函数。 When I adapted that line in my AppBundle, an exception was thrown in which Symfony claimed that a block named "form_field" is undefined.当我在 AppBundle 中修改该行时,抛出了一个异常,Symfony 声称名为“form_field”的块未定义。 However, I defined this block in my custom form template:但是,我在自定义表单模板中定义了这个块:

{% use 'bootstrap_3_horizontal_layout.html.twig' %}

{%- block form_field -%}
    {{- form_label(form) -}}
    {{- form_widget(form) -}}
    {{- form_errors(form) -}}
{%- endblock form_field -%}

Declare a twig template Form/form_field.html.twig:声明一个树枝模板 Form/form_field.html.twig:

{%- block form_field -%}
    {{- form_label(form, label) -}}
    {{- form_widget(form) -}}
    {{- form_errors(form) -}}
{%- endblock form_field -%}

Then I used the renderBlock method in my Twig custom function.然后我在我的 Twig 自定义函数中使用了renderBlock方法。 This is my twig extension file as described here :这是描述了我树枝扩展文件在这里

namespace AppBundle\Twig;

class AppExtension extends \Twig_Extension
{
    protected $environment;
    private $template;

    public function __construct(\Twig_Environment $env)
    {
        $this->environment = $env;
    }


    public function getFunctions()
    {
        return array(
            'form_field' => new \Twig_SimpleFunction('form_field', array($this, 'formField'), array(
                'is_safe' => array('html')
            ))
        );
    }

    public function formField($form, $label = null)
    {
        $this->template = $this->environment->loadTemplate( '::Form/form_field.html.twig' );

        return $this->template->renderBlock('form_field', array(
            'form' => $form,
            'label' => $label
        ));
    }

    /**
     * Returns the name of the extension.
     *
     * @return string The extension name
     */
    public function getName()
    {
        return 'app_extension';
    }
}

I configured the DI container to pass the Twig_Environment for the AppExtension service:我将 DI 容器配置为为 AppExtension 服务传递 Twig_Environment:

services:
    app.twig_extension:
        class: AppBundle\Twig\AppExtension
        arguments:
            - '@twig'
        tags:
            - { name: twig.extension }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM