2012-03-24 3 views
3

Я пытаюсь очистить пользовательский заполнитель из viewscript, скажем, у меня есть плагин контроллера, который создает боковую панель:Zend Framework - очистить пользовательский заполнитель из 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) { 
    } 
} 

Любая идея, как сделать такую ​​вещь?

Спасибо.

Edit:

Моя проблема была очень простой на самом деле, так как мой плагин был зарегистрирован и выполняется в методе postDispatch(), то мой viewscript был выполнен перед тем плагин и макет был выполнен после в плагин.

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

Я мог бы также использовать вспомогательный помощник , как вы думаете? Вопрос: already asked about it. Я все еще чувствую, что это не правильный способ сделать это, и это звучит слишком много.

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

Любая идея?

+0

Одна идея состоит в том, чтобы установить флаг, как '$ view-> isSidebarRenderable' и проверить его в макете перед визуализацией врезку. Неэлегантный, но должен работать. –

+0

Я думал об этом, но, как вы сказали, это кажется неэлегантным. Спасибо, что поделились своими мыслями :) –

+0

Действительно. Мне интересно, если кто-то еще придумает что-то более чистое. Ура! –

ответ

0

Вы были довольно близки на самом деле. Вам просто нужно было добавить имя вашего заполнителя, sidebar в этом случае:

$this->placeholder('sidebar')->exchangeArray(array()); должно работать.

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

EDIT:

Это странно, что выше не работает для вас. Я тестировал это на своем собственном веб-сайте 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

Он должен работать как 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); 
    } 
} 
+0

Я отредактировал мое сообщение, чтобы написать его правильно (я не копировал/не вставлял первый раз). Заметьте, что если бы я забыл параметр, я получил бы предупреждение. А также, если вы прочитаете весь мой вопрос, вы увидите, что 'Zend_Debug :: dump ($ placeholder);' ouputs en empty object. Спасибо за ваш ответ. –

+0

Хм, я удивлен, что это не сработало для вас. Это сработало для меня на одном из моих сайтов. Я добавил свой оригинальный ответ, который немного более многословен, но, я думаю, он может быть инкапсулирован. Это также может объяснить, почему вы получили пустой объект. – Gohn67

+0

Нашел свою проблему, я отредактировал свой вопрос. –