我刚刚开始研究Zend框架2.我无法弄清楚的一件事是,当我决定使用什么视图模板时,如何更改框架的行为viewmodel。
当我自己找到答案时,我发现了以下内容,其中指出Zend使用以下路径解析视图模板:
{normalized-module-name}/{normalized-controller-name}/{normalized-action-name}
现在我正在寻找编辑或删除normalized-module-name段。所有视图文件都保留在我的module / views文件夹中。我想改变它的原因是因为我使用子命名空间作为我的模块名称,导致命名空间的第一段作为规范化模块名称(对我来说不够具体)。
举个例子,模块Foo\Bar
将导致从以下位置呈现示例视图:
/modules/Foo/Bar/view/foo/test/index.phtml
。
我想将默认行为更改为:
/modules/Foo/Bar/view/bar/test/index.phtml
答案 0 :(得分:4)
从zf 2.3开始,您可以使用额外的配置参数view_manager['controller_map']
来启用不同的模板名称解析。
请查看此PR以获取更多信息:https://github.com/zendframework/zf2/pull/5670
'view_manager' => array(
'controller_map' => array(
'Foo\Bar' => true,
),
);
将导致控制器FQCN以' Foo \ Bar'开头。按照这些规则解决:
例如:Foo\Bar\Controller\Baz\TestController
- > foo/bar/baz/test/actionname
<强>更新强>
从zend-mvc v3.0开始,这是默认行为
答案 1 :(得分:3)
我有类似的问题,这是我的解决方案。
默认模板注入器以优先级-90附加到当前控制器的事件管理器,仅当视图模型未提供模板名称时才会解析模板名称。 知道了这一点,您可以使用所需的逻辑创建自己的模板注入器,并将其附加到具有更高优先级的事件管理器。
请参阅以下代码:
public function onBootstrap(EventInterface $event)
{
$eventManager = $event->getApplication()->getEventManager();
$eventManager->getSharedManager()
->attach(
'Zend\Stdlib\DispatchableInterface',
MvcEvent::EVENT_DISPATCH,
new TemplateInjector(),
-80 // you can put here any negative number higher -90
);
}
您的模板注入器,它解析模板路径而不是默认路径。
class TemplateInjector
{
public function __invoke(MvcEvent $event)
{
$model = $event->getResult();
if (!$model instanceof ViewModel)
{
return;
}
$controller = $event->getTarget();
if ($model->getTemplate())
{
return ;
}
if (!is_object($controller))
{
return;
}
$namespace = explode('\\', ltrim(get_class($controller), '\\'));
$controllerClass = array_pop($namespace);
array_pop($namespace); //taking out the folder with controllers
array_shift($namespace); //taking out the company namespace
$moduleName = implode('/', $namespace);
$controller = substr($controllerClass, 0, strlen($controllerClass) - strlen('Controller'));
$action = $event->getRouteMatch()->getParam('action');
$model->setTemplate(strtolower($moduleName.'/'.$controller.'/'.$action));
}
}
以下是我的博客中的链接,我在其中详细介绍了它:http://blog.igorvorobiov.com/2014/10/18/creating-a-custom-template-injector-to-deal-with-sub-namespaces-in-zend-framework-2/
答案 2 :(得分:0)
ViewModel的正确模板被注入MVC事件&#39; dispatch&#39; (由ViewManager定义)Zend\Mvc\View\Http\InjectTemplateListener
,优先级为-90
您必须创建自定义的InjectTemplateListener并以相同事件的更高优先级注册它。
但我建议手动设置每个动作的模板,因为性能 - 请参阅http://samminds.com/2012/11/zf2-performance-quicktipp-1-viewmodels/
答案 3 :(得分:0)
模板名称解析是一个繁重的过程(在系统资源上),所有关于ZF2性能的文章都说你应该手动提供模板名称以提高性能。
所以不要浪费时间寻找一种方法来做一些你最终会手动做的事情:D
答案 4 :(得分:0)
为了改进Next Developer的答案,我在TemplateInjector.php中编写了以下代码:
class TemplateInjector
{
public function __invoke(MvcEvent $event)
{
$model = $event->getResult();
if (!$model instanceof ViewModel) {
return;
}
if ($model->getTemplate()) {
return;
}
$controller = $event->getTarget();
if (!is_object($controller)) {
return;
}
$splitNamespace = preg_split('/[\\\]+/', ltrim(get_class($controller), '\\'));
$moduleName = $splitNamespace[1];
$controller = $splitNamespace[0];
$action = $event->getRouteMatch()->getParam('action');
$model->setTemplate(strtolower($moduleName . '/' . $controller . '/' . $action));
}
}
我改变了构建模板路径的方法。使用regexp比使用数组方法更快。