Post Format

Easy CakePHP permalinks and URL slugs with SluggableBehavior

I put together a CakePHP behaviour for generation of permalinks as a record is saved to the database.
This has been shown to help with search engine optimisation, getting important keywords and phrases into your site URLs.

Go from this: http://example.com/posts/view/23

To this: http://example.com/posts/view/great-new-widget-product-released

  • Specify a source field from which the slug should be generated (e.g. column “headline” : ‘The Great & the Good’)
  • Specify a database field into which the slug should be stored (e.g. column “slug” : ‘the_great_the_good’)
  • Automatically handle potential duplicates, adding numerical suffixes accordingly
  • Keep slugs constant even when source field changes (for true permalinks)
  • Slug may be manually overridden without problems by putting it into the data array being saved in Cake

Download the source file

Pick up the sluggable.php file from Github and put it in your CakePHP app (folder is /app/models/behaviors/).

Set up your database field

Create a VARCHAR column in the relevant database table. The default column name is “slug”, so stick with that unless you have any reason to do otherwise.

URLs have a length limit, so I recommend a maximum slug field length of 100 to leave room for the rest of the URL

Add the behaviour to your CakePHP model(s)

For the basic installation, add the following to the correct model in your CakePHP app (or adjust your $actsAs model member variable to include Sluggable):

var $actsAs = array(
	'Sluggable' => array(
		'title_field' => 'title'
	)
);

 

The title_field is the database field from which the slug will be generated – usually the title of your record. You can specify a few other options, the default values for which are shown below:

var $actsAs = array(
	'Sluggable' => array(
		'title_field' => 'title',
		'slug_field' => 'slug',
		'slug_max_length' => 100
	)
);

 

Check that the maximum length matches the length of your VARCHAR field.

Update your controllers and views

Here’s a basic controller action example to pull a single record using its permalink instead of its ID:

function view($permalink=null)
{
	$post = $this->Post->findBySlug($permalink);

	if (!$post){
		$this->cakeError('error404');
	}
	$this->set('post', $post);
}

 

Links to this page would look like this:

http://example.com/posts/view/my_great_news_story

Using the HTML helper to generate the link:

$html->link('Great Story', array(
	'controller'=>'posts',
	'action'=>'view',
	$post['Post']['slug']
));

 

That’s that!

Comments are closed but I'd love to hear from you via a reply on your own blog, my contact form or Twitter.