在某些情况下,你个性化的片段可能会丢失。比如,在Symfony提供的默认主题中没有提供textarea_errors片段。那么如何来渲染一个textarea字段的错误信息呢?
答案是通过field_errors片段。当Symfony渲染一个textarea类型的错误时,它首先查找一个textarea_errors片段,如果没有找到则会回到field_errors片段。
每个field类型有一个parenttype(textarea的父类型为field),Symfony如果没有发现本身的片段,就会转而使用父类片段。
所以,要重写textarea字段的errors,拷贝field_errors片段,重命名为textarea_errors并个性化它们。为所有字段重写默认的error渲染,则需要直接拷贝和个性化field_errors片段。
全局表单主题
在上面的示例中,我们使用了form_theme helper来导入自定义个的表单片段到表单。你也可以告诉Symfony在全项目中导入自定义的form。
Twig
为了从所有之前创建的fileds.html.twig模板中自动包含个性化的block,修改你的应用程序配置文件:
YAML格式:
# app/config/config.yml twig: form: resources: - 'AcmeTaskBundle:Form:fields.html.twig' # ...
XML格式:
<!-- app/config/config.xml --> <twig:config ...> <twig:form> <resource>AcmeTaskBundle:Form:fields.html.twig</resource> </twig:form> <!-- ... --> </twig:config>
PHP代码格式:
// app/config/config.php $container->loadFromExtension('twig', array( 'form' => array('resources' => array( 'AcmeTaskBundle:Form:fields.html.twig', )) // ... ));
现在在fields.html.twig模板中的任何块都可以被广泛的使用来定义表单输出了。
自定义表单输出到一个单一的Twig文件中
在Twig中,你也可以个性化一个表单块在模板中
{% extends '::base.html.twig'%} {# 导入"_self" 作为一个表单主题 #} {% form_theme form _self %} {# 个性化表单片段 #} {% block field_row %} {# 自定义字段行输出 #} {% endblock field_row %} {% block content %} {# ... #} {{ form_row(form.task) }} {% endblock %}
这里{% form_theme form _self %}标签允许表单块在使用那些自动化内容的模板中被直接自定义化。使用这个方法来快速的生成个性化输出。
注意,{% form_theme form _self %}的功能只有在继承自其它模板时才能起作用,如果不是继承自其它模板,则需要指出form_theme 到单独模板中。
PHP
从以前在所有模板中创建的Acme/TaskBundle/Resources/views/Form 目录自动导入个性化模板。修改你的配置文件:
YAML格式:
# app/config/config.yml framework: templating: form: resources: - 'AcmeTaskBundle:Form' # ...
XML格式:
<!-- app/config/config.xml --> <framework:config ...> <framework:templating> <framework:form> <resource>AcmeTaskBundle:Form</resource> </framework:form> </framework:templating> <!-- ... --> </framework:config>
PHP代码格式:
// app/config/config.php $container->loadFromExtension('framework', array( 'templating' => array('form' => array('resources' => array( 'AcmeTaskBundle:Form', ))) // ... ));
此时在Acme/TaskBundle/Resources/views/Form目录中的任何片段都可以全局范围内定义表单输出了。
CSRF 保护
CSRF--Cross-site request forgery,跨站伪造请求 是恶意攻击者试图让你的合法用户在不知不觉中提交他们本不想提交的数据的一种方法。
幸运的是,CSRF攻击可以通过在你的表单中使用CSRF 记号来阻止。
默认情况下,Symfony自动为你嵌入一个合法的CSRF令牌。这就意味着你不需要做任何事情就可以得到CSRF保护。CSRF保护是通过在你的表单中添加一个隐藏字段,默认的名叫_token。它包含一个值,这个值只有你和你的用户知道。这确保了是用户而不是其它实体在提交数据。Symfony自动校验该token是否存在以及其准确性。
_token 字段是一个隐藏字段并且会自动的渲染,只要你在你的模板中包含了form_rest()函数。它确保了没有被渲染过的字段全部渲染出来。CSRF令牌可以按照表单来个性化,比如:
class TaskType extends AbstractType { // ... public function getDefaultOptions(array $options) { return array( 'data_class' => 'Acme\TaskBundle\Entity\Task', 'csrf_protection' => true, 'csrf_field_name' => '_token', // 一个唯一的键值来保证生成令牌 'intention' => 'task_item', ); } // ... }
要关闭CSRF保护,设置csrf_protection 选项为false。intentsion选项是可选的,但为不同的表单生成不同的令牌极大的加强了安全性。
使用一个无底层类表单