Мне нужно иметь возможность использовать разные макеты для разных категорий, выбранных на вкладке « Пользовательский дизайн » в поле «Категория» и « Макет страницы» .
Я использую 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 полон странного поведения и несоответствий, подобных этому 🙂