Zend Framework - clear custom placeholder from viewcript

I'm trying to clear a custom placeholder from a viewcript, let's say I have a controller plugin that creates a sidebar:

    $bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');
    $view = $bootstrap->getResource('view');
    $partial = $view->render('partials/_sidebar.phtml');
    $view->placeholder('sidebar')->append($partial);

      

My part contains my submenu (displayed via the Zend_Navigation view helper).

To display this sidebar, I have this in my layout:

<?= $this->placeholder('sidebar'); ?>

      

But what if on some pages I don't want to display the sidebar (like the login page)? How can I handle these cases?

I thought I could reset / clear my placeholder using $this->placeholder('sidebar')->exchangeArray(array());

, but it seems that I cannot access my placeholder from viewcript:

// in /application/modules/default/views/account/login.phtml
<?php $placeholder = $this->placeholder('sidebar');
Zend_Debug::dump($placeholder); ?>

// output:

object(Zend_View_Helper_Placeholder_Container)#217 (8) {
  ["_prefix":protected] => string(0) ""
  ["_postfix":protected] => string(0) ""
  ["_separator":protected] => string(0) ""
  ["_indent":protected] => string(0) ""
  ["_captureLock":protected] => bool(false)
  ["_captureType":protected] => NULL
  ["_captureKey":protected] => NULL
  ["storage":"ArrayObject":private] => array(0) {
  }
}

      

Any idea how to do this?

Thank.

Edit:

My problem was very simple actually, since my plugin was registered and executed in the postDispatch () method, then my viewcript was executed before the plugin, and the layout was executed after the plugin.

From now on, what are my options? I am unable to declare the sidebar in the preDispatch method because there will be no set of script directories and therefore I cannot determine what kind of script to execute in this step.

I could also use a helper action()

, what do you think? The question has already been about this . I still feel that this is not the right way to do it, and it sounds too much to me.

Also, another idea would be to move my plugin into the preDispatch () method of my controller, but that would lead me to copy / paste my sidebar to each controller, or create a baseController, but I still don't like this idea, i feel like i'm doing it wrong.

Any idea?

+3


source to share


1 answer


You were pretty close actually. You just needed to add the name of your placeholder, sidebar

in this case:

$this->placeholder('sidebar')->exchangeArray(array());

must work.

See http://framework.zend.com/manual/en/zend.view.helpers.html#zend.view.helpers.initial.placeholder

EDIT:

It's weird that the above didn't work for you. I tested this on my own ZF website and it worked. Perhaps another scenario. I dont know.

Here's another alternative, albeit a more attractive one.



//Get the placeholder object directly
$placeholderObj = $this->getHelper('placeholder')

//This may be why you were getting null in your example above. Since your were using the magic method in the View class to call the placeholder view helper method directly.

//For example you could call the placeholder like so:
$placeholderObj->placeholder('sidebar')->set("Some value");

//Now the alternative way to remove the placeholder value is as follows.
$registry = $placeholderObj->getRegistry()
$registry->deleteContainer('sidebar');

      

EDIT3

It should work like Zend_Controller_Plugin using the preDispatch hook. I think you only need to make sure you order this plugin after setting the view script / helper paths and layout paths. This can be done in the same plugin or in a different plugin.

Here is some sample code based on what I am using in my website. The relevant part is just stuff in the preDispatch where I set the view script paths etc.

class RT_Theme extends Zend_Controller_Plugin_Abstract
{
    private $_sitename;
    private $_assets;
    private $_appPath;
    private $_appLibrary;

    /**
     * Constructor
     * 
     * @param string $sitename
     * @param SM_Assets $assets
     * @param string $appPath
     * @param string $appLibrary
     */
    public function __construct($sitename, $assets, $appPath, $appLibrary)
    {
        $this->_sitename = $sitename;
        $this->_assets = $assets;
        $this->_appPath = $appPath;
        $this->_appLibrary = $appLibrary;
    }

    /**
     * Sets up theme
     * 
     * Sets up theme template directory and assets locations (js, css, images)
     * 
     * @param Zend_Controller_Request_Abstract $request
     */
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $module = $request->getModuleName();
        $controller = $request->getControllerName();
        $action = $request->getActionName();

        $layout = Zend_Layout::getMvcInstance();
        $view = $layout->getView();

        $view->sitename = $this->_sitename;
        $view->headTitle()->setSeparator(' - ')->headTitle($view->sitename);

        $layout->setLayoutPath($this->_appPath . "/html/$module/layout/");

        $view->setScriptPath($this->_appPath . "/html/$module/view/");
        $view->addScriptPath($this->_appPath . "/html/$module/view/_partials/");

        $view->addScriptPath($this->_appLibrary . '/RT/View/Partials/');
        $view->addHelperPath('RT/View/Helper', 'RT_View_Helper');

        $view->addHelperPath($this->_appPath . '/html/view/helpers','My_View_Helper');

        $viewRenderer =
            Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
        $viewRenderer->setView($view); 


        //Ignore this line. Not relevant to the question                 
        $this->_assets->loadFor($controller, $action);

        //Example: Now I can set the placeholder.
        $view->placeholder('header_title')->set($view->sitename);
    }
}

      

0


source







All Articles