4

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;
        $block->setTemplate($template);
        return $block->toHtml();
    }
}

Cache.xml:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <placeholders>
        <ajax_cart>
            <block>page/html_ajaxcart</block>
            <name>ajaxCart</name>
            <placeholder>AJAX_CART</placeholder>
            <container>Myname_Page_Model_Container_Ajaxcart</container>
            <cache_lifetime></cache_lifetime>
        </ajax_cart>
    </placeholders>
</config>

layout.xml:

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

template.phtml:

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

config file:

<?xml version="1.0"?>
<config>
    <modules>
        <Myname_Page>
            <version>0.1.0</version>
        </Myname_Page>
    </modules>
    <frontend>
        <routers>
            <page>
                <use>standard</use>
                <args>
                    <module>Myname_Page</module>
                    <frontName>page</frontName>
                </args>
            </page>
        </routers>
    </frontend>
    <global>
        <blocks>
            <page>
                <rewrite>
                    <html_ajaxcart>Myname_Page_Block_Html_Ajaxcart</html_ajaxcart>
                </rewrite>
            </page>
            <myname_page>
                <class>Myname_Page_Block</class>
            </myname_page>
        </blocks>
    </global>
</config>

block file:

<?php
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
        asort($items);

        // 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. – Fabian Schmengler Jul 22 '15 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. – easymoden00b Jul 22 '15 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. – Lee Saferite Jul 22 '15 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. – easymoden00b Jul 22 '15 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 Jul 23 '15 at 18:48
3
+50

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? – easymoden00b Jul 22 '15 at 12:13
1

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"?>

<config>
    <placeholders>
        <ajax_cart>
            <block>page/html_ajaxcart</block>
            <name>ajaxCart</name>
            <placeholder>AJAX_CART</placeholder>
            <template>page/html/ajaxCart.phtml</template> <!-- Your template file -->
            <container>Myname_Page_Model_Container_Ajaxcart</container>
            <cache_lifetime>false</cache_lifetime>
        </ajax_cart>
    </placeholders>
</config>

Try the above code it may work.

  • didn't do anything. – easymoden00b Jul 21 '15 at 20:50
  • Can you show your module config.XML file – MeenakshiSundaram R Jul 22 '15 at 1:47
  • i added the config file. – easymoden00b Jul 22 '15 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> – MeenakshiSundaram R Jul 22 '15 at 12:10

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.