How to set different layouts for different modules in Zend Framework 3

℡╲_俬逩灬. 提交于 2019-12-25 09:18:44

问题


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?


回答1:




Zend Framework - Issue


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

        ]
    ]
];





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.





e.g.



Module/Namespace: Content,



Controller: Content\Controller\MatchMeController,(success!)

Controller: Other\Controller\DontMatchMeController,(fail!)



But there is a tiny drawback: setLayout() use



strpos(controller, __NAMESPACE__) === false



to identify current module, but what if I had a ContentController in some other module? So use



strpos(controller, __NAMESPACE__) !== 0



instead.




----------



Zend Framework - Issue



The manual is quite detailed, it also mentions lots of other things like set different layouts for different controllers (or actions).






回答2:


You can switch between layouts for a particular controller's action by using the following code:

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

  //...
}

In addition to the Layout controller plugin, there is the Layout view helper which provides the same capabilities. With the Layout view helper, you can, for example, switch layout from the "static" page which has no specific controller action.

Setting Layout for All Actions of a Controller

If all action methods of a controller class need to use the same alternative layout, you can override the onDispatch() method of the AbstractActionController class and call the setTemplate() method there, as shown in the example below:

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



来源:https://stackoverflow.com/questions/41181792/how-to-set-different-layouts-for-different-modules-in-zend-framework-3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!