
In my last post I mentioned that there’s a change in the works for Kohana 2.3, and I wasn’t lying! If you watch the forum then you will of certainly seen some discussions on it, of particular note are:Routing in 2.3 and 2.3 Routing Examples.
I think initially the change was met with skepticism , as these things so often are, people don’t like future compatibility issues, which is understandable, but in this case I think the additional advantage gained is great enough to offset this potential cause of frustration. Hopefully this post will outline some of those benefits to you, allowing you to make up your own mind!
Configuration
So the first thing you will notice is that routing is now configured
differently, imo when you get to grips with that is going on then it is
actually now SIMPLER to setup more complex routes, you can now achieve
scenarios with equal or greater flexibility to those of before but without the
use of any regular expressions. The new default route is as follows:
$config['default'] = array
(
// Default routing
':controller/:method/:id',
// Defaults for route keys
'controller' => 'welcome',
'method' => 'index',
);
$config[‘default’] Now this may or may not appear self-explanatory, we’ll go through it anyway! Routes are now given a name, this route is called ‘default’, the name itself is not technically important, though we will come to their usage later!
‘:controller/:method/:id’ This is the definition of our routing arguments, prefixing a segment with a colon ‘:’ makes it a router argument, and interpretable as such, :controller and :method are ignored as arguments and if present are used as you would imagine (:controller is used as the request controller, :method for the method)
‘controller’ => ‘welcome’,’method’ => ‘index’, Here we set the defaults, this basically says that if the controller is not present then use the ‘welcome’ controller and the ‘index’ method within it. If controller is present with no method then use the index method within whichever controller
Play Time Confused? maybe, but with that under our belt we can now start playing around with this. Best way to get to grips with this is to grab a checkout of the development head (http://source.kohanaphp.com/trunk (or http://dev.kohanaphp.com/browser/trunk if your more graphically inclined)) and set yourself up a sandbox! Once installed if you go to your local address you should be presented with the nice new green welcome page.
New Controller Create yourself a new controller ‘Page’ (remember controllers are now defined as ‘class Controller_Page’), and give it an empty index method which echos your favorite hello world substitute before exiting. Going to
Going to
If we wanted to capture that fourth segment potentially then we could change our default route to:
$config['default'] = array
(
// Default routing
':controller/:method/:id/:style',
// Defaults for route keys
'controller' => 'welcome',
'method' => 'index',
);
Above we have added another router argument called ’style’, visiting our page with 4 segments no longer gives us an error … making any more sense yet?
Accessing URI parameters (arguments)
So above we have seen how to add additional parameters to the route, how can
we access these named parameters? Router::$arguments is the answer, add to
your index method in your page controller the following, then visit your four
segment route again:
var_dump(router::$arguments['style']);
Very nice. We now have a nice, unified way of accessing these named parameters.
Practical Example
So lets now run quickly through a practical example to demonstrate some more
of the functionality we can leverage from this . .yes there is more!
Lets re-use our page controller and add a blog_posts function to it. We define the following route:
$config['blog_post'] = array
(
// Default routing
'post/:year/:month/:day',
// Defaults for route keys
'controller' => 'page',
'method' => 'blog_post',
'year' => date('Y'),
//Ensure we get the correct date formats!
'regex' => array(
'year' => '[0-9]{4}',
'month' => '[0-9]{2}',
'day' => '[0-9]{2}'
)
);
The above has introduced the regex functionality, hopefully it is relatively self-explanatory there. We can basically provide individual regex patterns for each of our defined url arguments, which makes for some really nice and simple pattern matching options. Also note how we define our default year to be the current one, very simple, very effective and very future proof! All from the routing configuration.
Add the below function into your Page controller (from before):
public function blog_post()
{
$year = router::$arguments['year'];
$month = isset(router::$arguments['month']) ? router::$arguments['month'] : null ;
$day = isset(router::$arguments['day']) ? router::$arguments['day'] : null ;
echo "Blog Post";
var_dump($year);
var_dump($month);
var_dump($day);
exit;
}
Now visit
Reverse Routing
Just to finish this off lets take a look at what really tidies all this up
into a neat package: Reverse routing. This allows us to generate application
links using our configured routes set-up. For instance:
echo router::uri('blog_post', array(
'year' => '1983',
'month' => '08',
'day' => '22')
);
The above will now happily generate the route post/1983/08/22. On its own not to fantastic, and it came at the price of a slightly longer link generation syntax. However as some of you are probably realising if we ship this app over to the states where they do everything backwards ( :) ) we now want to switch our urls to read ‘post/:year/:day/:month’, so by making that ONE change in our routes config every single one of our application links will now match this backwards way of doing things, and because we retrieve our url arguments by name none of our code will be affected . . truly awsome. Reorganising methods and controllers is no longer an issue either. Play around with it and see what you think. Hopefully you will be impressed!
Breath - That turned out to be a bit longer than anticipated so hopefully you got all the way through it, as usual any problems, glaring omissions then please don’t hesitate to drop me a line!
/Matt