web-dev-qa-db-ja.com

小枝:特定のブロックを選択してレンダリングします

twigテンプレートエンジンをPHPアプリケーションに統合しています。特に、twig engineを使用したいと思います。フォームをレンダリングします。

Symfony2がtwigを使用してフォームウィジェットをレンダリングする方法を確認したところ、次のようなすべてのウィジェットを含む巨大なテンプレートファイルがあります。

(...)
{% block password_widget %}
{% spaceless %}
    {% set type = type|default('password') %}
    {{ block('field_widget') }}
{% endspaceless %}
{% endblock password_widget %}

{% block hidden_widget %}
    {% set type = type|default('hidden') %}
    {{ block('field_widget') }}
{% endblock hidden_widget %}

{% block email_widget %}
{% spaceless %}
    {% set type = type|default('email') %}
    {{ block('field_widget') }}
{% endspaceless %}
{% endblock email_widget %}

{% block test_widget %}
{% spaceless %}
   <div>
     {{test}}
   <div>
{% endspaceless %}
{% endblock test_widget %}

(...)

私が持っている質問は、このテンプレートからブロックを「取得」してレンダリングするにはどうすればよいですか?

これまでのところ、テンプレートをロードし、getブロックを呼び出してすべてのブロックを取得することができます。

twig = new \Twig_Environment($loader, array('cache' => 'cache'));
$template = $twig->loadTemplate('view\form_div_layout.html.twig');
//var_dump($template->getBlocks()); //try getting all blocks
$template->displayBlock('test_widget', array('test' => 'test'));
echo $template->render();

残念ながら、この場合、「test_widget」ブロックだけをレンダリングすることはできません。テンプレートから「test_widget」ブロックを取得し、それを別のテンプレートに挿入してフォーム全体をレンダリングするにはどうすればよいですか?

19
F21

代わりに$template->renderBlock('blockname', array('test' => 'test'));を使用する必要があることがわかりました。これにより、twigそのブロックがレンダリングされ、そのブロックのマークアップを含む文字列が返されます。その後、echoを使用して表示したり、他のテンプレートに挿入したりできます。

完全な例:

$loader = new \Twig_Loader_Filesystem(array('/my-template-root'));
$twig = new \Twig_Environment($loader, array('debug' => true));
$template = $twig->loadTemplate('view\form_div_layout.html.twig');
$result = $template->renderBlock('blockname', array('test' => 'test'));
echo $result;
23
F21

Symfonyを使用していて、グローバル変数(app、app.userなど)に引き続きアクセスできるようにしたい場合、これはうまく機能します。

private function renderBlock($template, $block, $params = array())
{
    /** @var \Twig_Environment $twig */
    $twig = $this->get('twig');
    /** @var \Twig_Template $template */
    $template = $twig->loadTemplate($template);

    return $template->renderBlock($block, $twig->mergeGlobals($params));
}

これを追加したところ、コントローラーにプライベート機能があります。よく働く。私を正しい方向に向けてくれた@ F21に感謝します。

3
Skylord123

これは素晴らしい!また、テンプレートのレンダリングを実行する前に検証を実行できるhasBlock関数があることも追加したいと思います。これにより、テンプレートが期待どおりに作成されているか、私の場合はオプションのブロックがあるかを検証できます。価値があるものとして、通知メールを送信するコンソールアプリの例を次に示します。

        $templateContent = $this->getContainer()->get('twig')->loadTemplate('FTWGuildBundle:AuctionNotification:notificationEmail.html.twig');
        $body = $templateContent->renderBlock('body', array('siteDomain' => $siteClient->getSiteDomain(), 'staticContentDomain' => $siteClient->getStaticContentDomain(), 'batch' => $batch->getNotifications(), 'auction_notification_lockout_period' => $this->getContainer()->getParameter('auction_notification_lockout_period')));
        $subject = ($templateContent->hasBlock("subject")
            ? $templateContent->renderBlock("subject", array('batchSize' => $batch->getSize(), 'batch' => $batch))
            : "Auction House Notifications");
3
Chris

注:テンプレートが親ブロックを拡張または埋め込む場合、hasBlockは機能しません。

https://github.com/twigphp/Twig/issues/45 を参照してください

0
fezfox