Intially when the cache is cleared and I visit a page the block and corresponding template load perfectly. Then, when I revisit this page the block isn't loaded at all. Am I missing something in this hole punching process?

Model Container:

class Myname_Page_Model_Container_Ajaxcart extends Enterprise_PageCache_Model_Container_Abstract
    protected function _renderBlock()
        $blockClass = $this->_placeholder->getAttribute('block');
        $template = $this->_placeholder->getAttribute('template');

        $block = new $blockClass;
        return $block->toHtml();


<?xml version="1.0" encoding="UTF-8"?>


<block type="page/html_ajaxcart" name="ajaxCart" as="ajaxCart" template="page/html/ajaxCart.phtml"/>


<?php echo $this->getChildHtml('ajaxCart');?>

config file:

<?xml version="1.0"?>

block file:

class Myname_Page_Block_Html_Ajaxcart extends Mage_Core_Block_Template
    // sort quote by item date of addition
    public function sortByUpdatedAt($quote)
        // initialize item collection
        $items = array();
        $collection = $quote->getAllVisibleItems();

        // get updated at date for each item
        foreach ($collection as $item) {
            if (!$item->isDeleted()) {
                array_push($items, $item->getData('updated_at'));

        // sort and keep key association

        // reverse order and keep key association
        $k = array_reverse(array_keys($items));
        $reversed = array_reverse(array_values($items));
        $items = array_combine($k, $reversed);

        // collection is sorted
        $collection = $this->finishSort($items, $collection);
        return $collection;

    // sort collection by established ordering
    protected function finishSort($items, $collection)
        $sortedCollection = array();

        // collection will reflect sorted item array
        foreach ($items as $key => $value) {
            // get new order by established key value order
            array_push($sortedCollection, $collection[$key]);
        return $sortedCollection;

    public function getProductPrice($product)
        // return formatted special price
        if ($product->getSpecialPrice() != null && Mage::app()->getLocale()->isStoreDateInInterval(Mage::app()->getStore(), $product->getSpecialFromdate(), $product->getSpecialToDate())) {
            $price = $product->getSpecialPrice();
        } else {
            $price = $product->getPrice();
        // return formatted price
        return Mage::helper('core')->formatPrice($price, true);
  • Please show the block and template as well. You probably access data there that is only available within a normal request. Commented Jul 22, 2015 at 7:41
  • @fschmengler added the block. the only thing in the template file that is unusual is a few helper requests to manipulate Mage::getModel('checkout/cart')->getQuote() information. Commented Jul 22, 2015 at 12:11
  • 1
    I'll take this post as a chance to point out what I see as a huge flaw in FPC. It totally disables block level caching. If you have a heavy block, say your menu, it will have to be rendered fully for every page that it lives on. The final output is cached in FPC for that page, but every other page has to do it again. Commented Jul 22, 2015 at 12:58
  • @LeeSaferite Yea, there's a lot of things wrong with magento. Slightly off topic but i'm glad i'm getting out of developing for it and into embedded programming! Php is terrible in and of itself and when combined with magento (where there are like 5 different 'product' objects) the learning curve is mostly due to terrible documentation (essentially nonexistent) and core code base implementation. Commented Jul 22, 2015 at 14:26
  • @LeeSaferite interesting, any details on such? As I assumed that blocks drive FPC invalidation, and wouldn't interfere with block level caching. i.imgur.com/GwZNXRH.png
    – B00MER
    Commented Jul 23, 2015 at 18:48

2 Answers 2


I believe you are missing a implementation of _getCacheId & _saveCache

A cache_id is already defined if none is provided but is of anonymous naming convention. Define an ID for the block and reference it in your _getCacheId

Add a etc/cache.xml file with a <config> root to your module. (see Enterprise/PageCache/etc/cache.xml). Choose a unique [placeholder] name.

The placeholders/[placeholder]/block node value must match the class-id of your custom dynamic block, e.g. mymodule/custom

The placeholders/[placeholder]/container node value is the class to generate the content dynamically and handle block level caching

The placeholders/[placeholder]/placeholder node value is a unique string to mark the dynamic parts in the cached page

placeholders/[placeholder]/cache_lifetime use to be ignored, but not anymore. For older instances specify a block cache lifetime in the container’s _saveCache() method instead.

Implement the container class and extends Enterprise_PageCache_Model_Container_Abstract. Use _renderBlock() to return the dynamic content.

Implement the _getCacheId() method to return a unique string. Use cookie values instead of model ids (lower cost).

Implement _saveCache() to simply return, or pass a cache lifetime value to the parent method. Voila, dynamic block done.

One last note: You DON’T have the full Magento App at your disposal when _renderBlock() is called. Be as conservative as possible.

  • Where do I define the cache_id? Within _getcacheId? Anywhere else? Commented Jul 22, 2015 at 12:13

I think you have missed the <template> tag in the cache.xml file. But 'm not sure about this.

<?xml version="1.0" encoding="UTF-8"?>

            <template>page/html/ajaxCart.phtml</template> <!-- Your template file -->

Try the above code it may work.

  • didn't do anything. Commented Jul 21, 2015 at 20:50
  • Can you show your module config.XML file Commented Jul 22, 2015 at 1:47
  • i added the config file. Commented Jul 22, 2015 at 12:06
  • @easymoden00b you have rewrite the html_ajaxcar block. So can try to replace block with your block. (i.e.,) <block>myname_page/html_ajaxcart</block> Commented Jul 22, 2015 at 12:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.