I\'m trying to add a block (button) to mini cart block: either to name=\"cart_sidebar\"
or preferably name=\"topCart.extra_actions\"
as it renders it\'
To anyone looking for a solution to the extra_actions PayPal button, there is a Magento patch fixing it (SUPEE-87_1.12.0.0_v1.patch).
Since it's a Magento patch, you can simply open the file "app/code/core/Enterprise/PageCache/Model/Container/Sidebar/Cart.php" and add these 2 functions after the _renderBlock function, which is exactly what the patch does:
/**
* 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;
}
Understanding how this works can help for other similar problems.
Thanks Vinai by the way, very informative answer.
What you are attempting to do is nest dynamic blocks, that is the dynamic mini cart block should contain a nested dynamic block with type=internationalcheckout/international
.
This does not work because of the way the FPC processor implements dynamic blocks (holepunching).
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()
// ...
}
Lets go through step by step what happens.
First, when the _processContainers()
method is called, $content
contains the cached page, including all placeholder tags. This also includes the nested block you defined.
Second, the method matches all placeholder tags. After this $placeholders
includes the mini cart placeholder, and then also your nested placeholder definition.
Third, the found placeholders are processed in order. This means the mini cart placeholder will be processed before it processes the nested placeholder, because that is how preg_match_all()
collects the matches.
Fourth, the mini-cart container is instantiated. It in turn instantiates the checkout/cart_sidebar
block, initializes the renderers and calls toHtml()
on it.
Fifth, the checkout/cart/cartheader.phtml template is rendered. When Magento reaches the call
<?php echo $this->getChildHtml('extra_actions') ?>
it won't render any content for it because during the processing of applyWithoutApp()
and applyWithApp()
no child blocks exist.
Sixth, the FPC processor replaces the complete content area marked by the mini cart placeholder tags with the rendered content returned by the mini cart container. The $content
now contains the updated mini cart html.
Seventh, the FPC container attempts to process the placeholder of your nested block. But the $content
no longer contains the placeholder tags for it. They have been removed by replacing the wrapping mini cart placeholder with the new generated content!
When the FPC is processing the content, no layout XML is loaded, and the regular block hierarchy isn't instantiated.
For dynamic ("holepunched") blocks, all output from child blocks will be removed, unless the block instance itself or the container takes care of instantiating them without the layout XML being loaded.
It would be a bad idea performance wise to load the layout XML and generate all blocks while the FPC is processing page content.
What this boils down to is that the topCart.extra_actions
container block looks like a good idea, but it's not compatible with the FPC :(
You can't use child blocks within dynamic blocks.
To implement a workaround you will have to move your block outside of the cart_sidebar
block.