Routing

Routing is the process of selecting paths in the controller. In Web:Extend, the controller is divided in 3 parts: the main controller, weeApplication; the frames; and the event within the frames. The main controller first receives the request, translate it into an event and then send it. Routing encompass the creation of an event (or translating it from the request received by the server) and its dispatch to the correct method.

You can use the default routing as described earlier or you can use a custom routing mechanism. It allows you to customize the paths in the URL of your application and to translate these custom URL into valid routes. It is very similar to using mod_rewrite, but is done in PHP directly.

Route translation

Custom routes are applied when translating the event received by the server into an event. This translation happens in weeApplication, before the event is sent to your frames.

Customizing the route is simply applying a regular expression to it. The regular expression is applied to the pathinfo of the request using preg_replace. To specify a route, you have to give a regular expression and its replacement. The replacement must be a valid application route and will be used to determine the frame and event names.

Routes are tested one by one iteratively. The first match will be used to translate the route.

Since it is applied on the pathinfo, the query string of the request is not modified. However, if a query string is found on the replaced route, its parameters will overwrite the parameters from the query string if they share the same name.

For example if you access the URL http://example.org/~worm?user=apple and you have the regular expression /^~(\w+)$/i and its replacement is viewuser?user=$1, then the resulting pathinfo will simply be viewuser and the value of $aEvent['get']['user'] will become worm instead of apple. The worm eats the apple.

Fail-safe routing

Sometimes you might need to redirect all non-existing events to the default event. This can be done automatically simply by implementing the weeFailSafeRouting interface, like this:

<?php

class myFrame extends weeFrame implements weeFailSafeRouting
{
	// ...

	protected function defaultEvent($aEvent)
	{
		doSomething();
	}

	protected function eventSave($aEvent)
	{
		doSave();
	}
}

All events reaching this frame will be redirected to the default event handler, except for the event named save. If you sent an event named update to this frame, for example, it will be handled by the default event handler.

Custom routes

As we saw, routes are defined by the regular expressions and their respective replacement. All configuration variables under the route namespace will be retrieved to be tested as custom routes, in the order they are found in the configuration file.

Regular expression and replacement are defined as follow in the configuration file:

route.regular_expression = replacement
				

The regular expression must not include the slashes and the pattern modifiers. The string regular_expression here literally translate to /^regular_expression$/i. The case insensitive modifier is applied to the regular expression, so REGULAR_EXPRESSION here is the same as regular_expression. The reason for this is because PHP class names are case insensitive too.

If the pathinfo matches /^regular_expression$/i, then it will be replaced by replacement, which will create an event that will be dispatched to the default event handler of the frame named replacement.

Take a look at these lines for a more complete example:

route.is = aboutus
route.~(\w+)/(\w+) = $2?user=$1
route.~(\w+)/(\w+)/(\w+) = $2/$3?user=$1
route.(\d{4})/(\d{2})/(\d{2})/(.*) = viewpost?year=$1&month=$2&day=$3&uid=$4
				

The first line is pretty straightforward. When the pathinfo equals is, the event is sent to the aboutus frame.

The second line matches words. A pathinfo like ~essen/editprofile will translate to editprofile?user=essen, meaning the event is sent to the editprofile frame's default event handler. The value of user will be available through $aEvent['get']['user'].

The last line can be used to format the URL of a blog post, for example. A pathinfo like 2008/11/06/rowo-part-2-simple-is-easy/ will be matched, and will translate to viewpost?year=2008&month=11&day=06&uid=rowo-part-2-simple-is-easy/. All the variables from the query string will be accessible through $aEvent['get'].

Strict routing

By default, if there is no match with a custom route, the framework will try to use the unmodified request to determine the frame and event names and dispatch the event. There is an option however which you can use to make sure only your defined routes will be valid. Simply activate strict routing in the configuration file by setting routing.strict to 1 instead of 0:

routing.strict = 1
					

When a request does not match any route, a RouteNotFoundException will be thrown.