0

如何在 Zend Framework 3 中为不同的模块设置不同的布局,而不是在整个站点中使用一个相同的布局模板?

4

2 回答 2

3



<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>

于 2016-12-17T13:38:05.390 回答
1

您可以使用以下代码在特定控制器操作的布局之间切换:

// 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;
  }
}

参考

于 2016-12-16T10:07:18.253 回答