刚刚开始使用symfony,我正在尝试使用表单模板系统做一些非常简单的事情(对我而言似乎很简单),但我找不到办法。
我的目标是渲染一个"返回"按钮除了提交按钮。我知道如何设置表单模板以及如何覆盖submit_widget,但问题是:必须在调用表单的模板上定义后退按钮URL,所以我需要以某种方式将此作为变量传递给submit_widget,我无法找到办法。
理想情况下,它会像这样工作:
模板:
{% 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 %}
然后,在表单模板
{% block submit_widget %}
<div class="col-sm-6 col-sm-offset-1">
<div class="pull-right">
<a class="btn btn-warning" href="{{ back }}"> Back</a>
<button type="submit" class="btn btn-success">Save</button>
</div>
</div>
{% endblock submit_widget %}
但是我无法找到一种方法来访问我的&#34;返回&#34; submit_widget块内的变量。
我怎样才能做到这一点?
更新
我设法做了我想要的事情:
1-按照Chausser的建议创建一个自定义字段:
class SaveButtonType extends SubmitType
{
public function __construct($router)
{
$this->_router = $router;
}//constructor
protected $_router;
/* (non-PHPdoc)
* @see \Symfony\Component\Form\AbstractType::buildForm()
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
}//buildForm
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$href = function(Options $options, $value){
return array('href'=>$this->_router->generate($options['route'], $options['params']), 'class'=>'btm btn-warning');
};
$resolver->setDefaults(array('mapped'=>false))->setRequired(array('route', 'params'));
$resolver->setNormalizers(array('attr'=>$href));
}//setDefaultOptions
public function getName()
{
return 'save_button';
}//getName
}//SaveButtonType
我已经使它扩展了SubmitType,否则它将在form_row中呈现。
services.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 %}
此类型立即呈现提交和后退按钮。
3-最后,由于我找不到阻止渲染另一个提交按钮的方法,我覆盖了submit_widget:
{% block submit_widget %}
{% endblock submit_widget %}
比我预期的要复杂得多,但确实有效。
感谢Chausser的所有帮助。
答案 0 :(得分:3)
我个人会写一个自定义字段类型,并为后退按钮创建。接受路线名称和路线参数的东西。
//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';
}
}
然后您需要将其注册为新的表单类型:
parameters:
acme_demo.form.type.back_button.class: Acme\DemoBundle\Form\Type\BackButtonType
services:
acme_demo.form.type.back_button:
class: %acme_demo.form.type.back_button.class%
arguments: ["@router"]
tags:
- { name: "form.type", alias: "back_button" }
现在您可以在正常形式中使用它。最后一步是创建树枝块以渲染此表单。
//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')));
}
这应该有效。尚未经过全面测试,但如果您有任何问题请告诉我。
答案 1 :(得分:1)
我相信你不需要传递变量,但只能使它(已知)到Twig
,因为表单渲染(而不是扩展和包含其他模板)只是块渲染。也就是说,这些变量属于同一范围。
所以:
父模板
{% set back = "MyFooValue" %}
表单模板:
<div class="{{ back }}">Some content</div>
另外,我喜欢将default
定义为后备,以防我忘记(或根本不)定义变量:
<div class="{{ back|default("") }}">Some content</div>
希望这会有所帮助......