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
Code:
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
Code:
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 tag.
HTML Code:
<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 tag takes in any regular expression which is the source url and in the we put in the destination url. $1,$2 etc is used for variable substitution which works same as the php preg_match function.
The 1 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 1, then in your controller when you do
PHP Code:
$this->loadLayout();
$this->renderLayout();
magento will not read the xml tag related to 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.
PHP Code:
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.
PHP Code:
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;
}
View more threads in the same category:
Bookmarks