如何处理表单主题

编辑本页

警告:您正在浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 4.2,现已不再维护。

本页的更新版本用于Sy欧宝娱乐app下载地址mfony 6.2(当前稳定版本)。

如何处理表单主题

本文解释了如何在应用程序中使用Symfony提供的任何表单主题,以及如何创建自己的自定义表单主题。欧宝娱乐app下载地址

欧宝娱乐app下载地址Symfony内置表单主题

欧宝娱乐app下载地址Symfony有几个内置表单主题使您的表单在使用一些最流行的CSS框架时看起来很棒。每个主题都在一个单独的Twig模板中定义:

提示

阅读这篇文章Bootstrap 4 欧宝娱乐app下载地址Symfony形式主题了解更多。

将主题应用于所有表单

欧宝娱乐app下载地址Symfony表单默认使用form_div_layout.html.twig主题。如果您想为应用程序的所有表单使用另一个主题,请在twig.form_themes选择:

  • YAML
  • XML
  • PHP
1 2 3 4
#配置/包/ twig.yaml枝:form_themes:(“bootstrap_4_horizontal_layout.html.twig”)#……

您可以将多个主题传递给该选项,因为有时表单主题只重新定义少数元素。这样,如果某个主题没有覆盖某个元素,Symfony就会在其他主题中查找。欧宝娱乐app下载地址

主题的顺序twig.form_themes选择权很重要。每个主题都会覆盖之前的所有主题,因此必须将最重要的主题放在列表的末尾。

将主题应用到单个表单

尽管大多数情况下您将全局应用表单主题,但您可能只需要将主题应用于某些特定的表单。你可以用form_theme树枝标签

1 2 3 4 5 6
{#这个表单主题将只应用于这个模板的表单{%form_theme“foundation_5_layout.html形式。嫩枝' %}{{form_start(form)}}{#……#}{{form_end(form)}}

的第一个参数form_theme标记(形式在本例中)是存储表单视图对象的变量的名称。第二个参数是定义表单主题的Twig模板的路径。

将多个主题应用到单个表单

还可以通过应用多个主题来定制表单。方法将所有Twig模板的路径作为数组传递关键字(它们的顺序很重要,因为每个主题都会覆盖之前的所有主题):

1 2 3 4 5 6 7
{#应用多个表单主题,但仅适用于该模板的表单#}{%form_theme使用['foundation_5_layout.html进行表单。嫩枝”、“形式/ my_custom_theme.html。树枝']%}{#……#}

为子窗体应用不同的主题

你也可以将表单主题应用到表单的特定子元素上:

1
{%form_theme的形式。/ my_custom_theme.html a_child_form”形式。嫩枝' %}

当您希望为不同于主表单的嵌套表单设置自定义主题时,这非常有用。指定两个主题:

1 2
{%form_theme表单的表单/ my_custom_theme.html。嫩枝' %}{%form_theme的形式。/ my_other_theme.html a_child_form”形式。嫩枝' %}

禁用单个表单的全局主题

在应用程序中定义的全局表单主题始终应用于所有表单,即使是那些使用form_theme标签来应用自己的主题。例如,您可能希望在为可以安装在不同Symfony应用程序上的包创建管理界面时禁用此功能(因此您无法控制全局启用的主题)。欧宝娱乐app下载地址要做到这一点,请添加只有表单主题列表后的关键字:

1 2 3
{%form_theme使用['foundation_5_layout.html进行表单。只有树枝%}{#……#}

谨慎

当使用只有关键字,没有任何Symfony内置欧宝娱乐app下载地址的表单主题(form_div_layout.html.twig等)。为了正确地呈现表单,您需要自己提供一个功能齐全的表单主题,或者使用Twig的扩展内置的表单主题之一使用关键字代替扩展重新使用原有的主题内容。

1 2 3 4
{/形式/ common.html #模板。树枝#}{%使用“form_div_layout.html。树枝“%}{#……#}

创建自己的表单主题

欧宝娱乐app下载地址Symfony使用Twig块来呈现表单的每个部分——字段标签、错误、<输入>文本字段,<选择>标签等。一个主题是一个枝条模板,其中有一个或多个你想在呈现表单时使用的那些块。

例如,考虑一个表示整数属性的表单字段年龄.如果你把这个添加到模板:

1
{{form_widget(form.age)}}

生成的HTML内容将是这样的(它将根据应用程序中启用的表单主题而有所不同):

1
<输入类型“数量”id“form_age”的名字“形式[时代]”要求“要求”价值“33”/>

欧宝娱乐app下载地址Symfony使用一个名为integer_widget渲染那个领域。这是因为字段类型是整数你在渲染它小部件(与之相反标签错误帮助).创建表单主题的第一步是知道要覆盖哪个Twig块,如下一节所述。

表单片段命名

表单片段的命名取决于您的需要:

  • 如果你想自定义所有相同类型的字段(例如,所有textarea > <)使用field-type_field-part模式(如。textarea_widget).<李>如果你想自定义只有一个特定字段(例如,textarea > <用于描述字段的内容)使用_field-id_field-part模式(如。_product_description_widget).

在这两种情况下,字段部分可以是以下任何有效的表单字段部分:

同一类型的所有字段的片段命名

这些片段名称遵循type_part模式,其中类型对应于字段类型被渲染(例如:文本区域复选框日期等)和部分对应于什么正在被渲染(例如:标签小部件等)。

片段名称的一些例子是:

单个字段的片段命名

这些片段名称遵循_id_part模式,其中id对应于字段id属性(如。product_descriptionuser_age等)和部分对应于什么正在被渲染(例如:标签小部件等)。

id属性同时包含表单名和字段名(例如。product_price).表单名称可以手动设置,也可以根据您的表单类型名称自动生成。ProductType相当于产品).如果您不确定表单名称是什么,请查看为表单呈现的HTML代码。方法显式定义此值block_name选择:

1 2 3 4 5 6 7 8 9 10 11
使用欧宝娱乐app下载地址组件形式扩展核心类型TextType使用欧宝娱乐app下载地址组件形式FormBuilderInterface公共函数buildForm(FormBuilderInterface构建器数组,选项/ /……构建器->add (“名字”, TextType::类,“block_name”= >“custom_name”]);}

在本例中,片段名称为_product_custom_name_widget而不是默认_product_name_widget

集合的片段命名

当使用收集表格,每个集合项的片段都遵循预定义的模式。例如,考虑下面的复杂示例,其中aTaskManagerType收藏有TaskListType其中有一个集合TaskType

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
TaskManagerType扩展AbstractType公共函数buildForm(FormBuilderInterface构建器数组,选项= [])/ /……构建器->add (“taskLists”, CollectionType::类,“entry_type”= > TaskListType::类,“block_name”= >“task_lists”]);}}TaskListType扩展AbstractType公共函数buildForm(FormBuilderInterface构建器数组,选项= [])/ /……构建器->add (“任务”, CollectionType::类,“entry_type”= > TaskType::类,]);}}TaskType公共函数buildForm(FormBuilderInterface构建器数组,选项= [])构建器->add (“名字”);/ /……}}

