Search code examples
zend-frameworklayoutzend-layoutzend-application

Zend Layout - A "Smart" layout selector


I currently have Zend setup to look for a layout script in each module's view/scripts/layout.phtml file (ie: /application/modules/moduleName/scripts/layout.phtml). This is by setting layout[] to nothing (blank) in the application.ini file (resources.layout[] = )

The issue is that many modules may share the same layout. I don't want to copy the same exact layout into each module that uses it. I know I can set everything to use one layout script by setting a specific path like resources.layout.layoutpath = /layoutPath and everything would use /layoutpath/layout.phtml, and I know I can set individual pages (or whole Controllers, in the init) by using $this->_helper->layout->setLayout('foobaz');

The issue is that some modules will have different layouts, other than the 'standard' one, and I don't want to set it on a by Controller or by Action basis. I want to set it for the entire module, set in one place (or intuitively figured out by code/Zend automatically). Ideally, it would be setup how it is currently, but if a module doesn't have its own layout.phtml, it would use the default module's layout.

So... how do I do it?


Solution

  • There are several solutions, choose their own strategy

    1 extending the action controller

    class App_Controller_Action extends Zend_Controller_Action 
    {
    
        public function init()
        {
            parent::init();
    
            $moduleName = $this->getRequest()->getModuleName();
            $layoutPath = APPLICATION_PATH . '/modules/' . $moduleName . '/layouts';
            if (is_dir($layoutPath)) {
                $this->view->addScriptPath($layoutPath);
            }    
        }
     }
    

    and then do as usual IndexController extends App_Controller_Action ...
    if layout file exists in APPLICATION_PATH . '/modules/' . $moduleName . '/layouts' directory - it will ne used instead of default layout

    2 you can write frontcontroller plugin

    class App_Controller_Plugin_ModuleSwitcher extends Zend_Controller_Plugin_Abstract
     {
         protected $_view = null;
    
         public function routeShutdown(Zend_Controller_Request_Abstract $request)
         {
             $moduleName = $request->getModuleName();
    
             Zend_Layout::startMvc();
             $layout = Zend_Layout::getMvcInstance();
             $layout->setLayoutPath(APPLICATION_PATH . '/modules/' . $moduleName . '/layouts')->setLayout($moduleName);
    
             return $request;
         }
     }
    

    and dont forget to google for another solutions ;)