Вы правильно поняли директиву <update />
. Просто поместите его в поле Custom Layout Update
вашей категории в панели администратора, и эта категория должна применить этот дескриптор макета. Вы все еще можете установить шаблон страницы с полем Page Layout
.
Причина, по которой вам нужно явно указать дескриптор макета с помощью директивы <update />
, заключается в том, что контроллер категорий Magento не использует узел layout_handle
, тогда как другие части Magento, такие как контроллер страниц Magento CMS, используют его.
Например, давайте посмотрим на 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()
:
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()
.
Теперь заметили, что чего-то не хватает?
Да, контроллер категории не вызывает Mage_Page_Helper_Layout::applyHandle()
для применения layout_handle
, как определено в XML конфигурации. Это означает, что вы можете использовать поле Page Layout
для присвоения категории определенного шаблона страницы, но ваш layout_update
, сопровождающий шаблон, не будет применен!
Надеюсь, это прояснит, почему ваш узел layout_update
не используется на странице категории так, как вы ожидаете. Magento полон странного поведения и подобных несоответствий :)
person
Agop
schedule
31.01.2015