Symfony 2& Twig,如何从扩展中访问块

时间:2012-05-14 13:59:28

标签: symfony twig

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

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

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

示例代码:

  

public function 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. 如何继续使用基本form_div_layout.html模板访问新的TWIG模板?我可以以某种方式获取当前环境而无需重新创建一个并在那里加载我的附加模板吗?
  4. 谢谢!

1 个答案:

答案 0 :(得分: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 Extension Class

<?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 );
    }
}

services.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 %}

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

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

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

HTH

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