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 ?
  • 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 Nov 25 '13 at 6:48
  • it's 2015 and I'm having the same problem :D did you ever solve? – Ricky Odin Matthews Sep 11 '15 at 12:36
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;
    }
}
  • 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 ? – Curious Explorer Sep 26 '13 at 7:50
  • Why do you need to override applyInApp as the one from the parent will do all the same? – Foo Bar Mar 10 '16 at 6:46
  • @TimBezhashvyly it has changed dramatically in the past 3 years. – philwinkle Mar 10 '16 at 17:04
  • So let's improve your answer. – Foo Bar Mar 10 '16 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
    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 May 26 '16 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 – user3040610 Sep 11 '17 at 17:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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