Не удается добавить дочерний блок в список продуктов
Я пытаюсь добавить блок в список продуктов:
<?xml version="1.0"?>
<layout version="0.1.0">
<catalog_category_view translate="label">
<reference name="product_list">
<remove name="product_list_toolbar"/>
<block type="core/template" name="helloworld" as="helloworld" template="helloworld.phtml"/>
</reference>
<reference name="footer">
<block type="core/template" name="helloworld" as="helloworld" template="helloworld.phtml"/>
</reference>
</catalog_category_view>
</layout>
В каталоге/продукте/списке.phtml У меня есть это:
<?php Zend_Debug::dump($this->getSortedChildren()); ?>
<?php echo $this->getChildHtml('helloworld'); ?>
В страница/html/нижний колонтитул.phtml У меня есть это:
<?php Zend_Debug::dump($this->getSortedChildren()); ?>
<?php echo $this->getChildHtml('helloworld'); ?>
Обратите внимание, что я добавил <remove name="product_list_toolbar"/>
только для того, чтобы проверить, правильно ли работает моя ссылка на product_list
, посмотрев, удален ли product_list_toolbar
из отсортированного списка дочерних элементов. Это.
Итак, теперь у меня есть идентичный код в списке продуктов и нижнем колонтитуле, и это работает только в нижнем колонтитуле. После некоторых поисков я не могу найти ни одного экземпляра блока, добавляемого в product_list
, кроме product_list_toolbar
. Итак, есть ли что-то в этом блоке, из-за чего добавление детей не работает?
3 answers
Проблема здесь заключается в порядке, в котором блоки указаны в XML-файле макета.
catalog_category_view
технически это правильный дескриптор, НО в этом дескрипторе блок product_list
не существует (пока!).
Блок product_list
создается только в дескрипторах catalog_category_default
и catalog_category_layered
. (И эти дескрипторы указываются позже в XML, чем catalog_category_view
.)
Короче говоря, когда весь XML-файл макета будет объединен, ваша ссылка на product_list
не будет выполнена, потому что она еще не существует точка.
Решение состоит в том, чтобы добавить свой блок как в catalog_category_default
, так и в catalog_category_layered
, ИЛИ создать свой собственный пользовательский дескриптор, добавить свой блок в этот дескриптор и использовать директиву <update>
для включения вашего дескриптора в catalog_category_default
и catalog_category_layered
.
Надеюсь, это сработало для вас.
Действительноcatalog_category_view
обрабатывается для каждой страницы просмотра категорий, и вы правильно выбрали дескриптор макета. Однако проблема здесь заключается в том, что нам нужно позаботиться о порядке обработки дескрипторов макета в magento.
В этом контексте, то есть для страницы просмотра списка товаров категории, дескрипторы макета обрабатываются в таком порядке (ссылка на magento-1.9.1)
0 => 'default'
1 = 'STORE_default'
2 => 'THEME_frontend_rwd_default'
3 => 'catalog_category_view'
4 => 'catalog_category_layered'
5 => 'CATEGORY_4'
6 => 'customer_logged_out'
7 => 'SHORTCUT_popup'
8 => 'SHORTCUT_uk_popup'
9 => 'product_list'
Это означает, что когда magento обрабатывает действие loadLayout
, он сначала рассмотрит default
сначала обработайте макет и включите блоки, определенные в этом дескрипторе макета, с помощью файлов обновления макета. Затем он обработает STORE_default
и так далее. Это означает, что catalog_category_view
дескриптор макета обрабатывается до catalog_category_default
или catalog_category_layered
. Это важный момент, который здесь следует отметить.
Magento определяет блок product_list
внутри дескриптора макета catalog_category_default
и catalog_category_layered
. Поскольку catalog_category_view
обрабатывается непосредственно перед этими двумя дескрипторами макета, блок product_list
, на который ссылается в вашем определении, является совершенно незнакомый и, следовательно, magento просто пренебрегает содержимым внутри него.
По поводу вашего комментария
Я думаю, вы неправильно это поняли. Существует два типа категорий, основанных на макете. Они
- категория по умолчанию
- многоуровневая категория
Magento добавит разные layout update handle
для этих двух типов категорий. Для default categories
он будет обрабатывать только catalog_category_default
. Для layered cateogries
, только процесс magento catalog_category_layered
. В обоих этих случаях magento определенно будет процесс action layout handle
catalog_category_view
и category specific layout handle
CATEGORY_{ID}
. т.е., короче говоря, action layout handle
будет обрабатываться для каждой страницы просмотра категорий. (дескриптор макета для конкретной категории будет отличаться для разных категорий.) Смотрите доказательство здесь
Файл : app/code/core/Mage/Catalog/Model/Category.php
public function getLayoutUpdateHandle()
{
$layout = 'catalog_category_';
if ($this->getIsAnchor()) {
$layout .= 'layered';
}
else {
$layout .= 'default';
}
return $layout;
}
См. catalog_category_layered
будет включено в обновление макета только в том случае, если для свойства категории isAnchor
установлено значение yes
(мы делаем это через администрацию.). В противном случае оно будет обработано catalog_category_default
Короче говоря : порядок, в котором макет дескрипторы обрабатываются в magento, в этом случае злодей и герой.
Я помещаю свою ссылку и обновление под дескриптор catalog_category_view
, однако блок product_list
определен под дескриптором catalog_category_default
. Похоже, что это должно каскадироваться и все еще работать, и я приглашаю кого-нибудь сказать мне, почему это не так. Но изменение дескриптора, используемого для этого обновления, устранило проблему.