Magento – Disable Full Page Cache of Widget+Banner Blocks

full-page-cachemagento-enterprise

I have setup a custom module and block with a very short Full Page Cache lifetime. Inside that block I am calling Banners (an Enterprise feature.) These Banners are returned the first time the Full Page Cache is created, but not when it's refreshed a few seconds later.

How can I get the output of Banner blocks (powered by Widgets) to not cache. (See the bottom of this page for more details on the current outcome of the following code.)

app/code/local/Mycompany/FpcBlocks/etc/config.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Mycompany_FpcBlocks>
            <version>0.1.0</version>
        </Mycompany_FpcBlocks>
    </modules>
    <frontend>
        <layout>
            <updates>
                <fpcblocks>
                    <file>mycompany_fpcblocks.xml</file>
                </fpcblocks>
            </updates>
        </layout>
    </frontend>
    <global>
        <models>
            <fpcblocks>
                <class>Mycompany_FpcBlocks_Model</class>
            </fpcblocks>
        </models>
        <blocks>
            <fpcblocks>
                <class>Mycompany_FpcBlocks_Block</class>
            </fpcblocks>
        </blocks>
        <helpers>
            <fpcblocks>
                <class>Mycompany_FpcBlocks_Helper</class>
            </fpcblocks>
        </helpers>
    </global>
</config>

app/code/local/Mycompany/FpcBlocks/etc/cache.xml

<?xml version="1.0"?>
<config>
    <placeholders>
        <mycompany_fpcblocks>
            <block>fpcblocks/homepage</block>
            <name>mycompany.fpc.homepage</name>
            <placeholder>MYCOMPANY_FPCBLOCKS_HOMEPAGE_CACHE</placeholder>
            <container>Mycompany_FpcBlocks_Model_Container_Homepage</container>
            <cache_lifetime>3</cache_lifetime>
        </mycompany_fpcblocks>
    </placeholders>
</config>

app/code/local/Mycompany/FpcBlocks/Helper/Data.php

<?php
class Mycompany_FpcBlocks_Helper_Data extends Mage_Core_Helper_Abstract {}

app/code/local/Mycompany/FpcBlocks/Model/Container/Homepage.php

<?php

class Mycompany_FpcBlocks_Model_Container_Homepage extends Enterprise_PageCache_Model_Container_Abstract
{
    protected function _getCacheId()
    {
        return 'MYCOMPANY_FPCBLOCKS_HOMEPAGE_CACHE' . md5($this->_placeholder->getAttribute('cache_id')) . '_' . $this->_getCookieValue(Enterprise_PageCache_Model_Cookie::COOKIE_CUSTOMER, '');
    }

    protected function _renderBlock()
    {
        $blockClass = $this->_placeholder->getAttribute('block');;
        $template = $this->_placeholder->getAttribute('template');

        /** @var Mycompany_FpcBlocks_Block_Homepage $block */
        $block = new $blockClass;
        $block->setTemplate($template);

        return $block->toHtml();
    }
}

app/code/local/Mycompany/FpcBlocks/Block/Homepage.php

<?php

class Mycompany_FpcBlocks_Block_Homepage extends Mage_Core_Block_Template
{
    protected function _construct()
    {
        $this->setTemplate('mycompany_fpcblocks/homepage.phtml');
    }

    public function getDate()
    {
        return date('F d Y, h:i:s a');
    }
}

app/design/frontend/mytheme/default/layout/page.xmlInside default/root

<block type="fpcblocks/homepage" name="mycompany.fpc.homepage">
    <label>Mycompany FPC - Homepage</label>
    <block type="core/text_list" name="banner_block_1" as="banner_block_1">
        <label>Homepage Banner</label>
    </block>
</block>

app/design/frontend/mytheme/default/template/mycompany_fpcblocks/homepage.php

<?php
echo '<pre>';
echo 'This block was generated on '.$this->getDate()."\n";
var_dump(htmlspecialchars(trim($this->getChildHtml('banner_block_1', false))));
echo '</pre>';

The current result:

  • Without Full Page Cache turned on, this outputs the correct time, and the content of the banner.
  • Right after turning Full Page Cache on, this still outputs the correct time, and the content of the banner.
  • After refreshing the page once, (technically I think this is after the 3 seconds from cache.xml) this still outputs the correct time (IE: it doesn't get cached) but now the call to $this->getChildHtml('banner_block_1') comes back blank.

Notes:

I've gone into core_layout_update and found the XML for this banner, and manually added this inside the <block> tag:

<action method="unsetData"><key>cache_lifetime</key></action>
<action method="unsetData"><key>cache_tags</key></action>

This has no affect.

Best Answer

First of all you need to keep in mind that when you are in FPC cached page, the block is not getting created via layout. So first time when FPC page gets popuplated getChildHtml() returns you a correct block, but second time, it will not instantiate it, since Layout XML is not applied at all on cached response.

Any block you are referring to within FPC scope, should be created manually without using layout xml, so you can re-use it even, when layout is not available.

As far as I know, banners already FPC compatible, you should take a look into: Enterprise_PageCache_Model_Container_Banner

Related Topic