Php Symfony 2:将自定义变量传递给twig表单模板

Php Symfony 2:将自定义变量传递给twig表单模板,php,symfony,Php,Symfony,在刚刚开始的symfony中,我尝试使用表单模板系统做一些非常简单的事情(对我来说似乎很简单),但我找不到一种方法来做 我的目标是在提交按钮之外呈现一个“后退”按钮。我知道如何设置表单模板以及如何覆盖submit_小部件,但问题是:返回按钮URL必须在调用表单的模板处定义,因此我需要以某种方式将其作为变量传递给submit_小部件,我找不到方法来实现 理想情况下,其工作原理如下: 模板: {% form_theme form 'TutsAdminBundle:Form:bootstrap-hor

在刚刚开始的symfony中,我尝试使用表单模板系统做一些非常简单的事情(对我来说似乎很简单),但我找不到一种方法来做

我的目标是在提交按钮之外呈现一个“后退”按钮。我知道如何设置表单模板以及如何覆盖submit_小部件,但问题是:返回按钮URL必须在调用表单的模板处定义,因此我需要以某种方式将其作为变量传递给submit_小部件,我找不到方法来实现

理想情况下,其工作原理如下:

模板:

{% form_theme form 'TutsAdminBundle:Form:bootstrap-horizontal.html.twig' %}

{% block content %}
<h1>User creation</h1>

{{ form(form, { 'attr': {'role': 'form', 'class': 'form-horizontal'}, 'back': path('list_user') }) }}  
{% endblock %}
我让它扩展SubmitType,否则它会在表单行中呈现

服务.yml

tuts_admin.form.field.type.save_button:
    class: Tuts\AdminBundle\Form\Field\SaveButtonType
    arguments: ["@router"]
    tags:
        - {name: "form.type", alias: "save_button"}
2-然后我定义了它的模板(在我用来覆盖表单主题的同一个文件上)

{% block save_button_widget %}
    <div class="col-sm-6 col-sm-offset-1">
        <div class="pull-right marginL25">
            <button type="submit" class="btn btn-success">Save</button>
        </div>
        <div class="pull-right">
            <a href="{{ attr.href }}" class="btn btn-warning">Back</a>
        </div>
    </div>
{% endblock %}
比我想象的要复杂得多,但它确实有效


感谢Chausser提供的所有帮助。

我相信您不需要传递变量,只需要将变量提供给
Twig
,因为表单呈现(而不是扩展和包含其他模板)只是块呈现。也就是说,这些变量在同一范围内

因此:

父模板

表单模板:


希望这有帮助……

我相信您不需要传递变量,只需要将它提供给
Twig
,因为表单呈现(与扩展和包含其他模板相反)只是块呈现。也就是说,这些变量在同一范围内

因此:

父模板

表单模板:


希望这有帮助…

我个人会编写一个自定义字段类型,并为后退按钮设置if。它将接受路由名称和路由参数

//Acme/DemoBundle/Form/Type/BackButtonType
<?php
namespace Acme\DemoBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\OptionsResolver\Options;

class BackButtonType extends AbstractType
{
    protected $router;

    public function __construct($router)
    {
        $this->router = $router;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $attr = function(Options $options, $value){ 
            return array(
                'href'=>$this->_router->generate($options['route'], $options['params']),                
                'class'=>'btn btn-warning'
            ); 
        };

        $resolver
            ->setDefaults(array(
                'attr' => $attr,
                'mapped' => false
                'params' => array(),
            ))
            ->setRequired(array(
                'route',
            ))
            ->setNormalizers(array(
                'attr'=>$attr
            ));
    }

    public function getName()
    {
        return 'back_button';
    }

}
现在,您可以在普通表单中使用它。最后一步是创建细枝块以呈现此表单

//Acme/DemoBundle/Resources/Twig/fields.html.twig
{% block back_button_widget %}
    <a {{block('widget_attributes')}}>{{block('form_label')}}</a>
{% endblock %}
完成此操作后,您需要清除缓存:

php app/console cache:clear --env=dev
php app/console cache:clear --env=prod
现在如何使用这个:

//In your Form
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
       // Add other fields
       ->add('back', 'back_button',array('route'=>'my_custom_route_name','params'=>array('user_id'=>$this->getUser()->getUserId())))
       ->add('submit','submit',array('attr'=>array('class'=>'btn btn-primary')));
}

这应该行得通。还没有完全测试过,但如果您有任何问题,请告诉我。

我个人会编写一个自定义字段类型,并为返回按钮设置if。它将接受路由名称和路由参数

