CodeIgniter Forums
Route extension: default request - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forumdisplay.php?fid=20)
+--- Forum: Archived Libraries & Helpers (https://forum.codeigniter.com/forumdisplay.php?fid=22)
+--- Thread: Route extension: default request (/showthread.php?tid=6198)

Pages: 1 2


Route extension: default request - El Forum - 02-18-2008

[eluser]zauber[/eluser]
Hi, I'm reposting this here as I wasn't getting any feedback in the Code & Development forum. This might be the more logical place for it anyway.

What I have done is made a small extension to the Router.php that adds a feature I've been missing.

There are cases where you would like to have an url like

Code:
http://mysite.com/any_data_here

and have it actually be equivalent to:

Code:
http://mysite.com/somecontroller/somemethod/any_data_here

In my case, I was making a cms, and wanted to have:

Code:
http://mysite.com/any_page_name_here

equivalent to

Code:
http://mysite.com/pages/read/any_page_name_here

Anyhow. I solved it with the following router extension:





Code:
class MY_Router extends CI_Router{
    function _validate_segments($s){
        if (count($s)==1 && !file_exists(APPPATH.'controllers/'.$s[0].EXT)){
            if (isset($this->routes['default_query'])){
                $segments = explode("/",$this->routes['default_query']);
                $segments[] = $s[0];
                $this->set_class($segments[0]);
                $this->set_method($segments[1]);
                return $segments;
            }
            show_404();
        }
        else return parent::_validate_segments($s);
    }
}


It adds a feature to the config/routes.php. To make url with a single segment (that is not a controller) go to a specific controller and method with the segment as a parameter, you add the 'default_query' index to the route table, like so:

Code:
$route['default_query'] = "controllername/methodname"


My feedback request is this:

1) Is there a more direct 'built-in' way of achieving this that I have overlooked?
2) Does this punch any holes in security or break functionality in some way I have yet to notice?
3) Is this the most efficient (computing-wise) way of adding this feature, without hacking the Router class directly? I tried to avoid as much repetition of code in the Router class as possible, and adding as little new code as possible myself, but I'm not sure how well I succeeded.

Hi, I'm reposting this here as I wasn't getting any feedback in the Code & Development forum. This might be the more logical place for it anyway.

What I have done is made a small extension to the Router.php that adds a feature I've been missing.

There are cases where you would like to have an url like

Code:
http://mysite.com/any_data_here

and have it actually be equivalent to:

Code:
http://mysite.com/somecontroller/somemethod/any_data_here

In my case, I was making a cms, and wanted to have:

Code:
http://mysite.com/any_page_name_here

equivalent to

Code:
http://mysite.com/pages/read/any_page_name_here

Anyhow. I solved it with the following router extension:





Code:
class MY_Router extends CI_Router{
    function _validate_segments($s){
        if (count($s)==1 && !file_exists(APPPATH.'controllers/'.$s[0].EXT)){
            if (isset($this->routes['default_query'])){
                $segments = explode("/",$this->routes['default_query']);
                $segments[] = $s[0];
                $this->set_class($segments[0]);
                $this->set_method($segments[1]);
                return $segments;
            }
            show_404();
        }
        else return parent::_validate_segments($s);
    }
}


It adds a feature to the config/routes.php. To make url with a single segment (that is not a controller) go to a specific controller and method with the segment as a parameter, you add the 'default_query' index to the route table, like so:

Code:
$route['default_query'] = "controllername/methodname"


My feedback request is this:

1) Is there a more direct 'built-in' way of achieving this that I have overlooked?
2) Does this punch any holes in security or break functionality in some way I have yet to notice?
3) Is this the most efficient (computing-wise) way of adding this feature, without hacking the Router class directly? I tried to avoid as much repetition of code in the Router class as possible, and adding as little new code as possible myself, but I'm not sure how well I succeeded.


Route extension: default request - El Forum - 02-18-2008

[eluser]frenzal[/eluser]
$route[':any'] = 'controller/methodname';

but then you'd still want to check that the route is not an existing controller first


Route extension: default request - El Forum - 02-18-2008

[eluser]zauber[/eluser]
Hmm wouldn't that just make any url take you to Controllername->methodname() witout any parameter?

I want this: "mysite.com/blabla" executes Controllername->methodname('blabla'):

I remember trying $route[':any'] but not getting it to work. It was late though, so I could just have been being stupid Tongue


Route extension: default request - El Forum - 02-18-2008

[eluser]Lone[/eluser]
Checkout the _remap and __construct functions for controllers for use in your default controller

http://ellislab.com/codeigniter/user-guide/general/controllers.html


The quickest way I can think of is to replace the _ function in the core Router library and before line 224 with the following code:

Code:
// Can't find the requested controller...
        show_404();

Add
Code:
$this->set_class($this->default_controller);
$this->set_method('index'); // 'index' can be just the first uri segment
return;



Route extension: default request - El Forum - 02-18-2008

[eluser]zauber[/eluser]
That's a pretty neat solution! I was thinking about attempting something like that, but eventually chose not to because in this case, I wanted to avoid hacking the core.

But you got me thinking. If you rewrote the show_404() function, to add a new type of hook ('pre_show_404'), that would open up a whole slew of tricks you could do. Like: 'my app can't handle this request, so hand it off to a completely different app'. ... Something to keep up the sleve.

Regarding the _remap function. I read about it, but don't see how it helps in this case. The router still needs to determine the controller on which to do the _remap(), right?


Route extension: default request - El Forum - 02-18-2008

[eluser]frenzal[/eluser]
[quote author="zauber" date="1203365603"]Hmm wouldn't that just make any url take you to Controllername->methodname() witout any parameter?

I want this: "mysite.com/blabla" executes Controllername->methodname('blabla'):

I remember trying $route[':any'] but not getting it to work. It was late though, so I could just have been being stupid Tongue[/quote]

You can just use the uri segment to get what you need


Route extension: default request - El Forum - 02-18-2008

[eluser]zauber[/eluser]
Frenzal, hmm - I'll test that. If you're right, it's a much neater solution. I was under the impression that the router actually rewrites the segments to match the routing. I'll look into it.


Route extension: default request - El Forum - 02-18-2008

[eluser]frenzal[/eluser]
it's how i use it, if you want to use the rewrite segments you need to use uri->rsegment


Route extension: default request - El Forum - 02-18-2008

[eluser]Lone[/eluser]
Good idea on the 404 - changing how it handles might be a good idea.

The _remap was handy because it was hit first before the function in your controller - it depends on what you were wanting to do but _remap would allow you to have it as a common function like index if you didn't need a controller function for each different first uri segment but it seems now that you do so might now be much use.


Route extension: default request - El Forum - 02-18-2008

[eluser]zauber[/eluser]
After some further tests, it appears I cannot get the wildcard, or regular expression routes to work at all. Standard routes without any logic, like $route['hello'] = 'pages/read/hello'; work fine. Stick a wildcard in there like $route["readpage/:any"] = "page/read/some_specific_page_that_exists"; or plain-ol $route[:any]= ... will inevitably give me a CI 404 page. Again: same with regexps - they seem to be broken somehow.

I'm using the whatever the version before 1.6 of codeigniter was (1.5.4 I think). ...And this is WITHOUT my router extension Will try the latest release-version.