Magento – Disable FPC for controller

controllersfull-page-cacheholepunching

So normally when implementing FPC we'll holepunch certain blocks out that have dynamic data. What I can't seem to figure out, is there not a way to holepunch a url. So for example if we have /index/index with the following:

class Namespace_Module_IndexController extends Mage_Core_Controller_Front_Action
{
    public function indexAction()
    {
        $jsonArray = array('time'=>time());
        $response = Mage::helper('core')->jsonEncode($jsonArray);
        $this->getResponse()->setBody($response);
    }
}

Obviously with FPC enabled we'll always get the same JSON. Is there a way to holepunch a URL so that we can just always return up to date times? (Obviously I'm not using Magento just to return times, but it's a good example of dynamic data)

One alternative I can think of is to just create a block that will house the json through maybe a text block or something, but I was wondering if there was some way to do this without actually constructing a block. (Theoretically version shouldn't matter? But if it does let's say EE 1.13)

Best Answer

You'll need to define a container and a placeholder in your module.

Model/Pagecache/Container.php

class Namespace_Module_Model_Pagecache_Container extends Enterprise_PageCache_Model_Container_Abstract
{
    /**
     * Get container individual cache id
     *
     * Override to return false to cause the block to never get cached
     *
     * @return string
     */
    protected function _getCacheId()
    {
        return false;
    }

    /**
     * Render block content
     *
     * @return string
     */
    protected function _renderBlock()
    {
        $block = $this->_placeholder->getAttribute('block');
        $block = new $block;

        // only needed if the block uses a template
        $block->setTemplate($this->_placeholder->getAttribute('template'));

        return $block->toHtml();
    }

    /**
     * Generate placeholder content before application was initialized and
     * apply to page content if possible
     *
     * Override to enforce calling {@see _renderBlock()}
     *
     * @param string &$content The content
     *
     * @return bool
     */
    public function applyWithoutApp(&$content)
    {
        return false;
    }
}

etc/cache.xml

<config>
    <placeholders>
        <namespace_module>
            <block>namespace_module/something</block>
            <placeholder>NAMESPACE_MODULE_UNIQUE_STRING</placeholder>
            <container>Namespace_Module_Model_Pagecache_Container</container>
            <cache_lifetime>86400</cache_lifetime>
        </namespace_module>
    </placeholders>
</config>

Be sure and read over Vinai's details on how the FPC works:

Boilerplate container and placeholder code from:

Related Topic