Tag Archives: Controller Override

Magento CMS controller override / cms page controller override in magento

Whoops !! what Magento’s bad ? Ofcourse documentation. Bullshit documentation !!. Magento have features but without documentation !!!!

Magento cms module has some nice functionality. Using Magento’s 404 event handlers of cms module you can integrate 3rd Party CMS Content such Expression Engine, Drupal, wordpress, joomla etc within Magento.
Magento is robust and have some great nice features but still their documentation is very poor. In Magento forum and wiki they just demonstrate “how to override a controller?” as a general theory. But how to override exceptional cms and api controller is not clear. Even Magento did not mention anything about exceptionality of cms and api module. Cms module calls internally. So we cannot override cms module’s controller using as usual magento controller override process. Here I described how to overrite cms index and page controller.

Target : Override Cms module’s Index (Mage_Cms_IndexController) controller and Page (Mage_Cms_IndexController) controller.

Hint: IndexController is responsible for displaying errors (404) & home page and PageController is responsible for displaying pages like ‘about-us’, keep this in mind as you may want to rewrite which controller.

Ok, let’s start—

Firsty, it’s wise to name your module differently to avoid name collisions. Lets call my module M4U_Mycms for that case.

<?xml version="1.0"?>
<config>
    <modules>
        <M4U_Mycms>
            <active>true</active>
            <codePool>local</codePool>
        </M4U_Mycms>
    </modules>
</config>

Now create config xml for new module in app/code/local/M4U/Mycms/etc/config.xml. Here as example I mention xml to override norouteAction method of IndexController.

<?xml version="1.0"?>
<config>

    <modules>
        <M4U_Mycms>
            <version>0.1.0</version>
        </ M4U_Mycms>
    </modules>
   
    <frontend>
        <routers>
            <mycms>
                <use>standard</use>
                <args>
                    <module> M4U_Mycms</module>
                    <frontName>mycms</frontName>
                </args>
            </mycms>
        </routers>
</frontend>	
	
<global>
     <routers>
            <cms>
                <rewrite>
                    <index>
                        <to>M4U_Mycms/index</to>
                        <override_actions>true</override_actions>
                        <actions>
                           <noroute><to> M4U_Mycms/index/noroute</to></noroute>
                        </actions>
                    </index>
                </rewrite>
            </cms>
        </routers>

       </global>
</config>

N.B: Please take care about tag. It will let you create additional NEW actions that will be rewritten to new controller.

Now create new index controller in app/code/local/M4U/Mycms/controllers/IndexController.php and update noRouteAction method.


require_once "Mage/Cms/controllers/IndexController.php";
class M4U_Mycms_IndexController extends Mage_Cms_IndexController
{
    public function noRouteAction($coreRoute = null)
    {
        //modify this method as you need
        
        exit('Yes, I can successfully override cms/index noRoute method ');
		
        //$this->getResponse()->setHeader('HTTP/1.1','404 Not Found');
        //$this->getResponse()->setHeader('Status','404 File not found');
       // $pageId = Mage::getStoreConfig('web/default/cms_no_route');
       // if (!Mage::helper('cms/page')->renderPage($this, $pageId)) {
       //     $this->_forward('defaultNoRoute');
       // }
    }
}

Done !!

When any requested class/method is not found in system then Magento throw “404 Not Found” error using noRouteAction method. So we can test this method calling any undefined page url like http://127.0.0.1/magento/index.php/undefinedpagename. Here, undefinedpagename is not a defined page in magento.

ok, now run http://127.0.0.1/magento/index.php/undefinedpagename and if you get result
“Yes, I can successfully override cms/index noRoute method” in browser then noRouteAction method override is success.

Here i just describe noRouteAction method modification system. Like this way you can modify all of the indexController and pageController method.

You will get source code in right side box widget. Download code and enjoy your work.

if need any help let me know.

Create a new module in magento

When you need to add new functionality or want to edit existing magento class in both case you should create a new module. Suppose, you want to add “User Credit” system then you need to create a new UserCredit module in magento. And if you want to edit/update customer functionality  then you should follow magento override rules. To override existing Customer module you should create another new customer  module name M4U_Customer in local pool. In this case you need to use magento rewrite rules. When you go to add or edit something in magento,  each time you can be done as separate module or few methods can be combined in same module if they share functionality or could be used together.

Let’s create a module :

Module Declaration:
Create app/etc/modules/M4U_NewModule.xml and write below code

<?xml version="1.0"?>
<config>
         <modules>
<!-- declare CompanyName_NewModule module -->
           <M4U_NewModule>
