2

I am building a magento extension that will need a custom URL for the frontend that is set via the admin panel config setting for the extension.

Along the lines of the "set admin url" setting in the system settings (which can also be set in the app/etc/local.xml file as well).

basically, I have in my config.xml file

<frontend>
     <routers>
        <extensionname>
            <use>standard</use>
            <args>
                <module>My_Extensionname</module>
                <frontName>extensionname</frontName>
            </args>
        </extensionname>
    </routers>
</frontend>

This creates the URL site.com/extensionname

But I want to be able to set the url in the system/settings tab in the admin panel

I have looked through the core code and seen glimpses of code that does (a predispatch models controllers etc i think) this for the default admin URL key setting

How would I go about this? Would i set up an observer to catch the request to URL? or observer settings change and programmatically create a URL rewrite?

What about the content & root template as well in the layout/extensionname.xml?

<layout version="0.1.0">
<extensionname_index>
<reference name="root">
        <action method="setTemplate"><template>extensionname/page.phtml</template></action>
    </reference>
    <reference name="content">
        <block type="extensionname/extensionname" name="extensionname"  template="extensionname/extensionname.phtml" />
    </reference>
</extensionname_index>

Would this still be used even though I would be using a custom URL from the settings

3

2 Answers 2

1

The admin area has its own router class that allows a custom frontname, while the frontend router does not have such a mechanism.

You will have to write your own router that extends Mage_Core_Controller_Varien_Router_Standard and overrides match() - here you check for your custom front name and instantiate the appropiate controller action.

To register the router, add this to your config.xml:

<default>
    <web>
        <routers>
            <the_router_name>
                <area>frontend</area>
                <class>The_Router_Class_Name</class>
            </the_router_name>
        </routers>
    </web>
</default>

Since you will do all the matching logic in the custom router you don't need to register the frontend route anymore (<frontend><routers>...)


Regarding your layout concerns: Front name and route name are independent, so this will never be a problem, even with the default router:

<frontend>
     <routers>
        <extensionname> <--------- route name, used for layout handle
            <use>standard</use>
            <args>
                <module>My_Extensionname</module>
                <frontName>extensionname</frontName> <---- front name, used for URL
            </args>
        </extensionname>
    </routers>
</frontend>
1
  • 1
    Thanks @fschmengler i added some links in original based on your post
    – BENN1TH
    Commented Jul 7, 2015 at 7:48
0

Ok could not get any of the above info (links) to work from my end (in regards to using custom routers etc) because i think my extension is not using any collections from the database as its just a landing page so wont have index/index/id values etc.

So went with a dirty hack to do the job for now. See below.

etc/config.xml (observer event when admin field setting saved)

<config>
 ...
<frontend>
<routers>
        <myextension>
            <use>standard</use>
            <args>
                <module>Mycompany_Myextension</module>
                <frontName>myextension</frontName>
            </args>
        </myextension>
    </routers>
...
</frontend>
<global>
...
<events>
<admin_system_config_changed_section_myextension>
<observers>
    <myextension>
        <type>singleton</type>
        <class>myextension/observer</class>
        <method>observersave</method>
    </myextension>
</observers>
</admin_system_config_changed_section_myextension>
</events>
...
</global>
</config>

Model/Observer.php (Save a URL Rewrite) (EDITED)

public function observersave(Varien_Event_Observer $observer)
{

    #remove the old urlrewrite
    $url =  Mage::getStoreConfig('myextension/general/url');
    $uldURLCollection = Mage::getModel('core/url_rewrite')->getResourceCollection();
    $uldURLCollection->getSelect()
    ->where('id_path=?', 'myextension');//EDIT: so overwrites on each save

    $uldURLCollection->setPageSize(1)->load();

    if ( $uldURLCollection->count() > 0 ) {
    $uldURLCollection->getFirstItem()->delete();
    }

    #add url rewrite
    $modelURLRewrite = Mage::getModel('core/url_rewrite');

    $modelURLRewrite->setIdPath('myextension/'.strtolower($url))
    ->setTargetPath('myextension/index/index/id/'.$url.'')
    ->setOptions('')
    ->setDescription('New URL - Created as a new setting was saved')
    ->setRequestPath('myextension/url/'.$url.'');//EDIT: added extra rewrite url paths so rewrite can never conflict if admin setting field is set to a "key default url" like "admin" or "checkout" or "contacts" etc

    $modelURLRewrite->save();
}

controllers/IndexController.php (redirects if no ID...) (EDITED)

public function preDispatch()
{

    //$url =  Mage::getStoreConfig('myextension/general/url');
    if ( !strstr($this->getRequest()->getRequestUri(), 'myextension/index/index/id') ) {
        parent::preDispatch();
    }

}


public function indexAction()
{
    $url =  Mage::getStoreConfig('myextension/general/url');
    if ( trim($this->getRequest()->getParam('id')) == ''  ) {
        $this->_redirect('/');//Edit: changed redirect to root

    } else {

        $id = $this->getRequest()->getParam('id');
        if($id == $url) {   
        $this->loadLayout( array(
                        'default',
                        'myextension_index_index'
        ));//EDIT: added if statement to see if myextension/index/index/id matched admin setting, if not redirect to root

        $this->renderLayout();
        }else{
        $this->_redirect('/');//Edit: changed redirect to root
        }
    }

}

so at this point i have URLs at: (EDITED)

site.com/myextension/url/myadminfieldvalue

&

site.com/myextension/index/index/id/myadminfieldvalue

(EDITED) but in template/myextension/myextension.phtml

<?php if($current_url == ''.$base_url.'myextension/index/index'){ ?>
<p>Disabled cause i dont really want info at this url..</p>
<?php }else{ ?>
<p>show data because your accessing myextension/index/index via the rewrite /myextension/url/myadminfieldvalue.</p>
<?php } ?>

A bit more work is needed to achieve what i want but for now it works for me and hope others may find this useful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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