Zend Framework: route specific layouts
zend_layout, zend_controller_router, zend framework
I'm playing a bit with how I should organize my application. I don't want to put my admin controllers in a seperate module. This would provide problems when I want to have self-containing modules which contain a front and back-end part.
So, let's go a bit further into this: a module contains a number a controllers and actions. Some are open and others are protected. What better way to arrange this than by using Zend_Acl? For each module you specify the roles/privileges for the controllers and actions. You basically say what type of person can access what kind of functionality. I am still working this out in case you wanted to see the code, so no point in asking (yet).
Having a system to control the rights, we also need a system to display the admin and front-end correctly. Enter the Zend_Layout and routes...
I specified following routes in my main bootstrap (if anyone knows of a shorter way to do this in one line, please let me know):
public function _initAdminRoute() { $this->_bootstrap('frontController'); $front = $this->getResource('frontController'); $route = new Zend_Controller_Router_Route( 'admin/:module/:controller/:action/*', array('_layout' => 'admin')); $front->getRouter()->addRoute('admin_module_controller_action', $route); $route = new Zend_Controller_Router_Route( 'admin/:module/:controller', array('_layout' => 'admin')); $front->getRouter()->addRoute('admin_module_controller', $route); $route = new Zend_Controller_Router_Route( 'admin/:module', array('_layout' => 'admin')); $front->getRouter()->addRoute('admin_module', $route); $route = new Zend_Controller_Router_Route( 'admin', array('_layout' => 'admin')); $front->getRouter()->addRoute('admin', $route); }
I then created a plugin that would handle the layout change:
<?php class Amz_Controller_Plugin_Layout extends Zend_Controller_Plugin_Abstract { /** * Called before Zend_Controller_Front enters its dispatch loop. * * @param Zend_Controller_Request_Abstract $request * @return void */ public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request) { $layout_route = $request->getParam('_layout', null); $layout_param = $request->getParam('layout', $layout_route); if (!is_null($layout_param)) { Zend_Layout::getMvcInstance()->setLayout($layout_param); } } }
Why the layout and _layout params? Both are used for overriding the default layout. The "layout" param will be used for changing the layout trough the url (i.e. print layout, popup layout,...). The _layout param is for system internal layout changes like the one above. If I would have both called "layout", the system param would override the url entered param. This is not what I strived for.
To get the above plugin working you need to add following line to your application's config file:
resources.frontController.plugins.layout = Amz_Controller_Plugin_Layout
The front-end layout will implement the normal site's layout. The admin's layout will provide links to the main module's admin screens, but also to those defined by the module. I'm thinking of bootstrapping an admin zend_navigation object to do this where the modules add their links to. I haven't worked with Zend_Navigation yet, so I'm still working this out. I want the acl somehow to determine which links should be shown/added so that smart-asses who change the layout by the url don't see a thing they're not supposed to.






+32 475 62.42.64
JoeDevon
2009-06-21 18:59Haven't played w/ Routes in zf 1.8+ but I usually put them in configs/routes.ini which I think looks cleaner.