I was looking into adding a layout specific to a certain module. It didn't work out as I planned, so I'm probably missing something. I have a possible solution, but I'm not confident that it's the way to do it.
Let's start by explaining what I did:
1/ I created a admin.phtml and default.phtml in the layouts/scripts directory
2/ I added following code in my application.ini :
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
resources.layout.layout = default
This loaded the default layout as I expected. So far so good, then I started to play:
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
resources.layout.layout = default
admin.resources.layout.layout = admin
=> loads the default layout
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
default.resources.layout.layout = default
admin.resources.layout.layout = admin
=> loads the admin layout (as it was defined last, it will overwrite the default one).
I ended using the second config with a default layout specified in the resource and then specific ones for the modules.
So I gathered that working this way I wasn't going to get anywhere. My second thought was to wirte a custom layout loader (_initLayout), but I realized there was no use, since I need access to the request to find out the current module name.
Then I decided to put it in a plugin. Cool, I have the module name there, I can access the layout, but... mmm... my application config is not readily available (ok, I could probably reload it, but I don't like that approach).
Finally I created a controller action helper, which I initialized from the default bootstrap:
protected function _initLayoutHelper()
{
$this->bootstrap('frontController');
$layout = Zend_Controller_Action_HelperBroker::addHelper(
new Amz_Controller_Action_Helper_Layout());
}
The helper itself is very straight forward (removed the comments to save space, it's very basic stuff):
class Amz_Controller_Action_Helper_LayoutLoader extends Zend_Controller_Action_Helper_Abstract
{
public function preDispatch()
{
$bootstrap = $this->getActionController()->getInvokeArg('bootstrap');
$config = $bootstrap->getOptions();
$module = $this->getRequest()->getModuleName();
if (isset($config[$module]['resources']['layout']['layout'])) {
$layoutScript = $config[$module]['resources']['layout']['layout'];
$this->getActionController()
->getHelper('layout')
->setLayout($layoutScript);
}
}
}
I have the layout changing based on module now, but I have some reservations. For instance: will the helper preDispatch be executed once or for every action (i.e. actionstack) ?
Is this the way to move how to do it, or do you guys do it in another way?
Thanks in advance for your feedback,
Wkr
Jeroen
没有评论:
发表评论