4

Scenario:

I have category landing page, in which another vendor has customized to add "Purchased" text instead of "Add to cart" in case the user has purchased it, hence this will be different for each user.

All iz well till now, until we turned on "The" FPC.

While I understand Holepunching a little better now I had this plan:

My Plan:

  1. We keep rest code in list.phtml as the same.
  2. I just cut the logic of the showing of the "Add To Cart" or "Purchased" and put it in another phtml.
  3. I would add this new block as the child of catalog/product/list block in the catalog.xml with this new phtml.
  4. Have a container model responsible for the _renderBlock. We say _saveCache false for this block and it would not be cached.

Question / Difficulties

  • I am not really aware of the exact implementation for this plan.
  • For step 4 what should be the implementation of _renderBlock like ?
  • How whould I get the productobject inside this phtml ? as The list.phtml works on the productCollection and we just loop over this and get product object. now, how does one get the project object now in the child block ?
  • I need a few pointers on how this can be done best. while I read about a product view page holepunch method I am not exactly sure how to do this for category page.
  • If nothing works I just want FPC to not cache the list block at all , but again not sure how to disable caching for only this block ?
2
  • 1
    if any of these answers solves your problem please accept it, or post the solution by yourself and mark it accepted, So that it will be helpful for somebody in future
    – zamil
    Commented Nov 25, 2013 at 6:48
  • it's 2015 and I'm having the same problem :D did you ever solve? Commented Sep 11, 2015 at 12:36

2 Answers 2

5

So the real question is - is the output of this "Purchased" text coming from a block? Or are you incorporating it in the phtml as logic?

The answer should be that it's coming from a Block. The reasoning is that Magento implements the hole punch via the block output. To do this is very simple:

  • Create a cache.xml file in the etc directory of your module
  • Create the page cachebust Container block

etc/cache.xml

<?xml version="1.0"?>
<config>
    <placeholders>
        <purchased_button>
            <block>purchased/button</block>
            <template>checkout/button.phtml</template>
            <name>product.info.addtocart</name><!-- THIS MUST MATCH THE ALIAS IN THE LAYOUT XML EXACTLY -->
            <placeholder>PURCHASED_BUTTON_TEXT</placeholder>
            <container>YourCompany_YourModule_Model_Container_Purchased</container>
            <cache_lifetime>86400</cache_lifetime>
        </purchased_button>
    </placeholders>
</config>

Model/Container/Purchased.php

<?php

class YourModule_YourCompany_Model_Container_Purchased extends Enterprise_PageCache_Model_Container_Abstract
{

    protected function _getCacheId()
    {
    return 'PURCHASED_BUTTON_TEXT_' . md5($_COOKIE["frontend"]);
    }

    public function applyInApp(&$content)
    {
        $block = $this->_getPlaceHolderBlock();

        $blockContent = $block->toHtml();

        $this->_applyToContent($content, $blockContent);

        return true;
    }

    protected function _saveCache($data, $id, $tags = array(), $lifetime = null)
    {
        return false;
    }
}
4
  • The way I understand it is that I would need 2 things to render this block separately (without the rest of magento getting initialized) The product id and the customer id, lets say I get the customer id from session. Still how do I get the product id or object ? Commented Sep 26, 2013 at 7:50
  • Why do you need to override applyInApp as the one from the parent will do all the same? Commented Mar 10, 2016 at 6:46
  • @TimBezhashvyly it has changed dramatically in the past 3 years.
    – philwinkle
    Commented Mar 10, 2016 at 17:04
  • So let's improve your answer. Commented Mar 10, 2016 at 20:07
3

You need to holepunch your block - as in @philwinkle's answer. Your block also needs to implement the getCacheKeyInfo method. This method should return any variables you might need in your _renderBlock method of your PageCache container:

public function getCacheKeyInfo() {
    $info = parent::getCacheKeyInfo();
    $info['myvariable'] = "hello"; //can be a product id, etc.
    return $info;
}

then, in your _renderBlock method you can access those variables like:

protected function _renderBlock()
{
    //...

    $myvariable = $this->_placeholder->getAttribute('myvariable');

    //...
}

Also, your cache_lifetime in cache.xml should be null so that it doesn't get cached I would imagine.

2
  • 2
    This was the problem that plagued me. I had a CMS page with a {{widget}} embedded in it but I couldn't read my parameters. I completely missed the specifying keys to the getCacheKeyInfo array when defining my block. After reading this, I was able to keep moving.
    – Brett
    Commented May 26, 2016 at 14:02
  • I dont have the _renderBlock() in my block file and i need to get the myvariable in another block class or the function Commented Sep 11, 2017 at 17:05

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.