Even when GET
and named
parameters can be useful in most situations, we may need to further optimize our application URLs for better search engine rankings.
Fortunately, CakePHP provides us with route elements, a solution that maintains the flexibility of GET
and named parameters, and improves the way intra-application URLs are built.
We need some sample data to work with. Follow the Getting ready section of the recipe Using GET and named parameters.
app/config/routes.php
file and add the following route at the end of the file:Router::connect('/article/:category/:id-:title', array('controller' => 'articles', 'action' => 'view'), array( 'pass' => array('id'), 'id' => 'd+', 'category' => '[^-]+', 'title' => '[^-]+' ) );
id
, category
, and title
), we need to modify the view to specify the values for those elements. Edit your app/views/articles/index.ctp
view file and make the following changes:<h1><?php echo $article['Article']['title']; ?></h1>
<p><?php echo $article['Article']['body']; ?></p>
<?php if (!empty($articles)) { ?>
<br /><p>Related articles:</p>
<ul>
<?php foreach($articles as $related) { ?>
<li><?php echo $this->Html->link(
$related['Article']['title'],
array(
'action'=>'view',
'id' => $related['Article']['id'],
'category' => strtolower(Inflector::slug($related['Category']['name'])),
'title' => strtolower(Inflector::slug($related['Article']['title']))
)
); ?></li>
<?php } ?>
</ul>
<?php } ?>
CakePHP uses the routes defined in the routes.php
configuration file to generate URLs, and parse requested URLs. When we want different URLs than those provided by the framework, we add new routes to this configuration file.
Routes are created by specifying up to three arguments when calling the Router::connect()
method:
plugin, controller, action
, and action arguments. You may omit parts of these default values, for example, to define a route for all actions in a specific controller.Using Router::connect()
, we defined a route that includes all these arguments:
/article/:category/:id-:title
as our route URL. Notice how we are referring to route elements by prefixing their names with a colon. view
action of the articles
controller. Similarly, if a URL that matches the route URL specified in the first argument is requested, this is the action that will be executed. id
(a number), category
(any string that does not include a dash), and title
(also a string that does not include a dash.) We use the special pass
option to specify which route elements are passed as regular action arguments.When CakePHP finds a URL that includes the same default values as those specified in the first argument of our route, and also includes the route elements specified in its third argument, it will convert the route to our provided string representation. For example, if we create a link using the following statement:
<?php echo $this->Html->link( 'My article', array( 'controller' => 'articles', 'action' => 'view', 'id' => 1, 'category' => 'my_category', 'title' => 'my_title' ) ); ?>
We would be matching all our route requirements, and the resulting generated URL would look like http://localhost/article/my_category/1-my_title
.
When our controller action is executed as a result of a route that uses route elements, we can obtain the values for all the specified elements using the $this->params
array available to every controller.
In our example, we set the id
route element to be passed as a regular action argument, but we did not do so for the remaining elements (category and title.)
To obtain the given value for category
, we would do:
$category = $this->params['category']
Even though CakePHP allows us to specify a string-based URL when creating links, it is recommended that we always use arrays to define link URLs unless the URL is an absolute reference to a foreign site.
URLs that are defined using an array allow for the reverse routing system to work, which is the part of the framework that allows us to use custom routes.
18.116.118.229