3

我正在创建我的 Twig Extension 来扩展实际的“FormExtension”。原因是我需要创建新函数而不覆盖当前函数并使其在整个项目中可用。

因此,建设和扩展似乎是正确的方式。构建扩展不是问题,我的问题是如何从那里渲染块?

到目前为止,我所理解的是,我需要创建一个 Twig_Environment ,我必须在其中加载我的实际树枝模板(包含我的块)。从那里我应该能够使用“$mytemplate->displayBlock()”渲染这些块。

示例代码:

公共函数 renderWidgetinline(FormView $view, array $variables = array()) {

  $loader = new \Twig_Loader_Filesystem(__DIR__.'/../Resources/views/Form');
  $twig = new \Twig_Environment($loader);
  $this->template = $twig->loadTemplate("form_layout.html.twig");

  ob_start();
  $this->template->displayBlock(???WHAT-PARAMS???);
  $html = ob_get_clean();

  return $html;

}

我通过查看 Symfony 基础 FormExtension.php 文件找到了这些信息。

我的问题是:

  1. displayBlock() 是如何工作的,我在哪里可以找到该函数的定义?
  2. 我上面描述的方法是正确的吗?
  3. 我应该如何继续访问该新的 TWIG 模板以及基本的 form_div_layout.html 模板?我能否以某种方式获得当前环境而不必重新创建一个并在那里加载我的附加模板?

谢谢!

4

1 回答 1

2

你试过renderBlock改用吗?

您需要的第一个参数是块的名称,第二个应该是传递给块的值的关联数组。

因此,对于呈现块的服务,您将拥有以下内容:

服务等级:

<?php

namespace Acme\BlockBundle\Blocks;

use Doctrine\Common\Persistence\ObjectManager;

Class Block {

    private $om;
    private $environment;
    private $template;

    public function __construct( ObjectManager $om, Twig $environment )
    {
        $this->om = $om;
        $this->environment = $environment;
    }

    public function render( $template, $data )
    {
        $this->template = $this->environment->loadTemplate( $template );

        // maybe query the DB via doctrine, that is why I have included $om
        // in the service arguments
        // example:

        $entities = $om->getRepository( 'AcmePizzaBundle:Pizza' )->getMeatyOnes()

        return $this->template->renderBlock( 'acme_block', array(
            'data' => $entities,
        ));
    }
}

Twig 扩展类

<?php

namespace Acme\BlockBundle\Twig\Extension;

use Twig_Extension;
use Twig_Function_Method;

class BlockExtension extends Twig_Extension
{
    protected $container;

    public function __construct( $container )
    {
        $this->container = $container;
    }

    public function getName()
    {
        return 'block_extension';
    }

    public function getFunctions()
    {
        return array(
            'render_block' => new Twig_Function_Method( $this, 'renderBlock', array(
                'is_safe' => array( 'html' ),
            )),
        );
    }

    public function renderBlock( $template, $data )
    {
        return $this->container->get( 'acme.block' )->render( $template, $data );
    }
}

服务.yml

parameters:
    acme.blocks.block.class:           Acme\BlocksBundle\Blocks\Block
    acme.twig.block_extension.class:   Acme\BlocksBundle\Twig\Extension\BlockExtension

services:
    acme.blocks.block:
        class:  '%acme.blocks.block.class%'
        arguments:
            - '@doctrine.orm.entity_manager'
            - '@twig'

acme.twig.block_extension:
    class: %acme.twig.block_extension.class%
    arguments:
        - '@service_container'
    tags:
        - { name: twig.extension }

不要忘记您的模板:

{% block acme_block %}
    {% spaceless %}
        {# do something with your data here #}
    {% endspaceless %}
{% endblock acme_block %}

然后当你想显示它时,你只需要调用你刚刚创建的twig函数:

{{ render_block( '::block_template.html.twig', someDataOneThePage ) }}

这绝不是一个完整的解决方案,但我使用了类似的东西,它被证明是有效的。

高温高压

[编辑:2016 年 4 月 - 供参考:此解决方案正在处理 Symfony 2.4 项目]

于 2014-04-06T11:33:39.213 回答