我有以下情况。与典型的ZF2-Application一样,现有布局的layout.phtml
- 视图脚本和特定于被调用操作的视图脚本。就我而言,它是team/frontend/index.phtml
。
我的问题是关于头衔。 headtitle-parts目前直接在view-script-files中设置,如下所示:
layout.phtml
<?php
echo $this->headtitle('My Application')->setAutoEscape(false)->setSeparator(' | ');
队/前端/ index.phtml
<?php
$this->headtitle('Our team');
这是 - 按预期 - 导致My Application | Our team
。到目前为止一切都很好。
现在我正在编写一个新模块,除了其他一些功能之外,还应该提供一些搜索引擎优化的可能性。其中一个SEO任务是覆盖内部视图脚本的标题:team/frontend/index.phtml
但不包括layout.phtml
。新标题来自数据库,但这与此问题无关。
因此,对于此操作,我希望能够产生如下结果:My Application | The faces behind the team
。正如您所看到的,我只想覆盖action-view-script设置的所有内容,而不是覆盖layout.phtml
的标题部分。
因为它是一个完全不同的模块,它会添加这个功能,并且两个模块应该是独立工作的,我希望这可以通过事件/ EventManager来解决。
旁注:调用新模块:节点
我尝试了两件事,两者都导致了同样的事情:
我在[{1}}的{{1}}方法中附加了MvcEvent::EVENT_RENDER
EventManager,并且(在另一次尝试中)我获取了onBootstrap
的EventManager并附加到Node\Module.php
在回调函数中,我从数据库中获取标题,并通过获取HeadTitle-View-Helper来设置它。
两次尝试都产生了Zend\View\View
的最终标题,这意味着虽然我在回调函数中使用了ViewEvent::EVENT_RENDERER_POST
- 参数,但只是附加了部分。
这是回调函数的简化版本:
My Application | Our team | The faces behind the team
正如您在此处所见,我使用SET
作为第二个参数。我明白了,为什么它不起作用:当action-view-script和layout-view-script完成处理时,事件似乎太迟了。但是我需要在处理layout-view-script之前挂钩,以便我可以覆盖action-view-scripts的标题。
我希望你理解我的意思。
对此有何想法?是否有为队列中的每个视图脚本触发的事件?
更新2015-10-14 - 13:10
我进一步研究了ZF2代码中的代码和事件触发。由于它的编写结构,我的请求不可能以我想要的方式实现。
与 Wilt 和 akond 的答案一样,字幕应该通常在动作或特定的其他地方处理,但不在视图脚本本身内
Wilt 发布了有关头号的ZF2-docs的链接。在那里,他们提供了如何在动作中设置标题的示例。
我知道怎么做,但是在专辑 - 模块教程(http://framework.zend.com/manual/current/en/user-guide/database-and-models.html#listing-albums)中,他们在视图中设置了标题,所以我这样做了......
当然,修复我的其他模块(比如我的 Team -Module)对我没有问题,但是我会遇到供应商模块的问题。如果其他模块的作者继续在他们的视图脚本中设置他们的标题,那么我的 Node -Module将不会有机会。在这种情况下我唯一能做的就是覆盖他们的视图脚本并删除标题的设置...
答案 0 :(得分:1)
在我看来,由于数据污染了视图,您遇到了这个问题。换句话说,您不应该将“我的应用程序”或“我们的团队”放入视图中。
你应该拥有的是一个模型/助手,它为视图提供了合适的头部标题。有点像:
$this->view ()->headtitle ('Our team');
控制器动作中的和
echo $this->headtitle
在视图中。
视图应该只呈现模型提供的数据。在我们的例子中,视图本身就是一个模型。那是假的。
答案 1 :(得分:1)
您应该在控制器中设置您的头部标题而不是您的视图 检查the ZF2 documentation on head title以了解如何正确使用此视图助手:
$headTitle = $viewHelperManager->get('headTitle');
$headTitle->setSeparator(' | ');
$headTitle->append('My Application');
$headTitle->append('Our team');
仅在视图中:
<?php echo $this->headTitle() ?>
输出以下html:
<title>My Application | Our team</title>
在您的其他模块中,您可以在另一个控制器中为标题设置新变量。
另一种可能性(不要认为更好)是将标题作为变量传递给参数中的视图。例如:
$view = new ViewModel(array(
'titles' => array(
'layout' => 'My Application',
'action' => 'Our team'
)
));
$view->setTemplate('template');
return $view;
现在,您可以在视图中执行以下操作:
$this->headtitle($this->titles['layout'])->setAutoEscape(false)->setSeparator(' | ');
和
$this->headtitle($this->titles['action']);
这最后一个解决方案更脏,因为如果你问我,你不应该在视图中设置你的头部标题。但它会起作用,它更适合您当前的解决方案(减少重构)。
如果您害怕其他人推翻您在其观看中设置的标题,那么您也可以扩展the HeadTitle
view helper并覆盖the '_invoke' method,这样就不会覆盖$title
如果它已经设定好了。
然后在视图助手管理器中重新注册(覆盖)它:
'view_helpers' => array(
'invokables' => array(
'headTitle' => 'My\Custom\View\Helper\HeadTitle',
)
)