1 # Routes, URLs, and Links
3 This section will provide you with the basic idea behind Kohana's request routing, url generation and links.
7 As mentioned in the [Request Flow](about.flow) section, a request is handled by the [Request] class which finds a matching [Route] and loads the appropriate controller to handle the request. This system provides much flexibility as well as a common sense default behavior.
9 If you look in `APPPATH/bootstrap.php` you will see the following code which is run immediately before the request is handed off to [Request::instance]:
11 Route::set('default', '(<controller>(/<action>(/<id>)))')
13 'controller' => 'welcome',
17 This sets the `default` route with a uri in the format of `(<controller>(/<action>(/<id>)))`. The tokens surrounded with `<>` are *keys* and the tokens surrounded with `()` are *optional* parts of the uri. In this case, the entire uri is optional, so a blank uri would match and the default controller and action would be assumed resulting in the `Controller_Welcome` class being loaded and eventually the `action_index` method being called to handle the request.
19 Notice that in Kohana routes, any characters are allowed aside from `()<>` and the `/` has no special meaning. In the default route the `/` is used as a static separator but as long as the regex makes sense there is no restriction to how you can format your routes.
23 For organizational purposes you may wish to place some of your controllers in subdirectories. A common case is for an admin backend to your site:
25 Route::set('admin', 'admin(/<controller>(/<action>(/<id>)))')
27 'directory' => 'admin',
28 'controller' => 'home',
32 This route specifies that the uri must begin with `admin` to match and the directory is statically assigned to `admin` in the defaults. Now a request to `admin/users/create` would load the `Controller_Admin_Users` class and call the `action_create` method.
36 The Kohana route system uses perl compatible regular expressions in its matching process. By default the keys (surrounded by `<>`) are matched by `[a-zA-Z0-9_]++` but you can define your own patterns for each key by passing an associative array of keys and patterns as an additional argument to [Route::set]. To extend our previous example let's say you have an admin section and an affiliates section. You could specify those in separate routes or you could do something like this:
38 Route::set('sections', '<directory>(/<controller>(/<action>(/<id>)))',
40 'directory' => '(admin|affiliate)'
43 'controller' => 'home',
47 This would provide you with two sections of your site, 'admin' and 'affiliate' which would let you organize the controllers for each into subdirectories but otherwise work like the default route.
49 ### More Route Examples
51 There are countless other possibilities for routes. Here are some more examples:
54 * Authentication shortcuts
56 Route::set('auth', '<action>',
58 'action' => '(login|logout)'
61 'controller' => 'auth'
69 Route::set('feeds', '<user_id>(/<action>).<format>',
72 'format' => '(rss|atom|json)',
75 'controller' => 'feeds',
82 Route::set('static', '<path>.html',
84 'path' => '[a-zA-Z0-9_/]+',
87 'controller' => 'static',
92 * You don't like slashes?
96 Route::set('gallery', '<action>(<controller>):<id>',
98 'controller' => '[A-Z][a-z]++',
99 'action' => '[A-Z][a-z]++',
102 'controller' => 'Slideshow',
108 Route::set('search', ':<query>', array('query' => '.*'))
110 'controller' => 'search',
114 Routes are matched in the order specified so be aware that if you set routes after the modules have been loaded a module could specify a route that conflicts with your own. This is also the reason that the default route is set last, so that custom routes will be tested first.
116 ### Request Parameters
118 The directory, controller and action can be accessed from the [Request] instance in either of these two ways:
120 $this->request->action;
121 Request::instance()->action;
123 All other keys specified in a route can be accessed from within the controller via:
125 $this->request->param('key_name');
127 The [Request::param] method takes an optional second argument to specify a default return value in case the key is not set by the route. If no arguments are given, all keys are returned as an associative array.
131 The established convention is to either place your custom routes in the `MODPATH/<module>/init.php` file of your module if the routes belong to a module, or simply insert them into the `APPPATH/bootstrap.php` file above the default route if they are specific to the application. Of course, they could also be included from an external file or even generated dynamically.
135 Along with Kohana's powerful routing capabilities are included some methods for generating URLs for your routes' uris. You can always specify your uris as a string using [URL::site] to create a full URL like so:
137 URL::site('admin/edit/user/'.$user_id);
139 However, Kohana also provides a method to generate the uri from the route's definition. This is extremely useful if your routing could ever change since it would relieve you from having to go back through your code and change everywhere that you specified a uri as a string. Here is an example of dynamic generation that corresponds to the `feeds` route example from above:
141 Route::get('feeds')->uri(array(
142 'user_id' => $user_id,
143 'action' => 'comments',
147 Let's say you decided later to make that route definition more verbose by changing it to `feeds/<user_id>(/<action>).<format>`. If you wrote your code with the above uri generation method you wouldn't have to change a single line! When a part of the uri is enclosed in parentheses and specifies a key for which there in no value provided for uri generation and no default value specified in the route, then that part will be removed from the uri. An example of this is the `(/<id>)` part of the default route; this will not be included in the generated uri if an id is not provided.
149 One method you might use frequently is the shortcut [Request::uri] which is the same as the above except it assumes the current route, directory, controller and action. If our current route is the default and the uri was `users/list`, we can do the following to generate uris in the format `users/view/$id`:
151 $this->request->uri(array('action' => 'view', 'id' => $user_id));
153 Or if within a view, the preferable method is:
155 Request::instance()->uri(array('action' => 'view', 'id' => $user_id));