Intereting Posts
Требуется регулярное выражение для соответствия нескольким строкам, пока не будет найдено совпадение между общими разделителями Использовать подготовленные заявления повсюду в PHP? (ПДО) Отображение данных диаграммы из базы данных var_dump и simpleXML? Выполнение выбора и обновления в одном запросе PDO с несколькими именованными заполнителями не извлекает данные Вход с помощью PHP curl и токена CSRF Как заставить загружать большие файлы, не используя слишком много памяти? php – как изменить iframe разные src каждые 5 секунд множественный префикс с той же группой маршрутов Использование одного параметра несколько раз в подготовленном mysqli-statement Получить определенный элемент из каждого вспомогательного массива Как перенаправить на другую страницу через 5 минут? Динамические изображения для электронной почты, такие как обратные часы (в свете кеширования изображений в Gmail) Вызов статического метода из имени строки в PHP

Пользовательские макеты для каталога_category_view на Magento

Мне нужно иметь возможность использовать разные макеты для разных категорий, выбранных на вкладке « Пользовательский дизайн » в поле «Категория» и « Макет страницы» .

Я использую Magento 1.9.1.0.

В моем config.xml у меня есть:

<global> <page> <layouts> <module_home module="page" translate="label"> <label>Module Home</label> <template>page/base.phtml</template> <layout_handle>module_home</layout_handle> </module_home> <module_categories module="page" translate="label"> <label>Module Categories</label> <template>page/base.phtml</template> <layout_handle>module_categories</layout_handle> </module_categories> </layouts> </page> ... 

И в моем файле layouts.xml меня есть:

 <default> <reference name="root">...</reference> </default> <module_home translate="label">...</module_home> <module_categories translate="label">...</module_categories> по <default> <reference name="root">...</reference> </default> <module_home translate="label">...</module_home> <module_categories translate="label">...</module_categories> по <default> <reference name="root">...</reference> </default> <module_home translate="label">...</module_home> <module_categories translate="label">...</module_categories> 

Когда я выбираю макет категорий модулей из администратора категории, я не получаю изменений для обработчика module_categories , только те, которые установлены на <default> .

Если я заставлю его так:

 <catalog_category_view> <update handle="module_categories" /> </catalog_category_view> 

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

Может быть, я делаю что-то не так? Не удалось найти пример, как это сделать, может быть, вы можете указать где-нибудь? Благодаря!

У вас есть правильная идея с директивой <update /> . Просто добавьте его в поле « Custom Layout Update в вашей категории, и эта категория должна применить этот макет. Вы все равно можете установить шаблон Page Layout поле « Page Layout .

Причина, по которой вам необходимо явно указать дескриптор макета с директивой <update /> состоит в том, что контроллер категории Magento не использует узел layout_handle , тогда как другие части Magento, такие как контроллер страницы CMS Magento, используют его.

Например, давайте посмотрим на Mage_Cms_PageController , который отвечает за отображение страницы CMS:

 public function viewAction() { $pageId = $this->getRequest() ->getParam('page_id', $this->getRequest()->getParam('id', false)); if (!Mage::helper('cms/page')->renderPage($this, $pageId)) { $this->_forward('noRoute'); } } 

Давайте Mage_Cms_Helper_Page::renderPage() и посмотрим на Mage_Cms_Helper_Page::renderPage() , который вызывает Mage_Cms_Helper_Page::_renderPage() :

 protected function _renderPage(Mage_Core_Controller_Varien_Action $action, $pageId = null, $renderLayout = true) { $page = Mage::getSingleton('cms/page'); /* ... */ if ($page->getRootTemplate()) { $handle = ($page->getCustomRootTemplate() && $page->getCustomRootTemplate() != 'empty' && $inRange) ? $page->getCustomRootTemplate() : $page->getRootTemplate(); $action->getLayout()->helper('page/layout')->applyHandle($handle); } /* ... */ if ($page->getRootTemplate()) { $action->getLayout()->helper('page/layout') ->applyTemplate($page->getRootTemplate()); } /* ... */ } 

Здесь мы видим две важные части логики.

Во-первых, _renderPage() вызывает $action->getLayout()->helper('page/layout')->applyHandle($handle) . Если вы копаете еще глубже, вы увидите, что Mage_Page_Helper_Layout::applyHandle() отвечает за применение соответствующего layout_handle как определено конфигурацией XML:

 public function applyHandle($pageLayout) { $pageLayout = $this->_getConfig()->getPageLayout($pageLayout); if (!$pageLayout) { return $this; } $this->getLayout() ->getUpdate() ->addHandle($pageLayout->getLayoutHandle()); return $this; } 

Во-вторых, _renderPage() вызывает $action->getLayout()->helper('page/layout')->applyTemplate($page->getRootTemplate()) . Подобно applyHandle() , applyTemplate() применяет фактический шаблон страницы.

Таким образом, это объясняет, почему вы можете зависеть от layout_handle как определено в XML конфигурации, когда речь идет о CMS-страницах. Теперь давайте выясним, почему он не зависит от категорий.

Давайте посмотрим на Mage_Catalog_CategoryController::viewAction() , который отвечает за отображение страницы категории:

 public function viewAction() { if ($category = $this->_initCatagory()) { $design = Mage::getSingleton('catalog/design'); $settings = $design->getDesignSettings($category); /* ... */ // apply custom layout update once layout is loaded if ($layoutUpdates = $settings->getLayoutUpdates()) { if (is_array($layoutUpdates)) { foreach($layoutUpdates as $layoutUpdate) { $update->addUpdate($layoutUpdate); } } } /* ... */ // apply custom layout (page) template once the blocks are generated if ($settings->getPageLayout()) { $this->getLayout()->helper('page/layout')->applyTemplate($settings->getPageLayout()); } /* ... */ } elseif (!$this->getResponse()->isRedirect()) { $this->_forward('noRoute'); } } 

Устраняя всю логику компоновки по умолчанию, у нас осталось две части:

  // apply custom layout update once layout is loaded if ($layoutUpdates = $settings->getLayoutUpdates()) { if (is_array($layoutUpdates)) { foreach($layoutUpdates as $layoutUpdate) { $update->addUpdate($layoutUpdate); } } } 

Это проходит через обновления макета категории (как определено в поле « Custom Layout Update в админе) и применяет их. Вот почему работает <update handle="some_handle" /> .

А также…

  // apply custom layout (page) template once the blocks are generated if ($settings->getPageLayout()) { $this->getLayout()->helper('page/layout')->applyTemplate($settings->getPageLayout()); } 

Это применимо к шаблону пользовательской страницы, аналогичному тому, как это сделала логика страницы CMS, используя Mage_Page_Helper_Layout::applyTemplate() .

Теперь заметите что-то не хватает?

Yup, контроллер категории не вызывает Mage_Page_Helper_Layout::applyHandle() чтобы применить layout_handle как определено в XML конфигурации. Это означает, что вы можете использовать поле « Page Layout чтобы присвоить категории конкретный шаблон страницы, но ваш layout_update который сопровождает шаблон, не будет применяться!

Надеюсь, что это очистит, почему ваш узел layout_update не используется на странице категории так, как вы ожидали. Magento полон странного поведения и несоответствий, подобных этому 🙂