Не уверен, почему это так сложно.Если я правильно пойму ЭТО , я смогу быстро достичь своих целей ... Но без радости.
Итак - я создаю свою первую тему и все еще разбираюсьмакет ...
Я специально работаю над страницей Catalog Product View
и преобразую эту страницу из макета правого столбца в макет левого столбца.Я просто хочу переместить блоки справа налево.
В файле catalog.xml по умолчанию определено product_list_related
:
</catalog_product_view>
//...
<reference name="right">
<block type="catalog/product_list_related" name="catalog.product.related" before="-" template="catalog/product/list/related.phtml"/>
</reference>
</catalog_product_view>
В моем файле local.xml я просто пытаюсь переместить этот блок:
<layout>
// bunch other page directives
<catalog_product_view>
<reference name="root">
<action method="setTemplate"><template>page/2columns-left.phtml</template></action>
</reference>
<reference name="right">
<action method="unsetChild"><name>catalog.product.related</name></action>
</reference>
<reference name="left">
<action method="insert"><blockName>catalog.product.related</blockName></action>
// note that that "catalog.leftnav" gets inserted as expected
<block type="catalog/layer_view" name="catalog.leftnav" after="-" template="catalog/layer/view.phtml"/>
</reference>
</catalog_product_view>
</layout>
Как уже отмечалось - вставка catalog.leftnav
работает как положено, поэтому я предполагаю, что все остальное настроено правильно.Целевой блок рендерится, как и ожидалось, если я оставлю шаблон и другие директивы без изменений, что говорит мне, что блок должен рендериться, как только его правильно установят и вставят ...
Это сводит меня с ума ... но чтоостальное новое с Magento.
Приветствия -
b [] x
UPDATE
Поскольку я просто не могу заставить работать local.xml
переопределение, я просто возвращаюсь к измененномуcatalog.xml
.Я довольно умный парень ... меня беспокоит то, что я не могу заставить это работать (и это magento просто молча терпит неудачу, в любом случае) - но я не могу больше тратить время на обсуждение этой глупой проблемы.
Продолжаем.
UPDATE, again.
Потратил некоторое время, работая в magento и знакомясь с его сложностями.Я вернулся к этой проблеме сегодня, так как мне нужно, чтобы мой local.xml работал правильно.
Я действительно не знаю, в чем я ошибся, но этот набор директив наконец сработал.
<reference name="right">
<action method="unsetChild">
<alias>catalog.product.related</alias>
</action>
</reference>
<reference name="left">
<action method="insert">
<block>catalog.product.related</block>
</action>
</reference>
Ключевой момент, который я запомню для других, имеющих дело с этим:
Директивы Layout xml вызывают доступные методы внутри классов magento.В этом случае блок Page.xmls "Left" имеет тип Mage_Core_Block_Text
, который наследуется от Mage_Core_Block_Abstract
, который содержит методы unsetChild
и insert
.
из Mage_Core_Block_Abstract
:
/**
* Unset child block
*
* @param string $alias
* @return Mage_Core_Block_Abstract
*/
public function unsetChild($alias)
{
if (isset($this->_children[$alias])) {
unset($this->_children[$alias]);
}
if (!empty($this->_sortedChildren)) {
$key = array_search($alias, $this->_sortedChildren);
if ($key !== false) {
unset($this->_sortedChildren[$key]);
}
}
return $this;
}
и
/**
* Insert child block
*
* @param Mage_Core_Block_Abstract|string $block
* @param string $siblingName
* @param boolean $after
* @param string $alias
* @return object $this
*/
public function insert($block, $siblingName = '', $after = false, $alias = '')
{
if (is_string($block)) {
$block = $this->getLayout()->getBlock($block);
}
if (!$block) {
/*
* if we don't have block - don't throw exception because
* block can simply removed using layout method remove
*/
//Mage::throwException(Mage::helper('core')->__('Invalid block name to set child %s: %s', $alias, $block));
return $this;
}
if ($block->getIsAnonymous()) {
$this->setChild('', $block);
$name = $block->getNameInLayout();
} elseif ('' != $alias) {
$this->setChild($alias, $block);
$name = $block->getNameInLayout();
} else {
$name = $block->getNameInLayout();
$this->setChild($name, $block);
}
if ($siblingName === '') {
if ($after) {
array_push($this->_sortedChildren, $name);
} else {
array_unshift($this->_sortedChildren, $name);
}
} else {
$key = array_search($siblingName, $this->_sortedChildren);
if (false !== $key) {
if ($after) {
$key++;
}
array_splice($this->_sortedChildren, $key, 0, $name);
} else {
if ($after) {
array_push($this->_sortedChildren, $name);
} else {
array_unshift($this->_sortedChildren, $name);
}
}
$this->_sortInstructions[$name] = array($siblingName, (bool)$after, false !== $key);
}
return $this;
}
Локальные xml-параметры важны не только по названию (конкретно), но и по порядку:
<reference name="left">
<action method="insert">
<block>catalog.product.related</block>
<siblingName>catalog.leftnav</siblingName>
<after>1</after>
<alias>catalog_product_related</alias>
</action>
</reference>
В конечном счете, это делает local.xml действительно мощным методом манипулирования системой, но если вы не знакомы с ней и системой magento, будьте готовы к неделям или месяцам работы, чтобы по-настоящему взбодриться.вокруг него.
Приветствия
Еще одно обновление
Я уже несколько раз сталкивался с проблемой, когда блок, который я хочу переместить, был удален.Это проблема, поскольку любой блок, который был удален из макета, обнуляется навсегда.
Однако, с очень удобным Alan Storm Unremove Plugin вы можете отменить то, что было сделано:
<checkout_onepage_index>
<x-unremove name="left" />
<reference name="right">
<action method="unsetChild">
<alias>checkout.progress.wrapper</alias>
</action>
</reference>
<reference name="left">
<action method="insert">
<block>checkout.progress.wrapper</block>
</action>
</reference>
</checkout_onepage_index>
Он управляет этим умением, наблюдая за объектом макета и создаваясписок удаленных блоков, на которые можно ссылаться позже.
Приятно!