Блоки в Zend Framework, версия 2

В своей статье Блоки в 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: , ,

3 Responses to “Блоки в Zend Framework, версия 2”

  1. helloamigo says:

    Спасибо, хорошая работа.
    А каким образом можно определить очередность вывода блоков в методе preDispatch()?

    • helloamigo says:

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

  2. Ouch! says:

    Читайте финальную статью о блоках в ZF: http://torqueo.net/blocks-in-zend-framework-final-version/

Leave a Reply