然后您将得到以下所有可定制的块(其中可由小部件标签,或帮助):

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
{%_task_manager_task_lists_ * %}{# TaskManager的集合字段#}{%endblock%}{%_task_manager_task_lists_entry_ * %}{#内部TaskListType #}{%endblock%}{%_task_manager_task_lists_entry_tasks_ * %}{# TaskListType的集合字段{%endblock%}{%_task_manager_task_lists_entry_tasks_entry_ * %}{#内部任务类型#}{%endblock%}{%_task_manager_task_lists_entry_tasks_entry_name_ * %}{# TaskType的字段#}{%endblock%}

模板片段继承

每个字段类型都有一个类型(例如,的父类型文本区域文本的父类型文本形式),如果基本欧宝娱乐app下载地址片段不存在,Symfony将使用该片段作为父类型。

例如,当S欧宝娱乐app下载地址ymfony呈现textarea类型的错误时,它首先查找textarea_errors碎片才落回text_errors而且form_errors碎片。

提示

每个字段类型的“父”类型可在表单类型引用对于每个字段类型。

在与表单相同的模板中创建表单主题

建议在应用程序中定制特定于单个表单时,例如更改所有表单textarea > <表单元素或自定义一个非常特殊的表单字段,这将由JavaScript处理。

你只需要添加特价{% form_theme form _self %}标记到呈现表单的同一模板。这使得Twig在模板中寻找任何被覆盖的表单块:

12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21
{%扩展“base.html.twig”%}{%form_themeForm _self %}{#这个覆盖任何整数类型的字段的小部件,但只在这个模板中呈现的表单中{%integer_widget %}<div“…”>{#……渲染HTML元素来显示这个字段…#}div>{%endblock%}{#这覆盖了字段中"id" = "product_stock"(和"name" = "product[stock]")的整行,但仅限于在这个模板中呈现的表单#}{%_product_stock_row %}<div“…”id“…”>{#……渲染整个字段内容,包括它的错误…#}div>{%endblock%}{#……渲染表单…#}

这种方法的主要缺点是,它只在模板扩展另一个(“base.html.twig”在前面的例子中)。如果你的模板没有,你必须指向form_theme到一个单独的模板,如下一节所述。

另一个缺点是,在其他模板中呈现其他表单时,不能重用定制的表单块。如果这是您所需要的,请在下一节中解释的那样在单独的模板中创建表单主题。

在单独的模板中创建表单主题

当创建在整个应用程序中使用的表单主题,甚至在不同的Symfony应用程序中重用时,建议这样做。欧宝娱乐app下载地址您只需要在某个地方创建一个Twig模板并遵循表单片段命名规则来知道要定义哪些树枝块。

例如,如果您的表单主题很简单,而您只想重写< input type = "整" >元素,创建这个模板:

1 2 3 4 5 6
{/形式/ my_theme.html #模板。树枝#}{%integer_widget %}{#……添加渲染此字段所需的所有HTML, CSS和JavaScript{%endblock%}

现在,您需要告诉Symfony使用这个表单欧宝娱乐app下载地址主题,而不是(或添加到)默认主题。如本文前几节所述,如果希望将主题全局应用于所有表单,请定义twig.form_themes选择:

  • YAML
  • XML
  • PHP
1 2 3 4
#配置/包/ twig.yaml枝:form_themes:['形式/ my_theme.html.twig ']#……

如果只希望将其应用于某些特定的表单,请使用form_theme标签:

1 2 3 4 5
{%form_theme表单的表单/ my_theme.html。嫩枝' %}{{form_start(form)}}{#……#}{{form_end(form)}}

重用内置表单主题的部分

创建一个完整的表单主题需要大量的工作,因为有太多不同的表单字段类型。你可以只定义你感兴趣的块,然后在你的应用程序或模板中配置多个表单主题,而不是定义所有这些Twig块。这是因为当呈现一个在自定义主题中没有被覆盖的块时,Symfony会退回到其他主题。欧宝娱乐app下载地址

方法使表单主题模板从内置主题之一扩展树枝“使用”标签而不是扩展标签,这样您就可以继承它的所有块(如果您不确定,可以从默认扩展form_div_layout.html.twig主题):

1 2 3 4
{/形式/ my_theme.html #模板。树枝#}{%使用“form_div_layout.html。嫩枝' %}{#……只覆盖您感兴趣的块#}

最后,您还可以使用枝父()函数重复使用内置主题的原始内容。当你只想做一些小的改变时,这是很有用的,比如用一些元素包装生成的HTML:

1 2 3 4 5 6 7 8
{/形式/ my_theme.html #模板。树枝#}{%使用“form_div_layout.html。嫩枝' %}{%integer_widget %}<div“some-custom-class”>{{()}}div>{%endblock%}

当在呈现表单的模板中定义表单主题时,此技术也适用。然而,从内置主题导入块有点复杂:

12 3 4 5 6 7 8 9 10 11 12 13
{%form_themeForm _self %}{#从内置主题导入一个块并重命名它,这样它就不会与这个模板中定义的相同块冲突#}{%使用“form_div_layout.html。用integer_widget作为base_integer_widget %}{%integer_widget %}<div“some-custom-class”>{{(“base_integer_widget”)}}div>{%endblock%}{#……渲染表单…#}

自定义表单验证错误

如果你定义验证规则对于对象,当提交的数据无效时,您将看到一些验证错误消息。属性显示这些消息form_errors ()功能,并可自定义使用form_errors树枝块在任何形式的主题,如前所述的章节。

需要考虑的重要一点是,某些错误与整个表单相关,而不是与特定字段相关。为区分全局错误和局部错误,请使用表单中可用的变量被称为复合.如果是的话真正的,这意味着当前呈现的是一个字段的集合(例如,一个完整的表单),而不仅仅是一个单独的字段:

12 3 4 5 6 7 8 9 10 11 12 13 14 15
{/形式/ my_theme.html #模板。树枝#}{%form_errors %}{%如果错误|长度> 0%}{%如果复合%}{#……显示全局表单错误#}<ul>{%错误%}中的错误<>{{错误。消息}}>{%endfor%}ul>{%其他的%}{#……显示单个字段的错误#}{%endif%}{%endif%}{%endblockform_errors %}
此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。