Kohana 3 Routing – Part 2: Dynamic Routes and Default Values

Part 1 | Part 2

In Part 1 of these articles we learned to created a simple static route in Kohana. In this part we’ll build on the basic routing to make parameters passed in the URL available to the action function.

Basic Parameters

Passing parameters into kohana from the URL is a fairly straightforward process. Below we’ll go over an example with a parameter called ‘parameter1′.

Set up your Kohana instance with the following file application/classes/controller/Foo.php

with the content:

<?php

class Controller_Foo extends Controller {
    public function action_bar(){
        $parameter = $this->request->param('parameter1');
        $this->response->body('In controller Foo, action Bar, with a Parameter of: '. $parameter);
    }
}

And the following route in your bootstrap.php file:

 Route::set('fooroute', 'foo/bar/<parameter1>')->defaults(array(
        'controller' => 'Foo',
        'action'     => 'bar',
    ));

Use a browser to hit http://yoursite.com/foo/bar/sometexthere . You’ll get a resulting page response of:

In controller Foo, action Bar, with a Parameter of: sometexthere

Change the ‘sometexthere’ part of the URL and it will update the resulting page. Easy as pie right? All you do is pick a parameter name, put it in the URL path surrounded with <> and you’ve got a parameter that wiil be passed to the controller’s action function. In this example the route matches and sets the ‘paramater1′ to ‘sometexthere’. You can add as many parameters as you need this way.

Remember any text in the URL must match exactly, unless it’s specified as a parameter between <>. Also, just because it’s a parameter, does not mean it’s optional. Up until this point any parameters specified must have a value set or Kohana will not see it as a match. Also, for now, don’t use parameters named ‘<directory>’, ‘<controller>’, and ‘<action>’–they have specifically reserved functionality, which we’ll look at later.

Optional URL Segments

If surround a part of the URL with parenthesis, it becomes optional. Let’s make a small edit to our Contoller_Foo class:

<?php

class Controller_Foo extends Controller {
    public function action_bar(){
        $parameter = $this->request->param('parameter1');
        if(!empty($parameter)){
            $this->response->body('In controller Foo, action Bar, with a Parameter of: '. $parameter);
        }else{
           $this->response->body("No parameter passed to Foo Controller, Bar action... but we're all good!");
        }
    }
}

Now, let’s make an optional part of the URL for the Route:

 Route::set('fooroute', 'foo/bar(/<parameter1>)')->defaults(array(
        'controller' => 'Foo',
        'action'     => 'bar',
    ));

Try going to this URL with http://yoursite.com/foo/bar/ or http://yoursite.com/foo/bar/sometext/. Both should work as expected.

If you remember from part 1, the route must not have a trailing slash in it. Take note from above that since <parameter1> is the final URL segment, we need to put the slash before <parameter1> inside the parenthesis that indicate an optional URL component. Otherwise, while everything will work with <parameter1> specified, when left out the match will fail.

Not only parameters can be optional, any text or part of the URL can be optional, but be careful, making a portion in the middle optional can cause confusion when you get past a few routes. Remember, Kohana matches only one route, the first one that matches, not the best or most explicit match. If a match is made and the respective controller/action combo it specifies is missing, a 404 Error is triggered–even if another matching route exists with a valid controller and action.

Special Parameters

Back a bit I mentioned parameters named controller, action, etc… have special meanings, well, now we’ll look at them. When we’ve been defining routes so far, the default array explicitly indicates the controller and action to use when a match is found. However, you can use the special parameters controller and action to do away with with defaults (we will use them again later… don’t worry.) Let’s edit our route to look like this:

 Route::set('fooroute', '<controller>/<action>(/<parameter1>');

Now, just as in the previous example, we can specify URL with http://yoursite.com/foo/bar/ or http://yoursite.com/foo/bar/sometext/ to trigger a URL match. Both the <controller> and <action> parts of the URL are mandatory, and the <parameter1&gt portion is optional. Kohana will look for a controller and action exactly matching the variable parameters specified in the URL. If the controller/action pair does not exist, a 404 error is returned.

More on Defaults

The last thing I want to do in this installment on routing is return to the default array. You may want a default controller or action for some things and not others. For example, if you want to make controllers and actions dynamic, but if a action part of the url is not specified always look for an ‘index’ action. Edit our route to look like this:

 Route::set('fooroute', '<controller>(/<action>)')->defaults(array(
        'action'     => 'index',
    ));

And edit our controller class to look like this:

class Controller_Foo extends Controller {
    public function action_bar(){
           $this->response->body("In Foo controller within the bar action");
    }
   
    public function action_index(){
           $this->response->body("In Foo controller within the index action");
    }
}

Now going to URL with http://yoursite.com/foo/bar/ will work, but so will http://yoursite.com/foo/. Without the action specified, it will use the default value, index in this case. Take note that the action parameter must be optional or this will fail to work–the pattern will not match a URL lacking the action component. Also, if an action is specified, even if non-existing, the default value is ignored.

Defaults simply provide values for parameters, whether they are ‘special’ parameters or not. If you make a parameter part of the URL and it’s specified it overrides the values in the defaults array. Our final example will show this explicitly. Change your route to look like the following:

 Route::set('fooroute', '<controller>(/<action>)')->defaults(array(
        'action'     => 'index',
        'parameter1' => 'boo-boo',
    ));

And also change the controller object correspondingly:

class Controller_Foo extends Controller {
    public function action_bar(){
        $parameter = $this->request->param('parameter1');
        $this->response->body('In controller Foo, action Bar, with a Parameter of: '. $parameter);
    }  
    public function action_index(){
        $parameter = $this->request->param('parameter1');
        $this->response->body('In controller Foo, action Index, with a Parameter of: '. $parameter);
    }  
 }

Once again, going to either http://www.crewfoo.com/foo/bar/ or http://www.crewfoo.com/foo/ will work as before, but notice parameter1 is set, EVEN THOUGH IT’S NOT SET IN THE URL.

One last example…

If you read the Kohana Documentation they’ll indicate a good ‘default’ route. Don’t be confused, there’s nothing special with a route named ‘default’, but it basically allows for use of a dynamic controller and action, with a default route if none is specified. Here is something similar in the context of our examples, with the default array set to our lovable Foo controller, Bar Action:

 Route::set('foodefaultroute', '(<controller>(/<action>))')->defaults(array(
        'controller' => 'Foo',
        'action'     => 'index',
    ));

Here would be the routing results for some URLs:

  • http://yoursite.com/ will route to controller Foo and action index
  • http://yoursite.com/foo/ will route to controller Foo and action index
  • http://yoursite.com/foo/bar/ will route to controller Foo, action Bar
  • http://yoursite.com/foofoo/bar/ will 404 since no controller Foo exists
  • http://yoursite.com/foo/barnone/ will 404 since no action barnone exists in the controller Foo

Clearly, with just the core routing functionality reviewed in this and Part 1, you have an amazing array of options to exploit. With this alone you can create just about any route pattern you need, but Kohana doesn’t stop there… it also enables you to use regular expression pattern matching. Unfortunately, this feature is too large/complex for this article and will have to be left for a future discussion.

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>