且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-09-01 14:53:10

原来, Symfony \ Bridge \Twig\Node\SearchAndRenderBlockNode()方法是限制来自于。



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


I am working on a project for which I need some custom form template blocks. Not modified versions of the existing blocks, but new blocks.

I have been able to create new blocks and get Symfony/Twig to regognize and use them, but with limitations.

It appears that there are strict naming conventions for form template blocks. It appears that template names must contain exactly one underscore. There also appear to be requirements and/or limitations on the word preceding the underscore. I have been able to get form_ to work, but nothing else. Also, if you end the name of a block with _widget, no exceptions will be thrown, but nothing will be rendered if you use the block directly in your page template. I presume that _widget blocks may only be used from within form_blocks (true?).

My goal is to name all of my new custom blocks using the project's initials (wwui) to make it very clear to other developers (and myself somewhere down the road :-) which tags are specific to this project.

This is what I have done to get to my current point:
- Create a fields.html.twig file as specified in the Symfony form customization docs
- Specify that form in twig.form.resources in config.yml
- Create a Twig extension with a function declaration - Use my new block in my templates

A simple example:

// 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 %}

This will throw an exception:

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.

If I rename it to form_byBlock it works fine.

So, the question is:
What are the formal naming requirements and limitations for custom form blocks.


Update 27-Aug-2015 09:30
Some additional information in response to a comment by @lxg:

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

I don't think that's entirely accurate. A block (at least a form block) is a Twig snippet that is referenced like a Twig function (e.g., {{ form_widget( form ) }}).

I'm asking specifically about form blocks here.

A number of these functions are defined in vendor/symfony/symfony/Bridge/Twig/Extension/FormExtension.php.
and several of those (form_widget(), form_errors(), form_label(), form_row(), form_rest(), form_start(), and form_end()) are implemented by the class Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode (see the getFunctions() method in FormExtension.php).

The Twig snippets for these are defined in vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig.

What I want do to is create new form blocks with project-specific names.

I have been able to create new, custom form blocks (as shown above), but not with the names that I would like to use.

Examining the Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode() method has yielded no additional understanding.

Turns out that the Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode() method is where the limitations are coming from.

There is another method that allows me to use the names that I want. It is Symfony\Bridge\Twig\Node\RenderBlockNode().