I'm working with a copy of Magento 1.4EE which has Extendware FPC installed. I'm trying to get breadcrumbs working properly for products that are within more than one category. This is my first time working with Extendware, and I've worked out how the hole punching works for my breadcrumbs block, but it seems that hole punching only applies to the secondary cache, yet the site only uses the primary cache when a user is not logged in.

My question is how can I hole-punch or make sure that my breadcrumbs are always dynamic, even when the user is not logged in?

Help appreciated!

2 Answers 2


While this is specific for an extension (that comes with good documentation and very prompt support I might add), I'll get you in the right direction.

There's a footer widget you can enable that adds some information about the decisions the cache makes. Consult that and the documentation to see why it thinks it can use the primary cache. The decision is among other things based on variables and cookies as well as layout handles marked dynamic.


Hi last month i happened to work with an extendware issue on hole punching. I am just writing down few things which i learned by experience. Might be useful to somebody using extendware full page cache.

EXTENDWARE HOLE punching for the Full page cache:

What is hole punching:

Hole punching is an advanced technique, but really a very simple technique to not cache certain blocks or elements of your page which is otherwise cached using Full page cache(FPC) and loaded instantly. There are two ways you can do the hole punching

  1. Full block hole.

  2. Inline hole. (Sometimes you do not want to replace a whole block or a block is not capable of being easily marked as a hole punch. In this scenario, you will need to create an inline hole punch and manually mark the beginning and end of the hole punched content.)


Without hole punching:

  1. First time page loads every block in the page is created and cached.
  2. When the same page is loaded for the second time only the cached content gets displayed.Any condition based content (like dynamic or session) content(For example: recently viewed products , customers on wish list etc) that can change during the next page loading is not reflected.

With hole punching:

  1. First time page loads every block in the page is created and cached.
  2. Second time, the page loads from cache, but the elements inside the inline hole alone gets created from the extendware block class in app/code/local/Extendware/EWPageCache/Model/Injector/ replacing all the elements inside the inline hole.


For example: If you want to just alter the random value in your page each time the page is loaded, 

  1. Marking the boundaries of the content with the getBeginMarker and getEndMarker tags with the injector key specified
> <?php if (class_exists('Extendware') &&
> Extendware::helper('ewpagecache') !== false) echo
> Mage::helper('ewpagecache')->getBeginMarker(‘random'); ?>   <li><?php
> echo rand(); ?></li> <?php if (class_exists('Extendware') &&
> Extendware::helper('ewpagecache') !== false) echo
> Mage::helper('ewpagecache')->getEndMarker(‘random'); ?>

Extendware->ManageExtensions->PageCache->Advanced->Injectors/holepunches->Add injector  

a. Blockkey is the block type found in the layout.xml b. Injectorkey is the path to the injector class. for example Injectorkey value of “Checkout_cart_sidebar” represents that the corresponding class resides in


  1. Add the Injector class


> class Extendware_EWPageCache_Model_Injector_Wishlist_Heart_Icon
> extends Extendware_EWPageCache_Model_Injector_Abstract {
>     public function getInjection(array $params = array(), array $request = array()) {
>         return rand();
>     } }

Note: If you do not create the injector at the right file location with the right class name, then the injector will not do anything.

ta da! you have now created a hole successfully in your page.

How it works

When the page loads it creates the content from inline block 

  • < /li> and during the second time of loading of the page the other page content is cached but only the block inside the boundaries is generated from return rand();

    Real time magento example:

    The requirement was depending on the condition for if isProductInCustomerWishlist (i.e.., if the product is in the customers wishlist) different content has to be rendered in the page. So when the page loads for the first time the content will be rendered from

  • getChildHtml('product.view.wishlist.icon'); ?>
  • and other part of the page would be cached. For the second time the content would be rendered from cache except for the block which will be rendered from the getInjection() method.


    <?php if (class_exists('Extendware') && Extendware::helper('ewpagecache') !== false) echo Mage::helper('ewpagecache')->getBeginMarker('wishlist_heart_icon'); ?>
        <li><?php echo $this->getChildHtml('product.view.wishlist.icon'); ?></li>
    <?php if (class_exists('Extendware') && Extendware::helper('ewpagecache') !== false) echo Mage::helper('ewpagecache')->getEndMarker('wishlist_heart_icon'); ?>
    class Extendware_EWPageCache_Model_Injector_Wishlist_Heart_Icon extends Extendware_EWPageCache_Model_Injector_Abstract
        public function getInjection(array $params = array(), array $request = array()) {
            $product_id = $request['params']['id'];
            $product = Mage::getModel('catalog/product')->load($product_id);
            $block = Mage::app()->getLayout()->getBlockSingleton('catalog/product_view_media')
            return  $block->toHtml();
        $_product = $this->getProduct();
        $_wishlistSubmitUrl = $this->helper('wishlist')->getAddUrl($_product);
        $customerWishlistHelper = Mage::helper('mynamespace_wishlist');
        $isProductInCustomerWishlist = $customerWishlistHelper->isInCustomerWishlist($_product->getId());
        if ($isProductInCustomerWishlist){
        <div class="link-wishlist product-action">
            <i class="fa fa-heart icon"></i>
            <span class="wished-txt"><?php echo $this->__('Wished') ?></span>
        <a href="<?php echo $_wishlistSubmitUrl ?>" onclick="productAddToCartForm.submitLight(this, this.href); return false;" class="link-wishlist product-action">
          <i class="fa fa-heart-o icon"></i>
          <span><?php echo $this->__('Wishlist') ?></span>


    Hole punching for full blocks:

    Similarly for the whole block to be hole punched its more simpler , just add the injector in the extender configuration giving the correct block name (type from layout.xml) and create the injector class in the path specified by the corresponding injector key . So the block will be replaced by the value returned from the injector class.

    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.