Zend Framework 2 – обтекание $ this-> контента другим макетом

Я пытаюсь создать обертку для $ this-> содержимого конкретного модуля.

У меня есть основной макет (все модули будут следовать этому макету), который строит базовый макет с верхними и нижними колонтитулами и т. Д. Они останутся неизменными во всех модулях.

Однако я хочу иметь модули с пользовательским макетом для их содержимого тела. Т.е. для пользовательских навигационных баров и т. Д.

Итак, со следующей структурой:

module / ModuleName / view / layout / modulelayout.phtml / modulename / index / index.phtml view / layout / layout.phtml 

/view/layout/layout.phtml:

 <?= $this->doctype(); ?> <html lang="en"> <head> ... </head> <body> <header>...</header> <div id='body'> <?= $this->content; ?> </div> <footer>...</footer> </body> </html> 

/module/ModuleName/view/layout/modulelayout.phtml:

 <div>...</div> <div> <?= $this->content; ?> </div> 

/module/ModuleName/view/modulename/index/index.phtml:

 Hello World ... 

Поэтому я хочу, чтобы все действия внутри ModuleName (их $ this-> контент, который отображается), были обернуты макетом из modulelayout.phtml.

Я создал слушателя в событии отправки контроллера для его захвата для всех действий контроллера:

 public function onBootstrap($e) { $app = $e->getApplication(); $app->getEventManager() ->getSharedManager() ->attach('Zend\Mvc\Controller\AbstractActionController', 'dispatch', array($this, 'dispatchControllerStrategy')); } 

Теперь мне нужно знать, как сохранить базовый макет, и добавить модуль в качестве обертки?

 public function dispatchControllerStrategy($e) { $controller = $e->getTarget(); $layout = $controller->layout(); $wrapper = new ViewModel(); $wrapper->setTemplate('layout/modulelayout'); $layout->addChild($wrapper, 'content'); } 

^^^ Добавление дочернего макета, похоже, каким-либо образом не переносит $ this-> content, а дочерний макет не отображает. Чтобы собрать все это вместе, я ожидаю, что окончательный источник будет выглядеть следующим образом:

 <!DOCTYPE html> <html lang="en"> <head> ... </head> <body> <header>...</header> <div id='body'> <div>...</div> <div> Hello World ... </div> </div> <footer>...</footer> </body> </html> 

Благодаря!

Ну, после долгих беспорядков, я наконец нашел свое решение. И похоже, что комментарий SlmThreeStepView user2257808 был тем, с чего я хотел начать, но мое решение соответствовало моей потребности именно так, я просто собираюсь поделиться им здесь:

Я перестал беспокоиться о попытке изменить макет диспетчера диспетчеризации и сосредоточиться на представлении с событием EVENT_RENDERER_POST:

 ->attach('Zend\View\View', \Zend\View\ViewEvent::EVENT_RENDERER_POST, array($this, 'renderViewStrategy')); 

Затем я изменяю свою модель на рендеринг:

 private $renderdedOuterView = false; public function renderViewStrategy($e) { if ($this->renderdedOuterView) { return; } else { $this->renderdedOuterView = true; } $layout = $e->getModel(); $children = $layout->getChildren(); $layout->clearChildren(); $wrapper = new ViewModel(); $wrapper->setTemplate('layout/modulelayout'); $wrapper->addChild($children[0], 'content'); $layout->addChild($wrapper, 'content'); } 

Я использовал $ renderedOuterView только для модификации рендеринга основного макета.

Затем для основного макета я получаю модель и хватаю присоединенного ребенка, который будет макетом для текущего действия.

Затем я очищаю основной шаблон этого ребенка и добавляю свою упаковку на свое место. Затем, как дочерний элемент моей оболочки, я добавляю макет для текущего действия, которое я только что удалил из основного шаблона.

Я не лучший вариант, но это решение подходит именно к тому, что я пытался выполнить с моим вопросом.

ОБНОВИТЬ

Я хотел добавить, что я обнаружил еще одну проблему. Все onBootstraps для каждого модуля вызываются, независимо от того, являются ли они активным модулем.

Это привело к тому, что другой модуль получил этот макет. Это изменение включало сначала EVENT_DISPATCH:

 $evtMgr = $e->getApplication()->getEventManager(); $evtMgr->attach(MvcEvent::EVENT_DISPATCH, array($this, 'handleEventStrategy')); 

Затем внутри handleEventStrategy я проверяю, что активный модуль является загрузочным модулем модуля, который вызывается. Если это так, я присоединяю EVENT_RENDER_POST и использую renderViewStrategy, который я определил.

Если активный модуль не является модулем с стратегией просмотра рендеринга, условие if завершится неудачно, и ни один другой модуль не получит этот измененный макет.

Вы пробовали этот модуль: https://github.com/EvanDotPro/EdpModuleLayouts

Затем добавьте конфигурацию в конфигурационный файл модуля

 array( 'module_layouts' => array( 'ModuleName' => 'layout/some-layout', ), );