有人知道为什么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

  1. 合并所有布局XML更新文件(app/design/area/theme/layout 成一棵树
  2. 查找要用于此请求的树的特定部分
  3. 使用树的那些特定部分来确定要实例化哪些块对象,然后实例化这些块对象

这是#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。

许可以下: CC-BY-SA归因
scroll top