Zend Framework-从视图脚本中清除自定义占位符


Zend Framework - clear a custom placeholder from a viewscript

我正试图从视图脚本中清除一个自定义占位符,假设我有一个控制器插件,可以创建一个侧边栏:

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

我的分部包含我的子菜单(通过Zend_Navigation视图辅助对象渲染)。

为了呈现侧边栏,我的布局中有以下内容:

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

但是,如果在某些页面中我不想显示侧边栏(例如登录页面),该怎么办?我该如何处理这些案件?

我想我可以使用$this->placeholder('sidebar')->exchangeArray(array());重置/清除占位符,但似乎无法从viewscript访问占位符:

// 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) {
  }
}

知道怎么做这样的事吗?

谢谢。

编辑:

事实上,我的问题很简单,因为我的插件是在postDispatch()方法中注册和执行的,然后我的viewscript在插件之前执行,布局在插件之后执行。

从现在开始,我有什么选择?我真的不能在preDispatch方法中声明我的侧边栏,因为不会有任何脚本目录集,因此我无法确定在这一步执行哪个视图脚本。

我也可以使用action()助手,你觉得怎么样?已经有人问过这个问题了。我仍然觉得这不是正确的方法,对我来说这听起来有些过头了。

此外,另一个想法是将我的插件移动到我的控制器的preDispatch()方法中,但这会导致我在每个控制器上复制/粘贴我的侧边栏,或者创建一个baseController,但我仍然不喜欢这个想法,我觉得我做错了。

知道吗?

实际上你已经很接近了。您只需要添加占位符的名称,在本例中为sidebar

$this->placeholder('sidebar')->exchangeArray(array());应该起作用。

请参阅http://framework.zend.com/manual/en/zend.view.helpers.html#zend.view.helpers.initial.placeholder

编辑:

奇怪的是,上面的内容对你不起作用。我在自己的ZF网站上进行了测试,结果成功了。可能是不同的情况。我不知道。

这是另一种选择,尽管涉及更多。

//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

它应该使用preDispatch钩子作为Zend_Controller_Plugin工作。我认为你唯一需要确保的是,在设置了视图脚本/助手路径和布局路径后,你就可以订购该插件。这可以在同一个插件或另一个插件中完成。

这是一个基于我在网站上使用的东西的代码示例。相关部分只是preDispatch中的内容,我在其中设置了视图脚本路径等

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);
    }
}