(this is a work in progress)
This tutorial explains basic usage of Tipos_Controller_Router, an extended front controller with built-in flexible routing mechanism.
Tipos_Controller_Router, or the “router controller”, is a class that extends Solar_Controller_Front to provide more flexibility and control for URI's. It allows virtually any URI scheme to be used in Solar apps, “routing” to the right controller and action. Also, it abstracts URI building and fetching processes, so URI schemes for entire apps can be changed in an unique place. Additionally, it allows the use of “modules”, or groups of controllers inside subdirectories.
The router controller can be used with existing Solar apps with no required changes, since it provides total backwards compatibility. Basically, if no routes are defined for the router controller, it will fall back to Solar_Controller_Front. Alternatively, if a route ”:controller/:action/*” is set, it will emulate the default routing mechanism from Solar_Controller_Front.
Route classes and the routing mechanism were ported from Zend Framework's excellent Zend_Controller_Router_Rewrite. You need a basic understanding of the routing mechanism to use the router controller, so if you are not familiar to the idea of routes, please read first the related page here at ZF's manual. Although the API is not exactly the same, the concept is and it may be easy to find the equivalents in Tipos_Controller_Router.
All required classes and code to use the router controller are described in [wiki:tutorials/Router/Setup Router Setup]. You will need them 'before' you start! :)
To start using the router controller, simply call it instead of Solar_Controller_Front as your front controller, in your bootstrap file:
<?php // Load and start Solar. require_once 'Solar.php'; Solar::start('config.php'); // Instantiate and run the router controller. $front = Solar::factory('Tipos_Controller_Router'); $front->display(); // Done! Solar::stop(); ?>
You'll notice that your apps still work perfectly. Good. :) This is because, as mentioned earlier, it is 100% compatible with existing Solar apps. If you don't have any routes set, it will just fall back to Solar_Controller_Front.
Now, let's set some routes. There are different strategies for this, and with time they all will be described. Summarizing, you can:
To start, I'll set some routes in the config file, because it is probably the most simple method. If 'routes' are set in Tipos_Controller_Router's config, the controller will automatically instantiate the proper route classes using the config data, so no changes are needed in the bootstrap to add the routes to the controller.
It may be a good idea to use a new config file to define the routes, for easier management. I will use 'routes.php' in the example below, but the 'routes' value can be set directly in the config as an array. I just prefer to use a separate file to make things more clean.
<?php $config['Tipos_Controller_Router'] = array( 'routes' => include dirname(__FILE__) . '/routes.php', ); ?>
Here's routes.php:
<?php $routes = array(); // Generic module route. $routes['module'] = array( 'route' => ':module/:controller/:action/*', 'defaults' => array( 'module' => 'news', 'controller' => 'base', 'action' => 'index', ), 'route_class' => 'Tipos_Controller_Route_Route', ); return routes; ?>
In the array above, we have set a generic route for modules. It allows you to divide apps in 'modules' / subdirectories, organizing things better.
Let's see what will happen:
Note The 'route_class' definition is optional. By default it will use Tipos_Controller_Route_Route, so in this example it is not necessary. In case you want to use other route class than the default one, that's how you can define it.
One of the advantages of working with the router controller is the possibility to use named parameters. When a route matches, the correspondent URI parts will be set in the front controller as a keyed array. Then you can get the uri parameter inside your app using a name, instead of a number, which is easier to recognize and order proof.
You can get the parameter calling the method _param(), which is an equivalent of Solar_Controller_Page's _info(). While _info() returns a URI parameter based on position (integer), _param() returns URI parameter based on name (string).
Good, now we have access to the route parameters. Let's see how clear it is to access URI parameters. Suppose you have a route '/news/:category', routing to your 'News' app. Inside any action, you can check if a category is set with:
<?php // Get the category, or set it to 'general' if it is not set. $category = $this->_param('category', 'general'); ?>
In this example, it will return the category value, if it is set, or “general”, which is the value we defined as default. If no default value is defined, it will just return null. If you're used to Solar, you have already noticed that _param() is almost identical to Solar_Controller_Page's _info(); the only difference is that you work with named parameters instead of parameters positions.
Well, it is not a deep explanation, but I hope this can help people to try the router controller. By now just basic setup and info is given, but with time I'll try to improve this tutorial with more examples. If you have doubts, contact me through the solar-talk mailing list or in the IRC channel #solarphp at freenode.org.
Have fun! :)
– rodrigo moraes