我正试图将一个块(按钮)添加到迷你购物车块:要么添加到name="cart_sidebar"
,要么最好添加到name="topCart.extra_actions"
,因为它会使其子块自动成为core/text_list
类型的
一切都很好,除了由于FPC生效,块没有在产品页面上被调用。我正在尝试从Enterprise_PageCache_Model_Container_Advanced_Quote
类扩展我的容器(也尝试过Enterprise_PageCache_Model_Container_Abstract
),但是没有调用_renderBlock
方法。
我的cache.xml似乎是正确有效的:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<placeholders>
<internationalcheckout_international>
<block>internationalcheckout/international</block>
<name>internationalcheckout_international</name>
<placeholder>INT_CHECKOUT</placeholder>
<container>GSX_InternationalCheckout_Model_Container_Button</container>
<cache_lifetime>84600</cache_lifetime>
</internationalcheckout_international>
</placeholders>
</config>
非常感谢任何帮助或提示
嵌套动态块您要做的是嵌套动态块,也就是说,动态迷你购物车块应该包含一个带有type=internationalcheckout/international
的嵌套动态块。
这不起作用,因为FPC处理器实现动态块(打孔)的方式。
protected function _processContainers(&$content)
{
$placeholders = array();
preg_match_all(
Enterprise_PageCache_Model_Container_Placeholder::HTML_NAME_PATTERN,
$content, $placeholders, PREG_PATTERN_ORDER
);
// ...
// ... if applyWithoutApp() on each placeholder then update content
// ... else prepare data for applyWithApp()
// ...
}
FPC处理流程
让我们一步一步地了解发生了什么。
首先,当调用_processContainers()
方法时,$content
包含缓存的页面,包括所有占位符标记。这也包括您定义的嵌套块。
第二个,该方法匹配所有占位符标记。在此之后,$placeholders
包括迷你购物车占位符,然后还包括您的嵌套占位符定义。
第三个,按顺序处理找到的占位符。这意味着迷你购物车占位符将在处理嵌套占位符之前进行处理,因为preg_match_all()
就是这样收集匹配项的。
第四个,迷你购物车容器被实例化。它依次实例化checkout/cart_sidebar
块,初始化渲染器并在其上调用toHtml()
第五个,将呈现checkout/cart/cartheader.phtml模板。当Magento到达呼叫时
<?php echo $this->getChildHtml('extra_actions') ?>
它不会为其呈现任何内容,因为在处理CCD_ 14和CCD_。
第六个,FPC处理器用迷你购物车容器返回的渲染内容替换由迷你购物车占位符标签标记的完整内容区域。$content
现在包含更新的迷你购物车html。
第七个,FPC容器尝试处理嵌套块的占位符。但是$content
不再包含它的占位符标记。它们已经通过用新生成的内容替换包装迷你购物车占位符而被删除!
摘要
当FPC处理内容时,不会加载布局XML,也不会实例化常规块层次结构
对于动态("打孔")块,子块的所有输出都将被删除,除非块实例本身或容器在没有加载布局XML的情况下负责实例化它们
在FPC处理页面内容的同时,加载布局XML并生成所有块在性能方面是个坏主意。
归根结底,topCart.extra_actions
容器块看起来是个好主意,但它与FPC不兼容:(
不能在动态块中使用子块。
要实现解决方法,您必须将块移动到cart_sidebar
块之外。
对于任何正在寻找extra_actions PayPal按钮解决方案的人,都有一个Magento补丁来修复它(SUPEE-87_1.12.0.0_v1.patch)。
由于它是一个Magento补丁,您只需打开文件"app/code/core/Enterprise/PageCache/Model/Containe/Sidebar/Cart.php",并在_renderBlock函数之后添加这两个函数,这正是补丁的作用:
/**
* Get Place Holder Block
*
* @return Mage_Core_Block_Abstract
*/
protected function _getPlaceHolderBlock()
{
$block = parent::_getPlaceHolderBlock();
$block->setChild('extra_actions', $this->_getExtraActionsChildBlock());
return $block;
}
/**
* Get child Block
*
* @return Mage_Core_Block_Abstract
*/
protected function _getExtraActionsChildBlock()
{
$paypalShortcutBlock = Mage::app()->getLayout()->createBlock('paypal/express_shortcut');
$paypalShortcutBlock->setTemplate('paypal/express/shortcut.phtml');
$paypalShortcutBlock->setLayout(Mage::app()->getLayout());
return $paypalShortcutBlock;
}
了解它的工作原理可以帮助解决其他类似的问题。
顺便说一句,谢谢Vinai,非常翔实的回答。