我看到这是一个较旧的线程,但我想提供一个替代解决方案,以防其他人发现它有用。我对这个主题的其他答案不满意,因为我想做三件事:
- 不必在每个视图模板中进行任何自定义表单渲染(我喜欢使用
{{ form(form) }}
)
- 让取消按钮出现在提交按钮旁边(令人惊讶的是,如果你不进行自定义渲染,symfony 默认将所有表单按钮包装在一个 div 标签中)
- 能够将取消操作设置为控制器中的一个选项,因为链接会根据我是添加还是编辑等而有所不同
我想在应用 DRY 原则的同时完成这一切。首先,我扩展了基本表单类型以允许自定义选项“cancel_action”:
<?php
namespace AcmeBundle\Form\Extension;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
class FormTypeExtension extends AbstractTypeExtension
{
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);
$resolver->setDefined('cancel_action');
$resolver->setAllowedTypes('cancel_action', 'string');
}
/**
* {@inheritdoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
parent::buildView($view, $form, $options);
if (isset($options['cancel_action'])) {
$view->vars['cancel_action'] = $options['cancel_action'];
}
}
/**
* {@inheritdoc}
*/
public function getExtendedType()
{
return 'form';
}
}
并在我的配置中注册了该表单类型扩展名(使用别名“form”,以便它可用于我的所有表单):
acme.form_type_extension:
class: AcmeBundle\Form\Extension\FormTypeExtension
tags:
- {name: form.type_extension, alias: form}
然后我使用表单主题来扩展基本表单视图(我扩展了 submit_widget 块,以便取消按钮位于 div 标签内的提交按钮旁边):
{# AcmeBundle:Form:fields.html.twig #}
{% extends 'form_div_layout.html.twig' %}
{%- block submit_widget -%}
{%- set type = type|default('submit') -%}
{{ block('button_widget') }}
{% if form.parent.vars.cancel_action is defined %}
<a class="btn btn-default" href="{{ form.parent.vars.cancel_action }}" role="button">Cancel</a>
{% endif %}
{%- endblock submit_widget -%}
并在我的 twig 配置中注册了该表单主题,以便它默认应用于所有表单视图:
twig:
form_themes:
- 'AcmeBundle:Form:fields.html.twig'
瞧!现在对于每个表单,如果我想要一个取消按钮,我需要做的就是在控制器中初始化表单时将取消操作指定为一个选项:
$form = $this->createForm(new AlbumType(), $album, array(
'cancel_action' => $this->generateUrl('album_home')
));