3

I have a router like this

<routers>
    <mymodule>
        <use>standard</use>
        <args>
            <module>NSP_MyModule</module>
            <frontName>mymodule</frontName>
        </args>
    </mymodule>     
</routers>

which (in my environment) will be accessable with this URL /magento/mymodule but I want the URL key mymodule to be custamizable through backend. How can I achieve that?

  • Hi, what have you tried so far? Do you know how to create a module configuration with system.xml in general? – simonthesorcerer Jul 25 '15 at 17:34
  • The system.xml should be managable. I don't know how to assign the variable to the frontName – mpfmon Jul 25 '15 at 17:36
  • Okay, what have you tried to achieve this, and why did it not work? – simonthesorcerer Jul 25 '15 at 17:37
  • I have no idea how this can be done and I couldn't find a solution by googling. This actually bugs me for a while now, that's why I asked. – mpfmon Jul 25 '15 at 17:40
2

In this excellent post by Alan Storm, I found a hint to a possible solution. You should register your own router. An example can be found in Magento's CMS module.

In the CMS module's config.xml find this section:

<events>
    <controller_front_init_routers>
        <observers>
            <cms>
                <class>Mage_Cms_Controller_Router</class>
                <method>initControllerRouters</method>
            </cms>
        </observers>
    </controller_front_init_routers>
</events>

The method initControllerRouters() registers a new router:

public function initControllerRouters($observer)
{
    /* @var $front Mage_Core_Controller_Varien_Front */
    $front = $observer->getEvent()->getFront();

    $front->addRouter('cms', $this);
}

...that will be iterated in app/code/core/Mage/Core/Controller/Varien/Front.php:

while (!$request->isDispatched() && $i++<100) {
    foreach ($this->_routers as $router) {
        if ($router->match($this->getRequest())) {
            break;
        }
    }
}

The match() method of the CMS-Router contains this code:

$page   = Mage::getModel('cms/page');
$pageId = $page->checkIdentifier($identifier, Mage::app()->getStore()->getId());
if (!$pageId) {
    return false;
}

$request->setModuleName('cms')
    ->setControllerName('page')
    ->setActionName('view')
    ->setParam('page_id', $pageId);

...which leads to the file Cms/controllers/PageController.php. The class inside is named Mage_Cms_PageController and has a method viewAction() that asks for the request's parameter page_id. From here, you can look further at the method Mage::helper('cms/page')->renderPage($this, $pageId).

I think another big problem will be, if the configured frontName matches that of a system frontName, or the frontName defined by another module. I have no idea how this might work out.

|improve this answer|||||
0

In order to achieve this, you need to manually add your dynamic routes to Standard-Router1 before dispatching of router happens. I will show you how you can achieve this with an example below. Using which, you can implement rest.

You need to listen to the event controller_front_init_routers and add your routes in the observer.

File: app\code\{codePool}\{Namespace}\{Module}\etc\config.xml

<config>
    <global>
        <events>
            <controller_front_init_routers>
                <observers>
                    <add_dynamic_frontnames>
                        <class>namespace_module/observer</class>
                        <method>addDynamicFrontnames</method>
                    </add_dynamic_frontnames>
                </observers>
            </controller_front_init_routers>
        </events>
    </global>
</config>

Note : Important. Observer should be inside global scope.

File : app\code\{codePool}\{Namespace}\{Module}\Model\Observer.php

<?php
class Namespace_Module_Model_Observer
{
    const DYNAMIC_FRONTNAMES = 'sytem/config/path/to/dynamic/routes';

    public function addDynamicFrontnames(Varien_Event_Observer $observer)
    {
        //get front controller
        $front = $observer->getEvent()->getFront();

        //grab request object and standard router
        $request = $front->getRequest();
        $standardRouter = $front->getRouter('standard');

        //grab module and route info using frontname;
        //note:a router with frontname 'mymodule' should be configured in your module
        $drouteName = $standardRouter->getRouteByFrontName('mymodule');
        $dmoduleName = $standardRouter->getModuleByFrontName('mymodule');

        //get dynamic frontnames from system config section
        $_dynamicFrontNames = explode(',',
            Mage::getStoreConfig()->getNode(self::DYNAMIC_FRONTNAMES)
        );

        //add your dynamic frontnames to standard router
        foreach ($_dynamicFrontNames as $frontName) {
            $standardRouter->addModule($frontName, $dmoduleName, $drouteName);
        }

        return $this;
    }

What we are doing here is, we are using Front-Controller2 to grab Standard-Router. Then we will collect module-name and router-name using our frontName mymodule. Then set the same module-name and router-name for every dynamic frontname which we collect from the system config section sytem/config/path/to/dynamic/routes. So all the frontnames which you configured from system config section will just behave like mymodule frontname here.

So along with these event setup, you are required to setup a router like this in your config.xml file.

<config>
    <frontend>
        <routers>
            <{router_identifer}>
                <use>standard</use>
                <args>
                    <module>Namspace_Module</module>
                    <frontName>mymodule</frontName>
                </args>
            </{router_identifer}>
        </routers>
    </frontend>
</config>

Also you need to setup a system.xml file to configure your dynamic frontnames and replace the constant DYNAMIC_FRONTNAMES with the the right path in the observer file above.

Hope that makes sense.


1:Mage_Core_Controller_Varien_Router_Standard

2:Mage_Core_Controller_Varien_Front

|improve this answer|||||

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.