views:

302

answers:

2

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?

A: 

The quickest solution might be to create a symlink to point what would be a module layout file to the default layout. This won't work on Windows and is harder to maintain.

Better, create a method in your Bootstrap to set the layout.

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{

    public function _initLayoutScript(){
        //ensure layout is setup
        $this->bootstrap(array('layout', 'FrontController'));

        $layout= $this->getResource('layout');

        $front = $this->getResource('FrontController');

        //do something with $layout and $front - set layout script/path etc based on request 
        //You could use file_exists to detect module layout scripts 

    }

}

See http://framework.zend.com/manual/en/zend.application.quick-start.html#zend.application.quick-start.resources for more details.

Finally, you could write your own application resource for use with Zend_Application.

David Caunt
A: 

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

SM