Simple URL Rewrite Using Magento xml

URL
In this blog post, we will see how to do simple url rewrite in magento using config.xml.

This method is very useful when creating modules in magento and you want to provide fancy url to your module without using .htaccess rewrites.
Let me know explain to you first what exactly is described in this blog. Suppose there is a module you have developed which displays a list of all products which belong to a particular manufacture. Here manufacturer is a product drop down product attribute, let us assume the frontend URL of our module is ‘manufacturer’. So the URL of a particular manufacturer page ideally would be something like this
www.your-website.com/manufacturer/index/index/brand/sony
This is how default URL’s are in magento where,
manufacturer = module frontend url
index = IndexController
index = index Action function
brand/sony = request parameters
But suppose if we want a URL like this
www.your-website.com/manufacturer/sony
which works exactly the same work as above url, it would be better. This traditional way to do this is using .htaccess url rewrites, but in this blog we are going to see how to do this using config.xml controller rewrites.
Now lets see how to do this, open your config.xml file of your module and add this code inside the <global> tag.

<rewrite>
    	<fancy_url>
	              <from><![CDATA[/manufacturer\/(.*)/]]></from>
	              <to><![CDATA[manufacturer/index/index/manufacturer/$1/]]></to>
                      <complete>1</complete>
            </fancy_url>
    	</rewrite>

what we are doing here is tell magento to rewrite /manufacturer\/(.*)/ to manufacturer/index/index/manufacturer/$1/
The <from> tag takes in any regular expression which is the source url and in the <to> we put in the destination url. $1,$2 etc is used for variable substitution which works same as the php preg_match function.
The <complete>1</complete> is important, it make magento use the correct layout handle which is used in layout xml files. what this means is if you don’t put <complete>1</complete>, then in your controller when you do

$this->loadLayout();
$this->renderLayout();

magento will not read the xml tag related to <manufacturer_index_index> but will read something else depending on your URL.

If you’r wondering where exactly this rewrite magic happens inside magento, the code is located in class Mage_Core_Controller_Varien_Front, rewrite() function.

public function rewrite()
    {
        $request = $this->getRequest();
        $config = Mage::getConfig()->getNode('global/rewrite');
        if (!$config) {
            return;
        }
        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, $request->getPathInfo());

            if (isset($rewrite->complete)) {
                $request->setPathInfo($pathInfo);
            } else {
                $request->rewritePathInfo($pathInfo);
            }
        }
    }

As you see magento uses the preg_replace() function itself, so all rules applicable to preg_replace() can be used for our rewerites.

There is just one exception to the regular expression you can use here. Your regular expression’s cannot have ‘{‘ and ‘}’ in them, the curly bracket regex won’t work. The reason being magento uses curly brackets for internal processing. If you see the code of the _processRewriteUrl() function, it replaces the content inside curly braces with route name.

protected function _processRewriteUrl($url)
    {
        $startPos = strpos($url, '{');
        if ($startPos!==false) {
            $endPos = strpos($url, '}');
            $routeName = substr($url, $startPos+1, $endPos-$startPos-1);
            $router = $this->getRouterByRoute($routeName);
            if ($router) {
                $fronName = $router->getFrontNameByRoute($routeName);
                $url = str_replace('{'.$routeName.'}', $fronName, $url);
            }
        }
        return $url;
    }
Hopefully you where able to understand the rewrite trick which can be used very effectively to have nice fancy url’s in magento modules.
  • Pingback: Simple URL Rewrite Using Magento xml | PHP | Syngu()

  • http://www.ave-nir.com Magento Development

    Great blog. This is what I have been searching for. It helped me a lot in implementing them. 

  • Horschi

    Many thanks for your blog. It’s really great! I could implement the rewrite urls to my custum module (it shows a collection of products depending on an attribute value). Unfortunately, I don’t know how to tell the paging toolbar to use the rewrite urls, too. It always targets to the unformated url…

  • Pingback: Quora()

  • Hgjjjjjjjjjghj

    6

  • http://twitter.com/MageBuzz MageBuzz

    Thank you for sharing this. That is a great helpful. Normally, we can
    change the URL directly in admin using Catalog > URL rewrite.

  • neonguyen

    Thank you for sharing, very helpful article.

  • http://aaronbonner.tumblr.com/ Aaron Bonner

    Thank you for explaining the tag, I could have dug through the mage source and probably figured it out, but you saved me a tonne of time.

    Cheers!

  • Manish Prakash

    Thanks vivek..

  • sadsads

    good like!

  • MR.Kien

    1

    the code below rewrite for a url : manufacturer/index/index/manufacturer/$1/

    I want rewrite a list urlkey in database!! help me!

  • abdullah al Mamun

    from manufacturer/xxx, I got xxx info. But for rewrite, lost my previous manufacturer list; how can I overcome this.