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

时间:2012-03-24 16:28:05

标签: php zend-framework placeholder zend-view zend-layout

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

    $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());重置/清除占位符,但似乎我无法从视图中访问我的占位符:

// 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在之前执行插件并且布局在之后执行 strong>插件。

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

我也可以使用action()助手,您怎么看?问题是already asked about it。我仍然觉得这不是正确的做法,这对我来说听起来有些过分。

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

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

你实际上非常接近。您只需要添加占位符的名称,在这种情况下为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);
    }
}