В своей статье Блоки в Zend Framework я рассказал, как можно встраивать блоки в макет приложения на Zend Framework. Но, как оказалось, предложенный мною способ не является удобным - мы не можем управлять поведением блоков, то есть не можем включать их только для некоторых контроллеров. Это был огромный недостаток.
Но! Я хорошенько обмозговал все это дело и решил исправить ситуацию. Итак, представляю вам второй способ работы с блоками в ZF.
Конфиг блоков я оставил в том виде, в каком он был:
; Отдельные блоки на сайте, которые маппятся на контроллеры
; Блок: меню администратора
[toolbar]
module=application
controller=toolbar
action=index
; Блок: еще один блок
[someblock]
module=something
controller=something
action=something
Только убрал у блоков параметр supportXhr - теперь все блоки по-умолчанию не будут загружаться, если произошел AJAX запрос.
Дальше, пришлось написать для пущего удобства помощник действия (action helper) и отказаться от использования плагина фронт-контроллера (controller plugin). Это было сделано для того, чтобы можно было управлять поведением блоков из действий контроллера.
Помощник действия получился таким:
class Project_Controller_Action_Helper_Block extends Zend_Controller_Action_Helper_ActionStack
{
protected $_config = array();
protected function loadConfig()
{
$blocksConfig = new Zend_Config_Ini(APPLICATION_PATH . "/config/blocks.ini");
$this->_config = $blocksConfig->toArray();
}
public function dispatch($blockName)
{
if ($this->getRequest()->isXmlHttpRequest())
{
return;
}
if (empty($this->_config)) {
$this->loadConfig();
}
foreach ($this->_config as $name=>$options) {
if ($blockName == $name) {
$r = new Zend_Controller_Request_Simple;
$r->setModuleName($options['module'])
->setControllerName($options['controller'])
->setActionName($options['action'])
->setDispatched(false);
$this->pushStack($r);
}
}
}
}
Теперь мы можем загрузить блок прямо из действия контроллера таким образом:
$this->_helper->block->dispatch('toolbar');
Для сквозных блоков, то есть тех, которые есть на каждой странице сайта, рекомендую делать базовый контроллер для всех остальных контроллеров и в его методе preDispatch() загружать нужные блоки.
Кстати, нельзя сначала загрузить блок, а потом выгрузить его. Обратного пути нет. Блок можно только загрузить - обратное действие нелогично и неэффективно.
Кто-то может спросить - а зачем нужен конфиг блоков? Смысл конфига, в основном, заключается в систематизации - мы видим в одном месте, какие блоки у нас имеются на сайте. К тому же, код загрузки блока при помощи помощника действия уменьшился, так как мы указываем только имя блока. Еще один плюс - мы можем поменять значения модуля, контроллера и действия в одном месте. Считаю это удобным.
До скорого.
Also interesting
Tags: zend framework, zf action helper, Блоки в ZF
Спасибо, хорошая работа.
А каким образом можно определить очередность вывода блоков в методе preDispatch()?
Я имею в виду седующее: каким образом я могу вывести нужный мне блок, в скрипте вида, в нужном мне месте?!
Читайте финальную статью о блоках в ZF: http://torqueo.net/blocks-in-zend-framework-final-version/