Welcome Guest, Not a member yet? Register   Sign In
search queries in first part of URI
#1

[eluser]Yednotek[/eluser]
Hi,

for a site I'd like to be able to add a search query to the URI so that it is the first part of the query string like so:
www.mydomain.com/this+is+a+search+query

Is this possible from within CI or would I need to use mod_rewrite?
#2

[eluser]WebsiteDuck[/eluser]
If you would just do http://www.domain.com/search/this+is+a+search+query you could easily do this with a controller...

Otherwise you'll have to mess around with your routes config so that you're still able to use any controllers you have.
#3

[eluser]Yednotek[/eluser]
'messing' with the config doesn't have to be a bad thing if it gets the desired result..
#4

[eluser]WebsiteDuck[/eluser]
I think the way I would do it is extend the CI_Router class like so:

Code:
class MY_Router extends CI_Router{
    
    function MY_Router(){
        parent::CI_Router();
    }
    
    function _validate_segments($segments)
    {
      //some code
    }
}

Copy the _validate_segments function from system/libraries/Router.php into there, then comment out the last show_404 function and instead do:
Code:
$this->set_class('your search controller');
$this->set_method('index');

Never tried it though...
#5

[eluser]Joshua Logsdon[/eluser]
Agreed.

In your config/routes you could try to set up $route[':any'] = 'your_catchall'; that should default to a controller name if no other $route picks up the url, but you could get screwy results with other urls that should be picked up automatically with existing controllers.

So like WebsiteDuck mentioned, you will have to play with _validate_segments() (he may have meant _validate_request) but you may also have to add into _validate_request(). Try what he mentioned first because what I have next may be more involved.

In _validate_request() I added a check for a new type of $route, $route['catchall_controller']. If this is set it will route to this controller as a last resort. Then that catchall controller uses _remap() to find what I'm looking for and if I dont't, then I show_404().

Here's a snippet of the end of my _validate_request(). Notice my addition is between the //BEGIN and //END comments. This may get you started and you can tweak it from there with how segments should be passed and what the default method should be...
Code:
return $segments;
        }
        
        //BEGIN - Joshua Logsdon
        if ( isset($this->routes['catchall_controller']) && file_exists(APPPATH.'controllers/'.$this->routes['catchall_controller'].EXT) )
        {
            // Assumes catchall will not be in a sub-folder
            $this->directory = '';
            $this->set_class($this->routes['catchall_controller']);// The catchall conroller will be the class
            $this->set_method($segments[0]);// The first segment will be the method
            array_unshift($segments, $this->routes['catchall_controller']);// The rest will be the adjusted segments
            
            return $segments;
        }
        //END - Joshua Logsdon

        // Can't find the requested controller...
        show_404($segments[0]);
    }
#6

[eluser]Shay Falador[/eluser]
I don't think editing all of this things is smart. CodeIgniter enables it pretty easily.
First you must enable + in urls, to do so change in the config this line:
Code:
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
To:
Code:
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-+';
Then all you have to do is catch requests, I would create a controller catch, with an index function that gets one argument, and use this route:
Code:
$route['(.+)'] = 'catch/index/$1';
#7

[eluser]Joshua Logsdon[/eluser]
Right, that's what I'm saying before I go into my edit. Shay gave a better representation of what's involved.

The problem I have with going that route (no pun intended) is that now via _parse_routes() in the Router library, you've just cut off any automatic routing, e.g. if he has a controller named "blogs" and doesn't have it listed as a $route, $route['(.+)'] is going to kick in instead of finding that "blogs" controller exists and setting it as the request.

In other words if you do $route['(.+)'], that controller is going to need to _remap every request that isn't listed in the $routes. If you are going to list all your known $routes, then you're fine.

For me at least, being able to specify an optional catchall controller (with a small add-on and no code reworking) while leaving automatic routing intact works smarter.
#8

[eluser]Shay Falador[/eluser]
Well, you can just put the catch-all route at the end of the list you know Tongue
#9

[eluser]Sean Gates[/eluser]
@WebsiteDuck is correct. You should not go through all this when it's easy to just prefix everything with /search/.
#10

[eluser]Joshua Logsdon[/eluser]
@Shay: I thought I said that in my post Tongue "If you are going to list all your known $routes, then you’re fine [to use the catchall route like you stated]." So if you list all your routes and the catchall last, you've got the idea. But this goes into Sean...

@Sean: Yes, but what if you want to mock Wordpress with a blog like http://example.com/2010/01/many-ways-to-go-about-this.

No one is wrong here. There are just different ways to go about it with different purposes, so it's good to understand each approach. Listed here: If you can prefix it, this wouldn't even be a problem. You can use routes, but keep in mind the issue about needing to have all routes listed. Or you can make an addition to the Router and not deal with the listed routes issue.




Theme © iAndrew 2016 - Forum software by © MyBB