Adding search engine friendly URL’s (Slugs)

Posted on: August 5th, 2009 by taff No Comments


I was looking for a quick way to add search engine optimised URL's to my cakePHP application and was amazed at how fast it was setup.

These are the (extremely simple) steps that I took.
Add a slug field to my database table

ALTER TABLE `the_table_name` ADD `slug` VARCHAR(255) NOT NULL;

Update our table to add slugs, related to the title

For the sake of ease I simply added an extra line to my edit method. This doesn't check anything and will resave the slug whenever the title is changed...but it worked for testing 😉

if (!empty($this->data)) {
$this->data['Controller']['slug'] = Inflector::slug($this->data['Controller']['title_we_want_adapted']);
if ($this->Controller->save($this->data)) { $this->Session->setFlash(__('Saved', true));
} else {
$this->Session->setFlash(__('Not saved. Please try again.', true));

Note our use of the built in Inflector::slug class method. We should probably have converted to lowercase too.

The next step was to change links that previously pointed to
to now point to

What's left to do? Well if we click on our newly generated link, it probably won't find the row it needs because it will be doing something like:

SELECT * FROM `the_table_name` WHERE `id` = the_slug_we_generated;

I personally already had a beforeFilter() in my controller to prevent users accessing Lists that didn't belong to them so I updated it in the following way to ensure that both slugs and id would work (May come in handy if people have links bookmarked with the old method).

function beforeFilter() {
//Are there any parameters for this action, i.e. is it an edit or view
//Is it numeric, in which case its an id already (we hope at least)
//If its a slug, we need the related item.
//So we know it's using a slug
$this->currList=$this->Dolist->find('first', array("conditions"=>array(''=>$id)));
//Check User stuff
$this->Session->setFlash("You're not authorised to ".$act." ID:".$this->params['pass'][0]." or it no longer exists");



I then updated my view method

function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid Dolist.', true));
//Carry on as normal....

For search engine optimisation we should probably set a redirect in the controller if it's an ID but thats up to you.

Don't you just love how easy things are to setup with cakePHP? 😉