Zend Framework - очистить пользовательский заполнитель из сценария просмотра

Я пытаюсь очистить пользовательский заполнитель из сценария просмотра, скажем, у меня есть плагин контроллера, который создает боковую панель:

    $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 (), мой сценарий просмотра был выполнен до плагина, а макет был выполнен после плагин.

Какие у меня варианты с этого момента? На самом деле я не могу объявить свою боковую панель в методе preDispatch, потому что не будет установлен какой-либо каталог сценария, и поэтому я не смогу определить, какой сценарий представления выполнить на этом этапе.

Я мог бы также использовать помощника action(), как вы думаете? Вопрос уже уже задан. Я до сих пор считаю, что это неправильный способ сделать это, и для меня это звучит излишне.

Кроме того, еще одна идея - переместить мой плагин в метод preDispatch () моего контроллера, но это заставит меня скопировать / вставить на каждом контроллере мою боковую панель или создать baseController, но мне все еще не нравится эта идея. , Я чувствую, что делаю это неправильно.

Любая идея?


person Dr. Dre    schedule 24.03.2012    source источник
comment
Одна из идей - установить такой флаг, как $view->isSidebarRenderable, и проверить его в макете перед рендерингом боковой панели. Неэлегантно, но должно работать.   -  person David Weinraub    schedule 24.03.2012
comment
Я думал об этом, но, как вы сказали, он кажется неэлегантным. В любом случае спасибо за то, что поделились своими мыслями :)   -  person Dr. Dre    schedule 24.03.2012
comment
Верно. Мне интересно посмотреть, не придумает ли кто-нибудь что-нибудь более чистое. Ваше здоровье!   -  person David Weinraub    schedule 24.03.2012
comment
Нашел свою проблему, отредактировал свой вопрос. Но я все еще ищу лучшее решение для этого.   -  person Dr. Dre    schedule 25.03.2012


Ответы (1)


На самом деле вы были довольно близки. Вам просто нужно было добавить имя вашего заполнителя, в данном случае 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');

РЕДАКТИРОВАТЬ3

Он должен работать как Zend_Controller_Plugin с использованием хука preDispatch. Я думаю, вам нужно только убедиться, что вы заказываете этот плагин после того, как зададите пути сценария / помощника представления и пути макета. Это можно сделать в том же или другом плагине.

Вот пример кода, основанный на том, что я использую на своем веб-сайте. Соответствующая часть - это просто материал в 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);
    }
}
person Gohn67    schedule 24.03.2012
comment
Я отредактировал свой пост, чтобы написать его правильно (с первого раза не копировал / вставлял). Обратите внимание: если бы я забыл параметр, я бы получил предупреждение. Кроме того, если вы прочтете мой вопрос полностью, вы увидите, что Zend_Debug::dump($placeholder); выводит пустой объект. Спасибо за ответ. - person Dr. Dre; 25.03.2012
comment
Хм, я удивлен, что у тебя это не сработало. Это сработало для меня на одном из моих веб-сайтов. Я добавил свой исходный ответ, который более многословен, но, думаю, может быть инкапсулирован. Это также может объяснить, почему у вас пустой объект. - person Gohn67; 25.03.2012
comment
Да, я подумал, что может быть проблема. В любом случае я отредактировал свой вопрос примером того, как заранее установить пути просмотра, чтобы вы могли использовать свой заполнитель с помощью preDispatch. Я в значительной степени скопировал это напрямую, поэтому вам нужно будет внести некоторые корректировки в зависимости от ваших настроек. - person Gohn67; 25.03.2012