Я пытаюсь создать обертку для $ 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', ), );