Issues

ZF-6537: Disabling Zend_Layout does not work correctly when ActionStack used.

Issue Type: Bug Created: 2009-05-05T04:32:53.000+0000 Last Updated: 2012-11-20T20:53:32.000+0000 Status: Closed Fix version(s): Reporter: Mark (lightflowmark) Assignee: None Tags: - Zend_Layout

Related issues: Attachments:

Description

This is partly a Zend_Layout issue and partly a problem with ViewRenderer helper, I think.

Suppose one is using Zend_Layout with the ActionStack, as recommended in the docs, and the stack is set up at dispatchLoopStartup (which seems like the right place for it). Content from these actions is assigned to response segments using $this->_helper->viewRenderer->setResponseSegment('someSegment'), in order that it can be rendered in the correct place by Zend_Layout.

I want to disable the layout in one of my actions; however, when I do so (using $this->getHelper('layout')->disableLayout()) , any actions previously called by the ActionStack are then appended to the body - there are no layout placeholders (as layout is disabled), and so these items are simply tagged on to the main body. This is not, I believe, appropriate behaviour.

Psuedo-code may clarify:

<pre class="highlight">
  function dispatchLoopStartup
  {
            $actionStack = $front->getPlugin('Zend_Controller_Plugin_ActionStack');
            $menuAction = clone($request);
            $menuAction->setActionName('menu')
                    ->setControllerName('my_controller');
            $actionStack->pushStack($menuAction);
  }



<pre class="highlight">
  function menuAction
  {
     // stuff ...
     // menu viewscript renders like 

menu item 1, menu item 2

     $this->_helper->viewRenderer->setResponseSegment('menu');
  }

  function withLayoutAction
  {
     // stuff ...
     // withLayout viewscript renders like 

some with-layout text

  }

  function noLayoutAction
  {
     $this->getHelper('layout')->disableLayout();
     // stuff
     // noLayout viewscript renders like 

Some no-layout stuff here

  }


<pre class="highlight">

Menu

<?= $this->layout()->menu ?>

Main Content

<?= $this->layout()->content ?>

If I go to my_controller/withLayout, I get the menu and withLayout div rendered at the layout placeholders as you'd expect, no problem. If I go to my_controller/noLayout, I the full output is:

Some no-layout stuff here

menu item 1, menu item 2

The content from menuAction is simply appended to the content from noLayoutAction, which is exactly not what I want!

One workaround is rather than disable the layout, to use a layout template with only the 'content' placeholder:

<pre class="highlight">
<?= $this->layout()->content ?>

and then, rather than disabling the layout, change layout script in the controller action

<pre class="highlight">
function noLayoutAction
{
  $this->getHelper('layout')->setLayout('no-layout');
} 

This implies to me that a possible fix would be to never actually disable Zend_Layout, but instead force it to use a basic layout template as above; to rewrite disableLayout:

<pre class="highlight">
public function disableLayout()
{
  $this->setLayout('no-layout');
  $this->_enabled = false;
  return($this);
}

Comments

Posted by Mark (lightflowmark) on 2009-05-05T04:50:32.000+0000

Markup edit for readability.

Posted by Matthew Weier O'Phinney (matthew) on 2009-05-05T06:46:02.000+0000

Assigning to Ralph

Posted by julien PAULI (doctorrock83) on 2009-05-13T11:39:53.000+0000

Yeah, good one. This is because the response object sticks all its body segments together when outputed, and the layout , when activated pulls them from the response. When the layout is disabled, the segment is not pulled out from the response object, so it gets rendered.

A quick patch could be (Plugin/Layout)

<pre class="highlight">
if (!$layout->isEnabled()) {
            if (Zend_Controller_Front::getInstance()->getParam('noViewRenderer') == false && !Zend_Controller_Action_HelperBroker::hasHelper('viewRenderer')) {
                return;
            }
            $segment = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer')->getResponseSegment();
            if ($segment != null) {
                $response = $this->getResponse();
                $response->setBody('', $segment);
            }
            return;
        }

Posted by Rob Allen (rob) on 2012-11-20T20:53:32.000+0000

Bulk change of all issues last updated before 1st January 2010 as "Won't Fix".

Feel free to re-open and provide a patch if you want to fix this issue.

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts