Почему Magento 1.9.2 “loadLayout” начинает загружать продукты?
-
13-12-2019 - |
Вопрос
Кто-нибудь знает, почему Magento любит загружать продукты, когда его просят просто загрузить макет?
Я просто просматриваю некоторый код Magento из 1.9.2.И я написал контроллер с помощью всего лишь:loadLayout en renderLayout.Итак, я подумал, что мог бы менять блоки между двумя функциями, но оказалось, что это не относится к большинству "основных" блоков.Например, в этом блоке заполнение HTML-заголовка выполняется, если вы говорите:"Загрузочное описание".
Есть ли у кого-нибудь опыт удаления блоков, которые уже "изменили" глобальный мир Magento?
Например:Mage_Catalog_Block_Product_View
/**
* Retrieve current product model
*
* @return Mage_Catalog_Model_Product
*/
public function getProduct()
{
if (!Mage::registry('product') && $this->getProductId()) {
$product = Mage::getModel('catalog/product')->load($this->getProductId());
Mage::register('product', $product);
}
return Mage::registry('product');
}
/**
* Add meta information from product to head block
*
* @return Mage_Catalog_Block_Product_View
*/
protected function _prepareLayout()
{
$this->getLayout()->createBlock('catalog/breadcrumbs');
$headBlock = $this->getLayout()->getBlock('head');
if ($headBlock) {
$product = $this->getProduct();
$title = $product->getMetaTitle();
if ($title) {
$headBlock->setTitle($title);
}
$keyword = $product->getMetaKeyword();
$currentCategory = Mage::registry('current_category');
if ($keyword) {
$headBlock->setKeywords($keyword);
} elseif ($currentCategory) {
$headBlock->setKeywords($product->getName());
}
$description = $product->getMetaDescription();
if ($description) {
$headBlock->setDescription( ($description) );
} else {
$headBlock->setDescription(Mage::helper('core/string')->substr($product->getDescription(), 0, 255));
}
if ($this->helper('catalog/product')->canUseCanonicalTag()) {
$params = array('_ignore_category' => true);
$headBlock->addLinkRel('canonical', $product->getUrlModel()->getUrl($product, $params));
}
}
return parent::_prepareLayout();
}
Это мой тест.:
<?php
include_once('../initMage.php');
initMage();
$controller = initController('Gn_Test_IndexController');
$product = Mage::getModel('catalog/product')->load(1);
Mage::register('product', $product);
$controller->loadLayout();
Решение
Объяснение этого в полном объеме выходит за рамки одного ответа Stack Exchange, система верстки могла бы заполнить небольшую книгу (и Я написал эту книгу).
Короче говоря, когда вы звоните loadLayout
ты рассказываешь об этом Magento
- Объедините все файлы обновления XML макета (
app/design/area/theme/layout
) в одно дерево - Найдите конкретные части этого дерева для использования в этом запросе
- Используйте эти конкретные части дерева, чтобы определить, какие блочные объекты создавать, а затем создайте экземпляры блочных объектов
Это последняя часть # 3, которая бросает вас в глаза - когда Magento создает экземпляр блока с помощью макета, который он вызывает _construct
и и _prepareLayout
в квартале.Эти методы, в свою очередь, часто выполняют такие действия, как загрузка коллекции продуктов.
Чтобы закончить вышесказанное, когда вы позвоните renderLayout
вы говорите Magento: "вызовите корневой блок toHtml
метод, который отображает корневой блок phtml
шаблон, который переходит каскадом к шаблону другого блока phtml
шаблоны через getChildHtml
(это также иногда запускает прямое создание экземпляра и рендеринг других блочных объектов)
Есть ли у кого-нибудь опыт удаления блоков, которые уже "изменили" глобальный мир Magento?
В общем, вы вероятно не хочу этого делать.Другие блоки и код могут зависеть от того состояния, которое вы хотите изменить, и его удаление может привести к фатальным ошибкам.
Если вы в самом деле если бы я хотел это сделать, я бы изучил следующие события
controller_action_layout_load_before
controller_action_layout_generate_xml_before
controller_action_layout_generate_blocks_before
а затем непосредственно модифицируйте макет и / или объект обновления макета (из переданного в observer), чтобы удалить XML, ответственный за создание блока, который вы хотите удалить.