I am building a Zend Framework MVC application and am having difficultly configuring my Zend_Layout.

Firstly, my application resources are all in resource plugins which are loaded in bootstrap with the following code:

protected function _initResourcePlugins() {

    $this->registerPluginResource('Log');        
    $this->registerPluginResource('Router'); 
    $this->registerPluginResource('Db');        
    $this->registerPluginResource('View');
}

I have not created a resource plugin for my Layout because I am handling login/logout in a front controller plugin and my layout configuration depends on whether the user is logged in or not (and other context-related information). I am kicking the layout in to life with the following lines in my application.ini:

resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/professional"
resources.layout.layout = "ver1"

Then I use a front controller plugin to configure it. Here's the plugin:

public function postDispatch(\Zend_Controller_Request_Abstract $request) {

    $layout = Zend_Layout::getMvcInstance();        
    $path   = $layout->getLayoutPath();

    // include static content
    $layout->header = include($path . '/includes/header.phtml');
    $layout->footer = include($path . '/includes/footer.phtml');

    if(APPLICATION_ENV == 'development') {
        $layout->dev    = include($path . '/includes/dev.phtml');                    
    }

    if(RW_Helper::isLoggedIn()) {
        $layout->sidebar = include($path . '/includes/sbar_secure.phtml');                    
    } else {
        $layout->sidebar = include($path . '/includes/sbar_public_login.phtml');            
    }
}

(I know its not particularly pretty but I'll deal with that later).

Now, the problem is that the only event I can run this on is the postDispatch event. If I try to run it on, say, dispatchLoopStartup, I get an error such as "Warning: UiWidgetElement decorator cannot render without a registered view object in ..."

I'm not sure which view object it is looking for. (Are there separate ones for the Layout and the Application view?) And I'm not sure where/how I should be injecting it or providing it. If it's chasing the view that I set up as a resource, I would have thought it could find it easily enough by consulting the bootstrap...

I don't really want to leave the Layout attached to the postDispatch event because a) it doesn't feel semantically correct, and b) I risk executing it more than once (if I execute multiple actions in a request).

What am I missing?

Thanks!

有帮助吗?

解决方案

From the look of the code it's trying to access to the view object from the view renderer. This gets initialised automatically postDispatch, so that's why your code only works as a postDispatch hook.

I think part of the pain you are experiencing is because you are trying mix application and presentation logic by trying to render templates during the dispatch process. You said in your question that your plugin code wasn't particularly pretty but you can easily simplify this and solve your issue at the same time.

I'd suggest removing this plugin completely, and then rendering these templates from within the layout itself, e.g.:

<?=$this->render('includes/header.phtml')?>

The login check you could either to in the layout in the same way or move this to a view helper. Since the view object will have already been setup, this should fix your problem.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top