4

So, I've written a custom router, in as much as I've extended Mage_Core_Controller_Varien_Router_Standard and created my own match() function. This part works beautifully, mapping the differently formatted URLs I'm using for a specific section of the site to the typical frontname/controller/action pattern.

The only issue is I now cannot use getUrl() in the normal way.

For example, the frontName in the modules config.xml is lookfor, and the extension name is Customsearch. Usually, using Mage::getUrl('customsearch/action') would return me a url of lookfor/action. But, with the custom router, I simply get back customsearch/action. If I switch back to the standard router in the config.xml, voila, it works.

You might ask why I want this when my URLs are different - handily some functionality through this module will still be accessed the normal way. I've got this to work as expected (by placing my custom code between the normal controller/action finding code, and the noRoute stuff), its simply the URL lookup thats failing.

I've done some digging, and noticed that in the below function, from Mage_Core_Model_Url, the $this->_getData('route_front_name') has the wrong frontName (customsearch, rather than lookfor), but I can't spot where this is set.

public function getRouteFrontName()
    {
        if (!$this->hasData('route_front_name')) {
            $routeName = $this->getRouteName();
            $route = Mage::app()->getFrontController()->getRouterByRoute($routeName);
            $frontName = $route->getFrontNameByRoute($routeName);

            $this->setRouteFrontName($frontName);
        }
        return $this->_getData('route_front_name');
    }

Here're the relevant sections from the modules config.xml...

<frontend>
   <routers>
      <customsearch>
         <use>namespace_customsearch</use>
         <args>
            <module>Namespace_Customsearch</module>
            <frontName>lookfor</frontName>
         </args>
      </customsearch>
   </routers>
   ...
</frontend>
...
<default>
   <web>
      <routers>
         <namespace_customsearch>
            <area>frontend</area>
            <class>Namespace_Customsearch_Controller_Router</class>
         </namespace_customsearch>
      </routers>
   </web>
</default>
  • Please add the relevant content from your module config. Also how are you adding your router instance to the front controller? – benmarks Jan 20 '14 at 17:30
2

General warning — while ideally it should be supported, what you're trying to do isn't really meant to be done by a non-core Magento developer. The abstractions around routing are confusing, and possibly incomplete. It's relatively safe to introduce a new router object with a match method, but (as you've seen) expecting it to behave in predicable ways with the system is asking Magento too much. Generally speaking, if you want a special URL in Magento, you use the rewrite system (either the rewrite models, or the configuration rewrites)

But that's not any fun.

So, the particular problem you're running into is a routername/frontName mismatch. Your router configuration is named customsearch, but your frontName is named lookfor. This is a common problem when customizing system behavior, because most developers don't realize there's a difference between these two. That's because Magento core code always has them match each other. You see this this a lot in the various methods of replacing a controller action, and having the layout handles generated not match the layout handles Magento expects.

Looking at your specific problem, my guess (because it's hard to tell with the information provided) is your custom router class

`Namespace_Customsearch_Controller_Router`

in inheriting from the Mage_Core_Controller_Varien_Router_Abstract class. If you look at the getFrontNameByRoute method definition there

#File: app/code/core/Mage/Core/Controller/Varien/Router/Abstract.php
public function getFrontNameByRoute($routeName)
{
    return $routeName;
}

You can see the method is essentially a placeholder. In the standard router

#File: app/code/core/Mage/Core/Controller/Varien/Router/Standard.php
public function getFrontNameByRoute($routeName)
{
    if (isset($this->_routes[$routeName])) {
        return $this->_routes[$routeName];
    }
    return false;
}

This method checks the configuration built up in the internal _routes array, and returns the value it finds (which will be the frontName).

As I said, my guess is your router object inherits from the Abstract class, and doesn't have a custom getFrontNameByRoute method. Your router object needs a similar/identical method, or needs to inherit from the standard router to have this functionality.

  • I'll tag onto this answer by pointing out that your router is expected to implement the collectRoutes() method given that you are including it via config XML; ref Mage_Core_Controller_Varien_Front::init(). – benmarks Jan 20 '14 at 21:47
  • Gents, thanks massively for the responses. Alan - I'm extending my router from Mage_Core_Controller_Varien_Router_Standard, which I presumed (naively) would allow everything else to run as normal. I'll take a look at the functions/code above and see if I can crack anything. Thanks again! – thebluefox Jan 21 '14 at 9:22
  • @thebluefox If you find an answer be sure to post an update — I'm curious now. – Alan Storm Jan 21 '14 at 17:18
  • @Alan Storm, Hey Alan - I will do - thanks to you and Ben for your help, this ones taken a little bit of a back seat at the mo. As soon as I've cracked it, I'll let you know! – thebluefox Feb 2 '14 at 18:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.