by Daniel | hits(14340)
TAGS: cakephp routing SEO normalize slug string friendly urls
Do you ever wanted to achieve SEO friendly urls?
Namely forget those ugly id-driven request like
www.mysite.com/posts/view/3
and switch to something more human readable like including the title of the post in the url
www.mysite.com/posts/view/3:the_title_of_my_post
But what if the title of the post contains strange accented etc characters?
Well in irder to normalize it I recently discovered that in CakePHP 1.2.RC3 there is a new snifty method in the Inflector class:
Inflector::slug()
This method converts all special chars into their url friendly counterpart (à=>a, è=>e, ö=>oe, etc).
From the CookBook:
"Slug converts special characters into latin versions and converting unmatched characters and spaces to underscores. The slug method expects UTF-8 encoding."
It does not convert the string to lowercase, and doe not cut it if it is too long.
A custom function that you can place in your CakePHP app/bootstrap.php can be:
/**
* Returns a lower case string with all spaces converted to $replacement and non word characters removed.
*
* @param string $string
* @param string $replacement
* @param int $length max string length
* @return string
* @access public
*/
function slug($string, $replacement = '_', $length = 100) {
$string = strtolower(Inflector::slug($string));
if (strlen($string) > $length) {
$string = substr($string, 0, $length);
}
return $string;
}
To tell your Router to ignore the slug part of the url keeping both the numeric ID and the slug in the url you can write something like this in your app/config/routes.php
Router::connect('/posts/view/([\d]+):(.+)', array('controller' => 'posts', 'action'=>'view'));In this way you can even avoid to store the post slug in DB and simply use the slug() function to build links like:
$html->link($post['title], '/posts/view/'.$post['id'].':'.slug($post['title]));
Happy baking!
view/hide comments | add comment
2009-05-15 20:02:05
You forgot to add the $replacement variable in the Inflector::slug method e.g.
$string = strtolower(Inflector::slug($string, $replacement));
powered by 4webby.com