Introduction
This is the Lion native URL rewrite engine, delegating the URL parsing from the webserver to Lion itself.
URL rewriting is a method of creating search engine friendly URLs, also known as SEO (Search Engine Optimization) URLs. Dynamic URLs have apparently a negative effect on search engine ranking. To get around this issue the URL rewriting technique is used. URL rewrite tools can examine a website and produce a simplified link for each resource on the website.
i.e. the link:
http://yourdomain.com/index.php?module=invoices&view_id=10948
can be changed to
http://yourdomain.com/invoices/10948.html
As part of a web application usability regarding the URLs, general recommendation is that URLs be chosen so that they:
- Are short.
- Are easy to type.
- Visualize the site structure.
- Are guessable, allowing the user to navigate through the site by using intuition to fid resourcesoff parts of the URL.
Defining a Route
The way to define routes is by adding them to the configuration (by default, the config/routes.xml file)
i.e.
<?xml version = "1.0" standalone="yes"?>
<configuration>
<routes>
<route id="invoice_search" uri-pattern="\/invoices\/$invoice_id\.html$">
<front-controller class="__HttpFrontController"/>
<action controller="invoices" code="search"/>
<parameter name="invoice_id" value="$invoice_id"/>
<variable name="$invoice_id" var-pattern="^\d+$"/>
</route>
</configuration>
In this example we are defining a route for URLs matching the regular expression \/invoices\/$invoice_id\.html$. It is, URLs like /invoices/xxx.html, being xxx a number.
An URL matching this pattern will be routed as following:
- The front controller class to attend the request will be the __HttpFrontController class
- The controller and action to be executed will be the default action within the invoices controller
- A parameter will be appended to the request, being the value of the variable $invoice_id, it is, the number xxx
Note that the way to define variables within the URL regular expression is by ussing the prefix dollar ($) followed by an identifier. In our example, $invoice_id.
It's also important to note that we can also impose a regular expression to restrict the value for a variable. In our example, we are restricting the value for $invoice_id to the pattern ^\d+$.
According to that, the full regular expression that need to matches an URL in order to be routed by the invoice_search route is the following one: \/invoices\/\d+\.html$
i.e.
http://yourdomain.com/invoices/10948.html
Now, let's see a more generic example:
<?xml version = "1.0" standalone="yes"?>
<configuration>
<routes>
<route id="search" uri-pattern="\/$module\/$search_id\.html$">
<front-controller class="__HttpFrontController"/>
<action controller="$module" code="search"/>
<parameter name="search_id" value="$search_id"/>
<variable name="$module" var-pattern="^(invoices|clients|accounts)$"/>
<variable name="$search_id" var-pattern="^\d+$"/>
</route>
</configuration>
In this example, we are reusing the same route definition for the controllers invoices, clients and accounts.
Conditional parameters
Lion allows the use of conditional parameters, meaning parameters that will be added just if a condition is satisfaced.
Conditions can be defined in 2 different ways:
- By checking if a variable has a concrete value, by ussing the if-equals tag.
- By checking if a variable has been set, by ussing the if-isset tag.
i.e., checking the variable value:
<?xml version = "1.0" standalone="yes"?>
<configuration>
<routes>
<route id="search" uri-pattern="\/$module\/$search_id\.$extension$">
<front-controller class="__HttpFrontController"/>
<action controller="$module" code="search"/>
<if-equals variable="$extension" value="html">
<parameter name="use_cache" value="1"/>
</if-equals>
<parameter name="search_id" value="$search_id"/>
<variable name="$module" var-pattern="^(invoices|clients|accounts)$"/>
<variable name="$search_id" var-pattern="^\d+$"/>
<variable name="$extension" var-pattern="^(html|action)$"/>
</route>
</configuration>
In this example, we are adding a variable (use_cache) just in case the extension is 'html'.
i.e., checking if a variable has been set:
<?xml version = "1.0" standalone="yes"?>
<configuration>
<routes>
<route id="search" uri-pattern="\/$module\/$search_id(\_$page_id)?\.html$">
<front-controller class="__HttpFrontController"/>
<action controller="$module" code="search"/>
<parameter name="search_id" value="$search_id"/>
<if-isset variable="$page_id">
<parameter name="pagination" value="1"/>
<parameter name="page_id" value="$page_id"/>
</if-isset>
<variable name="$module" var-pattern="^(invoices|clients|accounts)$"/>
<variable name="$page_id" var-pattern="^\d+$"/>
<variable name="$search_id" var-pattern="^\d+$"/>
</route>
</configuration>
In this example, we are adding 2 variables (pagination and page_id) just if the page_id is set.
The __Uri class
By delegating the URL rewrite to Lion, the URL format depends on the route definitions. Because URL formats are sensible to be changed, is a bad practice to hardcode URLs within the code/templates since they could stop working after changing the URL format within the route specification.
The __Uri class has been designed to cover this aspect. It provides methods to discompound an URL into components as well as to do the inverse task, to compose an URL as from the components.
i.e. Discompound an URL into components:
<?php
//Discompound an url into single elements:
createUri('http://yourdomain.com/invoices/10948.html');
$parameters = $uri->getParameters();
//--> [invoice_id => 10948]
$controller_code = $uri->getControllerCode();
//--> invoices
$action_code = $uri->getActionCode();
//--> default
$route_id = $uri->getRouteId();
//--> invoice_search
//we can also know which front controller attends the request:
$front_controller_class = $uri->getFrontControllerClass();
//--> __HttpFrontController
i.e. Compound an URL as from components:
<?php
//Compound an url from single elements:
$uri2->setControllerCode('invoices');
$uri2->setParameters(array('invoice_id' => 10948));
$uri2->setRouteId('invoice_search');
$url = $uri2->getUrl();
//--> /invoices/10948.html
$url = $uri2->getAbsoluteUrl();
//--> http://yourdomain.com/invoices/10948.html
See the __Uri definition for more information.