2011-09-28 73 views
17

我正在將樹枝模板引擎集成到PHP應用程序中。特別是,我想使用樹枝引擎來渲染表單。樹枝:選擇某些塊並渲染它們

說完看了一眼Symfony2中如何使用樹枝來渲染表單控件,它們有一個包含所有像這樣的小部件一個巨大的模板文件:

(...) 
{% 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'塊,然後將其插入到不同的模板中以呈現整個表單?

+0

這可能適用於我,你可以分享你是如何實際使用的,或者使用'$ loader'嗎? – blamb

回答

22

原來應該使用$template->renderBlock('blockname', array('test' => 'test'));代替。這將使枝條呈現該塊,然後返回包含該塊標記的字符串。然後可以使用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; 
+1

第二個參數的用法是什麼? – Aoi

+2

第二個參數是出現在模板中的一組變量。例如,'{{test}}'。 – F21

+0

即時通訊很難搞清楚這部分,因爲當我這樣做時,我會得到一個異常,就好像還需要一個USE狀態一樣。你是否說這是延長/嵌入了一個沒有USE的聲明,如果需要擴展樹枝引擎?即使我這樣做,它不起作用。 – blamb

3

這是偉大的!我還想補充說,有一個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"); 
1

如果您正在使用Symfony和希望能仍然可以訪問全局變量(應用程序,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將我指向正確的方向。

+0

改爲使用'load()',而不是'loadTemplate()' – Riki137