如何在Zend Framework 3中为不同的模块设置不同的布局
如何在Zend Framework 3中为不同的模块设置不同的布局,而不是在整个站点中使用单个相同的布局模板?
How can I set different layouts for different modules in Zend Framework 3 instead of using single one same layout template all around the site?
>您可能想根据当前的布局更改布局 模块.这要求(a)检测控制器是否匹配 路由属于此模块,然后(b)更改以下内容的模板 视图模型.
> You may want to alter the layout based on the current module. This requires (a) detecting if the controller matched in routing belongs to this module, and then (b) changing the template of the View Model.
执行这些操作的位置在侦听器中.应该听 优先级低(负)的路由"事件,或者 派遣"事件,具有任何优先权.通常,您将注册此 在引导事件期间.
The place to do these actions is in a listener. It should listen either to the "route" event at low (negative) priority, or on the "dispatch" event, at any priority. Typically, you will register this during the bootstrap event.
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');
}
}
手册上面说过,但是如果您想使用这些代码,则需要:
The manual says above, but if you want to use these code, you'll need:
// module/Content/config/module.config.php
return [
/* whatever else */
'view_manager' => [
'template_map' => [
'content/layout' => __DIR__ . '/../view/layout/layout.phtml'
]
]
];
很快,当所有模块成功初始化(引导)时,Zend会自动调用onBootstrap()
,它将'dispatch'事件绑定到setLayout()
方法,其中控制器名称与当前模块的名称空间匹配,如果成功,则使用setTemplate()
设置布局模板.
Shortly, when all modules initialized(bootstrap) successfully, Zend will call onBootstrap()
automatically, which bind 'dispatch' event to setLayout()
method, where the controller name is matched with current module's namespace, and if success, use setTemplate()
to set layout template.
例如
Module/Namespace: Content,
Controller: Content\Controller\MatchMeController,
(成功!)
Controller: Other\Controller\DontMatchMeController,
(失败!)
但是有一个小缺点:setLayout()
使用
But there is a tiny drawback: setLayout()
use
strpos(controller, __NAMESPACE__) === false
标识当前模块,但是如果我在其他模块中包含ContentController
怎么办?所以用
to identify current module, but what if I had a ContentController
in some other module? So use
strpos(controller, __NAMESPACE__) !== 0
相反.
----------
----------
该手册非常详细,还提到了许多其他内容,例如为不同的控制器(或动作)设置不同的布局.
The manual is quite detailed, it also mentions lots of other things like set different layouts for different controllers (or actions).