Pergunta

Alguém sabe por que o Magento gosta de carregar produtos quando é solicitado apenas a carregar o layout?

Estou apenas percorrendo alguns códigos Magento da versão 1.9.2.E eu escrevi um controlador com apenas:loadLayout e renderLayout.Então pensei que poderia mudar os blocos entre as duas funções, mas descobri que esse não é o caso para a maioria dos blocos 'principais'.Por exemplo, neste bloco, o preenchimento do cabeçalho HTML é feito se você disser:"carregarLayout".

Alguém tem experiência em remover blocos que já 'mudaram' o mundo global do Magento?

Por exemplo: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();
    }

Este é o meu teste:

<?php
include_once('../initMage.php');
initMage();

$controller = initController('Gn_Test_IndexController');
$product = Mage::getModel('catalog/product')->load(1);
Mage::register('product', $product);
$controller->loadLayout();
Foi útil?

Solução

Explicar isso na íntegra vai além de uma única resposta do Stack Exchange, o sistema de layout poderia preencher um pequeno livro (e Eu escrevi esse livro).

Resumindo - quando você liga loadLayout você está dizendo ao Magento

  1. Mesclar todos os arquivos de atualização XML de layout (app/design/area/theme/layout) em uma árvore
  2. Encontre as partes específicas dessa árvore para usar nesta solicitação
  3. Use essas partes específicas da árvore para determinar quais objetos de bloco instanciar e, em seguida, instanciar os objetos de bloco

É a última parte do item 3 que está impressionando você - quando o Magento instancia um bloco por meio do layout que ele chama _construct e e _prepareLayout no bloco.Esses métodos, por sua vez, geralmente fazem coisas como carregar uma coleção de produtos.

Para finalizar o acima, quando você ligar renderLayout você está dizendo ao Magento "chame o bloco raiz toHtml método, que renderiza o bloco raiz phtml modelo, que se espalha para o outro bloco phtml modelos por meio de getChildHtml (isso às vezes também aciona a instanciação direta e a renderização de outros objetos de bloco)

Alguém tem experiência em remover blocos que já 'mudaram' o mundo global do Magento?

Em geral, você provavelmente não quero fazer isso.Outros blocos e códigos podem depender do estado que você deseja alterar e removê-los pode causar erros fatais.

Se você realmente quiser fazer isso, eu analisaria os seguintes eventos

controller_action_layout_load_before
controller_action_layout_generate_xml_before
controller_action_layout_generate_blocks_before

e então modificar diretamente o layout e/ou objeto de atualização de layout (do observador passado) para remover o XML responsável pela criação do bloco que você deseja remover.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a magento.stackexchange
scroll top