<!-- this is an active module -->
                  <active>true</active>
<!-- this module will be located in app/code/local code pool -->
                  <codePool>local</codePool>
<!-- specify dependencies for correct module loading order -->
                  <depends>
                             <Mage_ExistingModule />
                  </depends>
<!-- declare module's version information for database updates -->
                  <version>0.1.0</version>
           </M4U_NewModule>
	</modules>
</config>

Here is example of create new M4U_customer module to override existing Mage_Customer module and M4U_Credit module to create new credit module.

<config>
    <modules>
        <M4U_Customer>
           <active>true</active>
           <codePool>local</codePool>
        </M4U_Customer>
        <M4U_Credit>
           <active>true</active>
           <codePool>local</codePool>
        </M4U_Credit>
    </modules>
</config>

Our new module will be called NewModule.

Replace all instances of ‘NewModule’ with name of your module and ‘newmodule’ with simplified code, that contains only alphanumeric characters and underscore.

To make this tutorial most concise, it’s implied that mentioned folders will be created when needed.

Module Configuration:

Create Model, Helper, coltrollers, Block, sql and etc folder under  app/code/local/M4U/NewModule/ and configure app/code/local/M4U/NewModule/etc/config.xml like below:

<?xml version="1.0"?>
   <config>
       <modules>
           <M4U_NewModule>
                 <version>0.1.0</version>
           </M4U_NewModule>
       </modules>

<!-- define Front end controller and template  -->
       <frontend>
<!-- define Front end controller  -->
           <routers>
               <newmodule>
                   <use>standard</use>
                   <args>
                          <module>M4U_NewModule</module>
                          <frontName>newmodule</frontName>
                   </args>
               </newmodule>
           </routers>
<!-- define Front end template xml -->
           <layout>
               <updates>
                    <newmodule>
                         <file>newmodule.xml</file>
                    </newmodule>
                </updates>
              </layout>
           </frontend>   

<!-- define blocks, models, helpers in global area -->
            <global>
               <models>
                  <newmodule>
                         <class>M4U_NewModule_Model</class>
                  </newmodule>
               </models>
               <blocks>
                  <newmodule>
                          <class>M4U_NewModule_Block</class>
                  </newmodule>
               </blocks>
               <helpers>
                  <newmodule>
                          <class>M4U_NewModule_Helper</class>
                  </newmodule>
               </helpers>

<!-- declare resource setup for new module -->
               <resources>
                    <newmodule_setup>
<!-- specify that this resource is a setup resource and used for upgrades -->
                       <setup>
<!-- which module to look for install/upgrade files in -->
                           <module>M4U_NewModule</module>
                       </setup>
<!-- specify database connection for this resource -->
                       <connection>
<!-- do not create new connection, use predefined core setup connection -->
                           <use>core_setup</use>
                       </connection>
                    </newmodule_setup>
                    <newmodule_write>
                         <connection>
                              <use>core_write</use>
                         </connection>
                    </newmodule_write>
                    <newmodule_read>
                         <connection>
                               <use>core_read</use>
                         </connection>
                    </newmodule_read>
                </resources>
           </global>
      </config>

Adapter Class:
To obtain module functionality you can write necessary method in various classes as magento convention.
1. Create necessary model class in app/code/local/M4U/NewModule/Model/
2. Create Block in app/code/local/M4U/NewModule/Block/
3. Create Helper in app/code/local/M4U/NewModule/Helper/
4. Place necessary updated database sql file in app/code/local/M4U/NewModule/sql/

Frontend Template Define:

1. Define page layout in app/design/frontend/M4U/default/layout/NewModule.xml

<?xml version="1.0"?>
   <layout version="0.1.0">
     <newmodule_index_usercredit>
        <reference name="root">
            <action method="setTemplate"><template>page/1column.phtml</template></action>
        </reference>
        <update handle="customer_account"/>
        <reference name="content">
            <block type="newmodule/blockClassName" name="usercredit" template="newmodule/usercredit.phtml"/>
        </reference>
     </newmodule_index_usercredit>
</layout>

2. Create template file app/design/frontend/M4U/default/template/newmodule/usercredit.phtml

Troubleshooting

  • Dont put your module in /Mage. It belongs in app/code/community/ or app/code/local/
  • Make sure your module’s first letter is capitlized. newmodule apparently will not work, it must start with a capital letter Newmodule.
  • If your module is not showing in configuration>advanced then check your config.xml
  • Make sure you clear the cache.

In this post i described general module customization theory of Magento. For more clarification you can see next post  “write HelloWord module” in this blog.