我的项目有一个包含主模板的核心包, 我有作为捆绑实现的可选功能。 不同的客户端获得项目的副本,激活了不同的包(=功能)。
功能包需要做的一件事是向主模板添加内容(在核心包中)。 显然,我不希望核心包中的模板能够“知道”#34;关于可选的捆绑包,所以我想要"钩子"在其他包可以将内容倒入的模板中。
我有一个解决方案,似乎有效。我希望得到反馈/建议。
我有一个twig函数可以得到一个" hook"名称。我将该功能放在我的模板中的不同位置。
该函数引发一个事件(通过事件调度程序)从各种事件侦听器收集html代码段(功能包负责这些侦听器),连接这些代码段并返回它们。
代码:
树枝功能:
new \Twig_SimpleFunction('template_hook', array( $this, 'templateHookFunction' ), array('is_safe' => array('html'))),
public function templateHookFunction($hookName)
{
$hookData = $this->eventDispatcher->dispatch(
TemplateHookEvent::TEMPLATE_HOOK,
new TemplateHookEvent($hookName)
)->getData();
return $this->hookDataRenderer->render($hookData);
}
事件:
<?php
namespace CRM\TwigBundle\Event;
use CRM\TwigBundle\Hook\HookData;
use Symfony\Component\EventDispatcher\Event;
class TemplateHookEvent extends Event
{
const TEMPLATE_HOOK = 'crm_twig.template_hook';
private $hookName;
/** @var HookData $data */
private $data;
function __construct($hookName)
{
$this->hookName = $hookName;
$this->data = new HookData();
}
/**
* @return mixed
*/
public function getHookName()
{
return $this->hookName;
}
/**
* @return HookData
*/
public function getData()
{
return $this->data;
}
/**
* @param HookData $data
*/
public function setData(HookData $data)
{
$this->data = $data;
}
public function addData($label, $html, $overwrite = true)
{
if ($overwrite || !isset($this->data[$label])) {
$this->data[$label] = $html;
} else {
$this->data[$label] .= $html;
}
}
}
听众的一个例子:
<?php
namespace CRM\ComputersBundle\EventListener;
use CRM\TwigBundle\Event\TemplateHookEvent;
class TemplateHookListener {
public function onTemplateHook(TemplateHookEvent $event)
{
$event->addData('computersBundle', '<li>CAKE</li>');
}
}
HookData只是一个数组的包装器(现在),每个侦听器都可以将它自己的片段推送给它。
并且HookDataRenderer只是加入(内爆)数组,并返回结果。