Magento – Disable Cache in CMS Page Using a Custom Module

cachecmsfull-page-cachemodule

I created a module which is an observer to listen to an event which is triggered on a CMS page and after listening to that disable the cache of the CMS page. My problem is how to have connection between module and CMS page.
I have a simple module which I downloaded from smashingmagazin website the structure is like the following:

app\code\local\SmashingMagazine\LogProductUpdate\etc\config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <SmashingMagazine_LogProductUpdate>
            <version>0.0.1</version>
        </SmashingMagazine_LogProductUpdate>
    </modules>
    <global>
        <models>
            <smashingmagazine_logproductupdate>
                <class>SmashingMagazine_LogProductUpdate_Model</class>
            </smashingmagazine_logproductupdate>
        </models>
        <events>

I have problem in here: what to write?I know that controller_action_predispatch is an event and it should be dispatched but I don't know if it is the right event to call in config.xml

<controller_action_predispatch>
                 <observers>
                 <page_cms_myid>
                <class>SmashingMagazine_LogProductUpdate_Model_Observer</class>
                <method>processPreDispatch</method>
                </page_cms_myid>
            </observers>
    </controller_action_predispatch>
            </events>
        </global>
    </config>

app\code\local\SmashingMagazine\LogProductUpdate\Model\observer.php

class SmashingMagazine_LogProductUpdate_Model_Observer
{
    Mage::log("test here");
public function processPreDispatch(Varien_Event_Observer $observer)
{
    $action = $observer->getEvent()->getControllerAction();

    // Check to see if $action is a CMScontroller
    if ($action instanceof Mage_Cms_PageController) {

$cache = Mage::app()->getCacheInstance();

        // Tell Magento to 'ban' the use of FPC for this request
        $cache->banUse('full_page');
    }
}
}

I want to add this module to the cms page so that the module can be loaded, this module doesn't have any phtml file or a block. do I need to create any?
I am doing it because with the help of friend I want to disable cache with this observer page

the module source can be downloaded at here.

I guess maybe I should update the layout of the cms page in design tab it should be something like:

<events>
        <observers>
            <page_cms_myid>
                <class>SmashingMagazine_LogProductUpdate_Model_Observer</class>
                <method>processPreDispatch</method>
            </page_cms_myid>
        </observers>
</events>

But It doesn't work,also I found these event cheat sheets:

enter image description here

so I changed config.xml again not worked:

  <events>
      <cms_page_prepare_save>
        <observers>
            <page_cms_myid>
                <class>SmashingMagazine_LogProductUpdate_Model_Observer</class>
                <method>processPreDispatch</method>
            </page_cms_myid>
        </observers>
    </cms_page_prepare_save>
        </events>

I also can have this function to write the dispatch event:

 Mage::dispatchEvent('cms_page_prepare_save', array('page' => $model, 'request' => $this->getRequest()));

but I don't know where to write it.
I know the following Information about my CMS page:

Controller Name:page
Action Name:view
Route Name:cms
Module Name:cms

Best Answer

At a glance, it seems that you are so close to the solution. So I just want to direct you in proper way.

About the event that you need to observe

Your are so confused about which magento event should observe. Everyone who works with magento development has this ambiguity in their mind for sure. So you dont have to have a feeling like "Oh God... I am trapped". :-)

Here is the scenario to find proper event. First you need to think about what should do via observer ? In this case, you need to disable cache. Next question is, when should magento processing cache ? The answer for this question is too broad and for now you should know that, magento will cache layout and blocks. So if we listen to an event which occurs after magento loading layout and blocks, then we are too late. We need to find an event which should occur before magento consider layouts.

Now if you think that you can observe to any event which happens before layout load, then you are again wrong. All of the event in magento is designed for managing different logic sides. That means purpose of each of the event in magento is different. You can alter/manage/add to that specific logic. So here comes other problem. You need to find an event which happens before loading layout and it will also allow to manage/edit/update magento cache system. This requirements leads us to controller_action_predispatch event.

The name of the above event says it all. It gives a clear hint that, the event is going to happen before dispatching the controller action. A controller action is the place where magento is used to load and render the layout. So at the point of magento processing this event, magento didnt touch the layout part. So our first requirement satisfies here. Now if you look on the definition of this event you can see that it holds Mage_Core_Controller_Front_Action instance.

#file : app/code/core/Mage/Core/Controller/Varien/Action.php

Mage::dispatchEvent('controller_action_predispatch', array('controller_action' => $this)); 

The advantage here is, Mage_Core_Controller_Varien_Action will allow you to get cache instance through it. This means, through an observent which listen to the above event, you have a chance to get the cache instance like this.

  $cache = $this->getControllerAction()->getCacheInstance();

But here is another problem. You want to disable cache on cms pages only. But you are observing to an event which will get called for every url request controller_action_predispatch. If possible, we should avoid it. Thankfully, magento gives some alternative methods which will reduce the scope of our observer. ie in your case you can also observe to controller_action_predispatch_cms. The advantage here is, magento will process this event only when if the requested page is a cms page. So according to me, this is the best event that you can observe.

So in your config.xml file, you need to use this.

Changes that you need to take care of

<frontend>
    <events>
        <controller_action_predispatch_cms>
            <observers>
                <cms_page_disabler><!-- this can be anything;only need to be unique -->
                    <class>smashingmagazine_logproductupdate/observer</class>
                    <method>processPreDispatch</method>
                </cms_page_disabler>
            </observers>
        </controller_action_predispatch_cms>
    </events>
</frontend>

and your observer should be

File : app\code\local\SmashingMagazine\LogProductUpdate\Model\Observer.php

class SmashingMagazine_LogProductUpdate_Model_Observer
{
    public function processPreDispatch(Varien_Event_Observer $observer)
    {
        $action = $observer->getEvent()->getControllerAction()->getFullActionName();

        // Check to see if $action is a CMScontroller
        if ($action == 'cms_page_view') {

            $cache = Mage::app()->getCacheInstance();

            // Tell Magento to 'ban' the use of FPC for this request
            $cache->banUse('full_page');
       }
   }
}

Here two things I need to point out. File name is Observer.php and not observer.php. Second thing is we are ensuring we are going to render a cms page. if condition is used for that.

Finally you need to ensure the activation file of your module should exist in your application.

File : app/etc/modules/SmashingMagazine_LogProductUpdate.xml

<config>
    <modules>
        <SmashingMagazine_LogProductUpdate>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Mage_Cms />
            </depends>
        </SmashingMagazine_LogProductUpdate>
    </modules>
</config>

PS : Also try to use controller_action_predispatch_cms_page_view. If this event is working for you, then go for it. It would be the best event for this scenario

Edit

I have tested this in my local machine and it works for me. You can get my extension here. Please try to use it.

Related Topic