为什么Magento1.9.2"loadLayout"开始加载产品?
-
13-12-2019 - |
题
有人知道为什么Magento喜欢在被要求只是加载布局时加载产品吗?
我只是从1.9.2走过一些Magento代码。我已经写了一个控制器:loadLayout en renderLayout.所以我认为我可以在两个函数之间更改块,但事实证明,对于大多数'核心'块来说,情况并非如此。例如,在这个块中,如果你说,填写HTML标题就完成了:"loadLayout"。
有没有人有删除已经"改变"全球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();
解决方案
在这个完整的解释超出了一个单一的堆栈交换答案,布局系统可以填补一本小书(和 我写了那本书).
总之--当你打电话的时候 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
然后直接修改布局和/或布局更新对象(来自传入的观察者)以删除负责创建要删除的块的XML。