如何在 Zend Framework 3 中为不同的模块设置不同的布局,而不是在整个站点中使用一个相同的布局模板?
2 回答
<a href="https://framework.zend.com/manual/2.4/en/modules/zend.view.quick-start.html" rel="nofollow noreferrer">Zend 框架 - 问题
> 您可能希望根据当前模块更改布局。这需要 (a) 检测路由匹配的控制器是否属于该模块,然后 (b) 更改 View Model 的模板。</p>
执行这些操作的地方是在监听器中。它应该以低(负)优先级侦听“路由”事件,或者以任何优先级侦听“调度”事件。通常,您将在引导事件期间注册它。
namespace Content;
class Module
{
/**
* @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
* @return void
*/
public function onBootstrap($e)
{
// Register a dispatch event
$app = $e->getParam('application');
$app->getEventManager()->attach('dispatch', array($this, 'setLayout'));
}
/**
* @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
* @return void
*/
public function setLayout($e)
{
$matches = $e->getRouteMatch();
$controller = $matches->getParam('controller');
if (false === strpos($controller, __NAMESPACE__)) {
// not a controller from this module
return;
}
// Set the layout template
$viewModel = $e->getViewModel();
$viewModel->setTemplate('content/layout');
}
}
手册上面说了,但如果你想使用这些代码,你需要:</p>
// module/Content/config/module.config.php
return [
/* whatever else */
'view_manager' => [
'template_map' => [
'content/layout' => __DIR__ . '/../view/layout/layout.phtml'
]
]
];
</p>
很快,当所有模块初始化(引导)成功时,Zend 会onBootstrap()
自动调用,将'dispatch'事件绑定到setLayout()
方法,其中控制器名称与当前模块的命名空间匹配,如果成功,则setTemplate()
用于设置布局模板。
例如</p>
Module/Namespace: Content,
<code>控制器:Content\Controller\MatchMeController,(成功!)
Controller: Other\Controller\DontMatchMeController,
(失败!)
但是有个小缺点:setLayout()
使用 </p>
strpos(controller, __NAMESPACE__) === false
</p>
识别当前模块,但是如果我ContentController
在其他模块中有一个呢?所以用</p>
strpos(controller, __NAMESPACE__) !== 0
反而。
----------
<a href="https://framework.zend.com/manual/2.4/en/modules/zend.view.quick-start.html" rel="nofollow noreferrer">Zend 框架 - 问题
该手册非常详细,它还提到了许多其他内容,例如为不同的控制器(或动作)设置不同的布局。</p>
您可以使用以下代码在特定控制器操作的布局之间切换:
// A controller's action method that uses an alternative
// layout template.
public function indexAction()
{
//...
// Use the Layout plugin to access the ViewModel
// object associated with layout template.
$this->layout()->setTemplate('layout/layout2');
//...
}
除了
Layout
控制器插件之外,还有Layout
提供相同功能的视图助手。例如,使用布局视图助手,您可以从没有特定控制器操作的“静态”页面切换布局。
设置控制器所有动作的布局
如果一个控制器类的所有动作方法都需要使用相同的替代布局,您可以覆盖该类的onDispatch()
方法AbstractActionController
并在那里调用该setTemplate()
方法,如下例所示:
// Add this alias in the beginning of the controller file
use Zend\Mvc\MvcEvent;
// ...
class IndexController extends AbstractActionController
{
/**
* We override the parent class' onDispatch() method to
* set an alternative layout for all actions in this controller.
*/
public function onDispatch(MvcEvent $e)
{
// Call the base class' onDispatch() first and grab the response
$response = parent::onDispatch($e);
// Set alternative layout
$this->layout()->setTemplate('layout/layout2');
// Return the response
return $response;
}
}