如何创建自定义 Symfony2 Twig 表单模板块

How to create a custom Symfony2 Twig form template block

我正在从事一个需要一些自定义表单模板块的项目。不是现有块的修改版本,而是新块。

我已经能够创建新块并获得 Symfony/Twig 重新识别和使用它们,但有一些限制。

表单模板块似乎有严格的命名约定。 看起来模板名称必须恰好包含一个下划线。下划线前面的单词似乎也有要求 and/or 限制。我已经能够让 form_ 工作,但没有别的。此外,如果您以 _widget 结束块的名称,则不会抛出任何异常,但如果您直接在页面模板中使用该块,则不会呈现任何内容。我认为 _widget 块只能在 form_blocks 中使用(是吗?)。

我的目标是使用项目的首字母 (wwui) 命名我所有的新自定义块,以便其他开发人员(以及我自己 :-) 非常清楚哪些标签是该项目特定的。

这是我为达到当前目标所做的工作:
- 按照 Symfony 表单自定义文档
中的指定创建一个 fields.html.twig 文件 - 在 config.yml
中指定 twig.form.resources 中的表格 - 创建带有函数声明的 Twig 扩展 - 在我的模板中使用我的新块

一个简单的例子:

// TwigExtension.php
...
public function getFunctions()
{
  $ret = 
  [
    new \Twig_SimpleFunction( 'wwui_myBlock', 
            null,
            [ 'node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode',
'is_sage' => [ 'html' ]] ),
    ...
  ];
  return $ret;
)

{# fields.html.twig #}
{% block wwui_myBlock %}
  <p>A simple literal for testing.</p>
{% endblock wwui_myBlock %}

这将引发异常:

An exception has been thrown during the rendering of a template ("Unable to render the form as none of the following blocks exist: "_siteActivityQueryForm_myBlock", "siteActivityQueryForm_myBlock", "form_myBlock".") in SiteBundle:Queries:activity.html.twig at line 31.

如果我将它重命名为 form_byBlock 它工作正常。

所以,问题是:
自定义表单块的正式命名要求和限制是什么。


2015 年 8 月 27 日更新 09:30
回应@lxg 评论的一些附加信息:

A block is simple a block of HTML/Twig code which can be overridden in child templates.

我认为这并不完全准确。一个块(至少是一个表单块)是一个像 Twig 函数一样被引用的 Twig 片段(例如,{{ form_widget( form ) }})。

我在这里专门询问有关表单块的问题。

vendor/symfony/symfony/Bridge/Twig/Extension/FormExtension.php 中定义了其中一些函数。
其中一些(form_widget()form_errors()form_label()form_row()form_rest()form_start()form_end())已实现通过 class Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode(参见 FormExtension.php 中的 getFunctions() 方法)。

这些的 Twig 片段在 vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig 中定义。

我想做的是创建具有项目特定名称的新表单块。

我已经能够创建新的自定义表单块(如上所示),但无法使用我想要使用的名称。

检查 Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode() 方法没有产生额外的理解。

事实证明,Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode() 方法是限制的来源。

还有另一种方法可以让我使用我想要的名字。是Symfony\Bridge\Twig\Node\RenderBlockNode().