Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在Symfony2中创建动态模板选择器?_Php_Symfony_Templating - Fatal编程技术网

Php 如何在Symfony2中创建动态模板选择器?

Php 如何在Symfony2中创建动态模板选择器?,php,symfony,templating,Php,Symfony,Templating,我想创建一个动态模板定位器。 基本上,当满足一些全局条件时,我希望对某些捆绑包中的模板进行优先级排序。类似于包继承的工作方式,但运行时是动态的 它应该是这样工作的: 我有一些“类别”,每个类别都有自己的捆绑包。在呈现模板时,我会检查当前设置的类别,并在该类别的捆绑包中搜索该模板。如果找不到,则回退到内置机制 我考虑过重写Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator,但这似乎有点太老套了。如果可能的话,我想模仿bu

我想创建一个动态模板定位器。 基本上,当满足一些全局条件时,我希望对某些捆绑包中的模板进行优先级排序。类似于包继承的工作方式,但运行时是动态的

它应该是这样工作的: 我有一些“类别”,每个类别都有自己的捆绑包。在呈现模板时,我会检查当前设置的类别,并在该类别的捆绑包中搜索该模板。如果找不到,则回退到内置机制

我考虑过重写
Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator
,但这似乎有点太老套了。如果可能的话,我想模仿bundle继承,但是我找不到它在哪里实现


你将如何处理这个问题?
TemplateLocator
是注入我的逻辑的最佳位置吗?

这可能不是最漂亮的解决方案,但它的效果很好

我对
TemplateLocator
服务进行了子类化和重载:

class CategoryWareTemplatelocator扩展了TemplateLocator
{
/**
*@var字符串
*/
受保护的$categoryBundle=null;
/**
*@var字符串
*/
受保护的$defaultBundle=null;
/**
*{@inheritardoc}
*/
公共函数构造(FileLocator接口$locator,$cacheDir=null)
{
父项::_构造($locator,$cacheDir);
}
/**
*{@inheritardoc}
*/
公共函数locate($template,$currentPath=null,$first=true)
{
if(!$TemplateInstanceof TemplateReferenceInterface){
抛出new\InvalidArgumentException('模板必须是TemplateReferenceInterface的实例');
}
$templateParameters=$template->all();
$templateBundle=array\u key\u存在('bundle',$templateParameters)?$templateParameters['bundle']:null;
如果(
null!=$this->categoryBundle&&
$templateBundle===$this->defaultBundle/*仅覆盖defaultBundle模板*/
) {
/*先试试我们的分类包*/
$categoryTemplate=克隆$template;
$categoryTemplate->set('bundle',$this->categoryBundle);
试一试{
返回父节点::locate($categoryTemplate,$currentPath,$first);
}捕获(\InvalidArgumentException$exception){
/*只是通过默认机制*/
}
}
返回父::locate($template,$currentPath,$first);
}
/**
*@param string$defaultBundle
*@param string$categoryBundle
*/
公共函数setCategoryBundle($defaultBundle,$categoryBundle)
{
$this->categoryBundle=$categoryBundle;
$this->defaultBundle=$defaultBundle;
}
}
所需的捆绑包名称在运行时通过setter注入(在“编译时”未知)。这也有点难看

最棒的是,这适用于所有细枝标记(
包括
使用
,…)。唯一的问题是您无法访问正在覆盖的“默认”模板。如果您试图从覆盖它的模板执行此操作,您将得到嵌套级别(无限递归)错误

这不是一个大问题,因为您可以使用组合(将模板拆分为较小的模板)巧妙地“继承”基础模板