//Acme/DemoBundle/Form/Type/BackButtonType
<?php
namespace Acme\DemoBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\OptionsResolver\Options;

class BackButtonType extends AbstractType
{
    protected $router;

    public function __construct($router)
    {
        $this->router = $router;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $attr = function(Options $options, $value){ 
            return array(
                'href'=>$this->_router->generate($options['route'], $options['params']),                
                'class'=>'btn btn-warning'
            ); 
        };

        $resolver
            ->setDefaults(array(
                'attr' => $attr,
                'mapped' => false
                'params' => array(),
            ))
            ->setRequired(array(
                'route',
            ))
            ->setNormalizers(array(
                'attr'=>$attr
            ));
    }

    public function getName()
    {
        return 'back_button';
    }

}
现在,您可以在普通表单中使用它。最后一步是创建细枝块以呈现此表单

//Acme/DemoBundle/Resources/Twig/fields.html.twig
{% block back_button_widget %}
    <a {{block('widget_attributes')}}>{{block('form_label')}}</a>
{% endblock %}
完成此操作后,您需要清除缓存:

php app/console cache:clear --env=dev
php app/console cache:clear --env=prod
现在如何使用这个:

//In your Form
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
       // Add other fields
       ->add('back', 'back_button',array('route'=>'my_custom_route_name','params'=>array('user_id'=>$this->getUser()->getUserId())))
       ->add('submit','submit',array('attr'=>array('class'=>'btn btn-primary')));
}

这应该行得通。还没有完全测试过,但如果您有任何问题,请告诉我。

谢谢,但它不起作用,“back”在表单模板上总是空的。很抱歉。我在发布之前无法实际尝试该解决方案。请您尝试一下
\u self.back
?谢谢,但它不起作用,“back”表单模板上总是空的很抱歉。在发布之前,我无法实际尝试该解决方案。请尝试
\u self.back
?谢谢。我现在正在尝试这种方法,但我遇到了以下错误:“路由”选项不存在。已知选项有:“操作”、“属性”…在任何情况下,如果我设法使此自定义字段类型正常工作,如何像我计划的那样,使用表单模板将其呈现在“提交”按钮旁边?这可能是因为在setDefaultOptions中,我将所需字段作为router not route。我已在代码示例中对其进行了更新。至于呈现s旁边的“后退”按钮ubmit按钮您应该能够修改submit按钮小枝块,只需使用css浮动将它们放在同一行上。将它们都放在一个表单组下是另一个怪兽。现在我得到“ContextErrorException:可捕获致命错误:类闭包的对象无法转换为字符串”在呈现模板时谢谢。我现在正在尝试这种方法,但是我得到了一个错误:“路由”选项不存在。已知选项有:“操作”、“属性”…在任何情况下,如果我设法使此自定义字段类型正常工作,如何像我计划的那样,使用表单模板将其呈现在“提交”按钮旁边?这可能是因为在setDefaultOptions中,我将所需字段作为router not route。我已在代码示例中对其进行了更新。至于呈现s旁边的“后退”按钮ubmit按钮您应该能够修改submit按钮小枝块,只需使用css浮动将它们放在同一行上。将它们都放在一个表单组下是另一个怪兽。现在我得到“ContextErrorException:可捕获致命错误:类闭包的对象无法转换为字符串”在呈现模板时,我可能有点晚了,但是您是否尝试过
public function buildView(FormView$view,FormInterface$form,array$options){$view->vars['back']=$options['back'];}
。我刚才遇到了确切的问题,并设法以这种方式解决了它。我可能有点晚了,但您是否尝试过
公共函数构建视图(FormView$view,FormInterface$form,array$options){$view->vars['back']=$options['back'];}
。我刚才遇到了确切的问题,并设法以这种方式解决了它。
//Acme/DemoBundle/Resources/Twig/fields.html.twig
{% block back_button_widget %}
    <a {{block('widget_attributes')}}>{{block('form_label')}}</a>
{% endblock %}
//app/config/config.yml
twig:
    debug:            %kernel.debug%
    strict_variables: %kernel.debug%
    form:
        resources:
            - 'AcmeDemoBunlde:Twig:fields.html.twig'
php app/console cache:clear --env=dev
php app/console cache:clear --env=prod
//In your Form
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
       // Add other fields
       ->add('back', 'back_button',array('route'=>'my_custom_route_name','params'=>array('user_id'=>$this->getUser()->getUserId())))
       ->add('submit','submit',array('attr'=>array('class'=>'btn btn-primary')));
}