如何在Zend Framework 3中为不同的模块设置不同的布局

时间:2016-12-16 10:03:15

标签: php zend-framework zend-framework3

如何在Zend Framework 3中为不同的模块设置不同的布局,而不是在网站周围使用单个相同的布局模板?

2 个答案:

答案 0 :(得分:2)

Zend Framework - Issue

  

>您可能希望根据当前更改布局   模块。这需要(a)检测控制器是否匹配   路由属于这个模块,然后(b)更改模板   视图模型。   

     

做这些行动的地方是听众。它应该听   要么是低(负)优先的“路线”事件,要么是   “派遣”活动,无论如何。通常,您将注册此   在引导活动期间。

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');
    }
}

上面的手册说明了,但是如果你想使用这些代码,你需要:

// module/Content/config/module.config.php

return [

    /* whatever else */

    'view_manager' => [
        'template_map' => [
            'content/layout' => __DIR__ . '/../view/layout/layout.phtml'

        ]
    ]
];

很快,当所有模块成功初始化(bootstrap)时,Zend将自动调用onBootstrap(),将'dispatch'事件绑定到setLayout()方法,其中控制器名称与当前模块的命名空间匹配,并且如果成功,请使用setTemplate()设置布局模板。

e.g。

Module/Namespace: Content,

Controller: Content\Controller\MatchMeController,(成功!)

Controller: Other\Controller\DontMatchMeController,(失败!)

但是有一个小缺点:setLayout()使用

strpos(controller, __NAMESPACE__) === false

识别当前模块,但是如果我在其他模块中有ContentController怎么办?所以使用

strpos(controller, __NAMESPACE__) !== 0

代替。

----------

Zend Framework - Issue

手册非常详细,它还提到了许多其他内容,例如为不同的控制器(或操作)设置不同的布局。

答案 1 :(得分: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;
  }
}

Reference