Twig模板的表单函数和表单变量参考

3.3 version
维护中的版本

当在模板中遇到表单时,在你的处置过程中有两个强力功能:

  • Functions (函数)用于渲染表单的每一部分;
  • Variables (变量)用于获取任意表单字段的 任意 信息。

表单渲染函数 

form(view, variables) 

1
2
3
{# render the form and change the submission method #}
{# 渲染表单,同时更改提交method #}
{{ form(form, {'method': 'GET'}) }}
1
2
3
4
5
6
7
8
{{ form_start(form) }}
    {{ form_errors(form) }}
 
    {{ form_row(form.name) }}
    {{ form_row(form.dueDate) }}
 
    {{ form_row(form.submit, { 'label': 'Submit me' }) }}
{{ form_end(form) }}

form_start(view, variables) 

1
2
3
{# render the start tag and change the submission method #}
{# 渲染表单的开始标签,同时更改提交method #}
{{ form_start(form, {'method': 'GET'}) }}

form_end(view, variables) 

1
{{ form_end(form) }}
1
2
3
4
{# don't render unrendered fields #}
{# 不去渲染未渲染的字段 #}
{{ form(form, {'method': 'GET'}) }}
{{ form_end(form, {'render_rest': false}) }}

form_label(view, label, variables) 

1
2
3
4
5
6
7
8
9
10
{{ form_label(form.name) }}
 
{# The two following syntaxes are equivalent #}
{# 以下两种语法是等同的 #}
{{ form_label(form.name, 'Your Name', {'label_attr': {'class': 'foo'}}) }}
 
{{ form_label(form.name, null, {
    'label': 'Your name',
    'label_attr': {'class': 'foo'}
}) }}

参见 "表单变量的更多内容" 以了解更多关于 variables 参数的内容。

form_errors(view) 

1
2
3
4
5
{{ form_errors(form.name) }}
 
{# render any "global" errors #}
{# 对任何“全局”错误信息进行输出 #}
{{ form_errors(form) }}

form_widget(view, variables) 

1
2
3
{# render a widget, but add a "foo" class to it #}
{# 渲染表单字段的小部件,但为它添加一个“foo”的CSS class #}
{{ form_widget(form.name, {'attr': {'class': 'foo'}}) }}

form_widget 的第二个参数是一个由变量组成的数组。最常用的变量是 attr,它是一个HTML属性的数组,用在HTML widget上。在一些场合中,特定的types也会有其他一些“与模板相关”的选项可以传进来。后面会逐类型地进行基本功能讨论。 attributes 在你一次输出很多字段时 (比如通过 form_widget(form)),并不递归地作用于子字段。

参见 "表单变量的更多内容" 以了解更多关于 variables 参数的内容。

form_row(view, variables) 

输出给定字段的“row”,每个字段行包括字段label,字段错误信息,字段小部件(译注:widget即构成表单的最核心部分,比如一个input标签)。

1
2
3
{# render a field row, but display a label with text "foo" #}
{# 输出一个字段的完整行,但显示label文本为“foo” #}
{{ form_row(form.name, {'label': 'foo'}) }}

form_row 的第二个参数是由变量组成的一个数组。Symfony中提供的模板,只允许像上例那样覆写labels。

参见 "表单变量的更多内容" 以了解更多关于 variables 参数的内容。

form_rest(view, variables) 

对某个给定表单,输出所有“尚未被渲染”的那些字段内容。在表单中的某处使用此函数是个好办法,因为它会帮你渲染隐藏字段,并且会把你已忘记的字段显示出来(因为它会帮你渲染该字段)。

1
{{ form_rest(form) }}

表单测试参考 

测试的执行靠的是Twig中的 is 操作符来创建一个条件。参考 the Twig documentation(Twig文档) 以了解更多。

selectedchoice(selected_value) 

这个测试,会检查当前选项是否等于 selected_value,或者,检查当前选项是否存在于数组中 (当 selected_value 是一个数组时)。

1
<option {% if choice is selectedchoice(value) %} selected="selected"{% endif %} ...>

表单变量的更多内容 

完整的变量列表,请参考:表单变量参考

在上面的Twig函数中,差不多每个函数的最后一个参数都是一个“变量”的数组,在渲染表单某一部分时要用到,以下代码为某字段渲染一个“widget”小部件,并修改其属性令其引入一个特殊的CSS class:

1
2
3
{# render a widget, but add a "foo" class to it #}
{# 渲染表单字段的小部件,但为它添加一个“foo”的CSS class #}
{{ form_widget(form.name, { 'attr': {'class': 'foo'} }) }}

这堆变量的目的 - 它们要做什么,以及它们来自于哪里 - 在本文中可能并没有立即体现得十分清晰,但它们却不思议的强大。只要你渲染出表单的任何一个部分,用于渲染它的块儿(block)就会利用这堆变量中的某些个。默认时,渲染块儿都在 form_div_layout.html.twig 中。

form_label 作为例子看一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{% block form_label %}
    {% if not compound %}
        {% set label_attr = label_attr|merge({'for': id}) %}
    {% endif %}
 
    {% if required %}
        {% set label_attr = label_attr|merge({
            'class': (label_attr.class|default('') ~ ' required')|trim
        }) %}
    {% endif %}
 
    {% if label is empty %}
        {% set label = name|humanize %}
    {% endif %}
 
    <label
        {% for attrname, attrvalue in label_attr -%}
            {{ attrname }}="{{ attrvalue }}"
        {%- endfor %}
    >
        {{ label|trans({}, translation_domain) }}
    </label>
{% endblock form_label %}

这个块儿利用了若干变量: compound, label_attr, required, label, name 以及 translation_domain。这些变量是表单渲染系统所提供的。然而更重要的是,这些都是你在调用 form_label 时(因为在本例中,你在渲染的就是label),可以去“覆写”的变量。

究竟哪些变量可以覆写,取决于你正在渲染的是表单的哪一部分 (比如,label 还是 widget),以及你正在渲染的是哪一个字段 (比如,一个 choice widget会有一个额外的 expanded 选项)。如果你在研究 form_div_layout.html.twig 的源代码时感觉良好,你将始终可以来查看“可用的选项”都有些什么。

背后的过程是,当表单组件对你的表单树(form tree)中的每一个“节点”去调用 buildViewfinishView 方法时,这些变量被提供给你的表单的 FormView 对象。要了解一个特定字段有哪些 "view" 变量,请在该字段(连同其父字段)的源代码中寻找,并查看上面这两个方法。

如果你是一次输出整个表单(或一个完整的内嵌表单),variables 参数将只能被用于表单本身而不是它的子项。换言之,下列代码将 不能 把“foo”这个class属性,传给当前表单的所有子字段:

1
2
3
{# does **not** work - the variables are not recursive #}
{# **不能**工作 - 变量不能递归使用 #}
{{ form_widget(form, { 'attr': {'class': 'foo'} }) }}

表单变量参考 

以下变量在每一个字段类型(field type)中都很常见。特定的字段类型可能拥有更多的变量,而此处的某些变量则只能用于特定字段类型。

假设你在模板中有一个 form 变量,你希望引用该变量的 name 字段,对这个变量进行访问,是通过使用 FormView 对象中的一个public vars 属性而实现的:

1
2
3
4
<label for="{{ form.name.vars.id }}"
    class="{{ form.name.vars.required ? 'required' : '' }}">
    {{ form.name.vars.label }}
</label>
1
2
3
4
<label for="<?php echo $view['form']->get('name')->vars['id'] ?>"
    class="<?php echo $view['form']->get('name')->vars['required'] ? 'required' : '' ?>">
    <?php echo $view['form']->get('name')->vars['label'] ?>
</label>
Variable Usage
form 当前 FormView 实例。
id 要渲染的 id HTML属性。
name 字段名称 (如 title) - 它不是 name HTML属性,HTML属性是 full_name
full_name 要渲染的 name HTML属性。
errors 附在特殊的 this 字段(如 form.title.errors) 上的一个“任意错误信息”的数组。注意,你不可以使用 form.errors 来决定一个表单是否通过验证,因为它返回的是一个“全局”的错误:而某些个体字段是有自己的错误信息的。使用 valid 选项来替代。
submitted 返回 truefalse ,取决于是否提交了整个表单。
valid 返回 truefalse ,取决于是否整个表单通过了验证。
value 渲染时要用到的值 (通常就是 value HTML属性)。
disabled 如果是 true, disabled="disabled" 将被添加到字段中。
required 如果是 true, 一个 required 属性将被添加到字段中,以激活(现代浏览器的)HTML5验证。 此外,一个 required class会被添加到label中。
label 将被渲染的字符串label。
multipart 如果是 true, form_enctype 将被渲染为 enctype="multipart/form-data"。只适用于根表单元素(root form element)。
attr 一个键值型数组,将作为字段的HTML属性而被渲染。
label_attr 一个键值型数组,将作为label的HTML属性而被渲染。
compound 某个字段是否为“一组子字段”的真正宿主(holder。例如,一个 choice 字段,确定会有一组checkboxes)。
block_prefixes 所有父类型名称的一个数组。
translation_domain 当前表单的翻译域(translation domain)。
cache_key 一个用于缓存的唯一键。
data 字段类型的normalized数据。(译注:要参考sf表单原理)
method 当前表单的method (POST, GET, 等等)。
action 当前表单的action。

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)