3

実際の「FormExtension」を拡張するために、Twig 拡張機能を作成しています。その理由は、現在の関数を上書きせずに新しい関数を作成し、プロジェクト全体で使用できるようにする必要があるためです。

したがって、構築と拡張が正しい方法のように思われました。拡張機能の構築は問題ではありません。私の問題はそこからブロックをレンダリングする方法ですか?

ここまで私が理解していたことは、実際の twig テンプレート (ブロックを含む) をロードする必要がある 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 に答える 1

2

renderBlock代わりに使用しようとしましたか?

必要な最初のパラメータはブロックの名前で、2 番目のパラメータはブロックに渡される値の連想配列でなければなりません。

したがって、ブロックをレンダリングするサービスの場合は次のようになります。

サービス クラス:

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

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

それを表示したいときは、作成したtwig関数を呼び出すだけです:

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

これは決して完全な解決策ではありませんが、私は同様のものを使用しており、機能していることが証明されています.

HTH

タム

[編集: 2016 年 4 月 - 参考: このソリューションは Symfony 2.4 プロジェクトに取り組んでいました]

于 2014-04-06T11:33:39.213 に答える