我正在将twig模板引擎集成到PHP应用程序中。特别是,我想使用twig引擎来渲染表单。
看了一下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 blocks来获取所有块:
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 :(得分:22)
原来应该使用$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;
答案 1 :(得分: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");
答案 2 :(得分:3)
如果您正在使用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 :(得分:0)
注意:如果模板扩展或嵌入父块,hasBlock将无效。