In this article I will show you how set up module specific layouts. Many people find it confusing that module resources like layouts are always loaded, regardless of the module requested.

The reason for this is that at the time of bootstrap, the request is not yet determined and the application does not know what module was requested. To set up resources like layouts, databases, translations etc. for specific modules ONLY when that module is requested, your best bet is a front controller plugin or action helper.

Usage example

Default layout settings in application.ini:

resources.layout.layout = "default"
resources.layout.layoutPath = APPLICATION_PATH "/views/layouts"

Then, if you use my ModuleSetup resource as described in module config, you can set the module layout options in the module.ini for that module:

resources.layout.layout = "modulename_default"

; this layoutpath is relative to the directory of the module itself
; in this case: application/modules/modulename/views/layouts
resources.layout.layoutPath = "views/layouts"

or, you can set the module config in your application.ini normally, as described in the Zend Framework reference:

modulename.resources.layout.layout = "modulename_default"

; this layoutpath is relative to the directory of the module itself
; in this case: application/modules/modulename/views/layouts
modulename.resources.layout.layoutPath = "views/layouts"

note: you can set all options for module layouts sources the same way as for the application layout resource. If you don’t specify a different layoutPath, the standard path is used.

The result is that when the module ‘modulename’ is requested, the layout modulename_default.phtml in the directory application/modules/modulename/views/layouts is used. Otherwise, the main layout is used.

Code

class Rexus_Controller_Plugin_RequestedModuleLayoutLoader
    extends Zend_Controller_plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $config     = Zend_Controller_Front::getInstance()
                            ->getParam('bootstrap')->getOptions();

        $moduleName = $request->getModuleName();

        if (isset($config[$moduleName]['resources']['layout']['layout'])) {
            $layoutScript = $config[$moduleName]['resources']['layout']['layout'];
            Zend_Layout::getMvcInstance()->setLayout($layoutScript);
        }

        if (isset($config[$moduleName]['resources']['layout']['layoutPath'])) {
            $layoutPath = $config[$moduleName]['resources']['layout']['layoutPath'];
            $moduleDir = Zend_Controller_Front::getInstance()->getModuleDirectory();
            Zend_Layout::getMvcInstance()->setLayoutPath(
                $moduleDir. DIRECTORY_SEPARATOR .$layoutPath
            );
        }
    }
}

To use this, drop the class above in your library and set the following in your application.ini:

resources.frontController.plugins.layoutloader = Rexus_Controller_Plugin_RequestedModuleLayoutLoader

If you want to know more about handling other types of resources with modules, check my post about module translation sources