Magento URL Rewrites and Controller Overriding

In this blog post we will see in detail how magento implements url rewriting and controller overriding

Controller Overriding

In the previous blog post we saw an important function in “Mage_Core_Controller_Varien_Front” class

$this->_getRequestRewriteController()->rewrite();

Lets look at this function in detail now. The “_getRequestRewriteController()” returns a class object as below

$className = (string)Mage::getConfig()->getNode('global/request_rewrite/model');
        return Mage::getSingleton('core/factory')->getModel($className, array(
            'routers' => $this->getRouters(),
        ));

Since the $className comes from xpath ‘global/request_rewrite/model’ it can also be a custom class (but that is a separate discussion). By default is defined in “Mage/Core/etc/config.xml”

<request_rewrite>
            <model>core/url_rewrite_request</model>
        </request_rewrite>

So this functions return an object of class “core/url_rewrite_request”. If you open this file you see the “rewrite()” function defined there. The “rewrite()” function has two important functions “$this->_rewriteDb();” and “$this->_rewriteConfig();”

_rewriteDB()

The _rewriteDb() function check if any url rewrite rules have been setup in (Admin -> Catalog -> URL Management) section. If applied it redirects to the new url.
Lets see in detail how the rewriteDB works. The function first generates different URL’s to compare in database.
It generated maximum there request cases
1. request with slash and query string
2. request without slash with query string
3. request without slash and without query string
so if URL is www.domain.com/test/index/index?abc=123

the request cases generated would be
1. test/index/index/?abc=123
2. test/index/index?abc=123
3. test/index/index

Next magento checks the table ‘core_rewrite_url’ with these request paths, if any of them matches it redirects to the target_path set in database.

_rewriteConfig()

The _rewriteConfig() function check for any url rewrite written in config.xml file. It looks for “global/rewrite” xpath and then check all “from” and “to”.

<rewrite>
        <fancy_url>
                  <from><![CDATA[catalog/index/index]]></from>
                  <to><![CDATA[manufacturer/index/index/manufacturer/$1/]]></to>
                      <complete>1</complete>
            </fancy_url>
        </rewrite>

More details about config.xml can be read here

The code written in the rewriteConfig is

protected function _rewriteConfig()
    {
        $config = $this->_config->getNode('global/rewrite');
        if (!$config) {
            return false;
        }
        foreach ($config->children() as $rewrite) {
            $from = (string)$rewrite->from;
            $to = (string)$rewrite->to;
            if (empty($from) || empty($to)) {
                continue;
            }
            $from = $this->_processRewriteUrl($from);
            $to   = $this->_processRewriteUrl($to);

            $pathInfo = preg_replace($from, $to, $this->_request->getPathInfo());
            if (isset($rewrite->complete)) {
                $this->_request->setPathInfo($pathInfo);
            } else {
                $this->_request->rewritePathInfo($pathInfo);
            }
        }
        return true;
    }

Important Note: This uses ‘preg_replace’ function. So its possible to define regular expressions as well in our config.xml to rewrite controllers.

Action Overriding

In the preDispatch() function of “Mage_Core_Controller_Varien_Action” class, which is extended by all controller we have “$this->_rewrite()” function.

The rewrite() function looks for config node

$rewrite = Mage::getConfig()->getNode('global/routers/'.$route.'/rewrite/'.$controller);

So in config.xml we can define if want to rewrite a particular action of a controller as well.

    <!-- this will rewrite all actions of a controller -->
    <global>
        <routers>
            <customer>
                <rewrite>
                    <account>
                        <to>test/index/index</to>
                    </account>
                </rewrite>
            </customer>
        </routers>
     </global>

or

     <!-- this will rewrite only single actions of a controller -->
     <global>
        <routers>
            <customer>
                <rewrite>
                    <account>
                            <login>
                                <to>test/index/index</to>
                            </login>
                        </actions>
                    </account>
                </rewrite>
            </customer>
        </routers>
     </global>

So these are the three ways of rewriting URL in magento which we have seen in detail.

  • janusz

    Thank You!

    (For this hint: Admin -> Catalog -> URL Management 🙂 )

  • Math is the very important subject for the educators. But don’t know well on this subject. As a result this functions inspired me to do this. ..