Using the Sluggable behavior

One of the main concerns most applications have is optimizing their content for search engines, so that their sites rank as high as possible on most engines. Among several recommendations found in most SEO (Search Engine Optimization) guides, building URLs that include relevant keywords is one of the most effective ones.

If we are building a content-based site, this is achievable by making sure that permanent links to each item include most of the words that are part of the item title. As an example, if we have a post whose title is Top 10 CakePHP Behaviors, an SEO-friendly URL could be:

http://localhost/articles/view/top-10-cakephp-behaviors.

The top-10-cakephp-behaviors part is commonly known as a slug, a part of the URL that uses relevant keywords. In this recipe, we will learn how to use the publicly available Sluggable behavior to automatically add slugs to our application.

Note

The Sluggable behavior is one of the many classes I released as open source to help fellow CakePHP developers. Feel free to send me any feedback.

Getting ready

To go through this recipe, we need a sample table to work with. Create a table named posts, using the following SQL statement:

CREATE TABLE `posts`(
`id` INT UNSIGNED AUTO_INCREMENT NOT NULL,
`slug` VARCHAR(255) NOT NULL,
`title` VARCHAR(255) NOT NULL,
`text` TEXT NOT NULL,
PRIMARY KEY(`id`),
UNIQUE KEY `slug`(`slug`)
);

We proceed now to create the required model. Create the model Post in a file named post.php and place it in your app/models folder, with the following contents:

<?php
class Post extends AppModel {
public $validate = array(
'title' => array('rule' => 'notEmpty'),
'text' => array('rule' => 'notEmpty')
);
}
?>

Create its appropriate controller PostsController in a file named posts_controller.php and place it in your app/controllers folder, with the following contents:

<?php
class PostsController extends AppController {
public function add() {
if (!empty($this->data)) {
$this->Post->create();
if ($this->Post->save($this->data)) {
$this->Session->setFlash('Post created'),
$this->redirect('/'),
} else {
$this->Session->setFlash('Please correct the errors'),
}
}
}
}
?>

Create a folder named posts in your app/views folder, then create the view to hold the form in a file named add.ctp and place it in your app/views/posts folder, with the following contents:

<?php
echo $this->Form->create();
echo $this->Form->inputs(array(
'title',
'text'
));
echo $this->Form->end('Create'),
?>

Finally, we need to download the Syrup plugin for CakePHP. Go to http://github.com/mariano/syrup/downloads and download the latest release. Uncompress the downloaded file into your app/plugins folder. You should now have a directory named syrup inside app/plugins.

How to do it...

  1. We start by attaching the Sluggable behavior to the Post model. Edit your app/models/post.php file and add the $actsAs property:
    <?php
    class Post extends AppModel {
    public $actsAs = array('Syrup.Sluggable'),
    public $validate = array(
    'title' => array('rule' => 'notEmpty'),
    'text' => array('rule' => 'notEmpty')
    );
    }
    ?>
    
  2. Let's create an action to list posts. Add the following method to the PostsController class:
    public function index() {
    $this->paginate['limit'] = 10;
    $posts = $this->paginate();
    $this->set(compact('posts'));
    }
    
  3. Create the view views/posts/index.ctp with the following contents:
    <div class="paging">
    <?php echo $this->Paginator->prev(); ?>
    &nbsp;
    <?php echo $this->Paginator->numbers(); ?>
    &nbsp;
    <?php echo $this->Paginator->next(); ?>
    </div>
    <br />
    <ul>
    <?php foreach($posts as $post) { ?>
    <li><?php echo $this->Html->link($post['Post']['title'], array('action'=>'view', $post['Post']['slug'])); ?></li>
    <?php } ?>
    </ul>
    

    Next, create the action to view a post by slug. Add the following method to the PostsController class:

    public function view($slug) {
    $post = $this->Post->find('first', array(
    'conditions' => array('Post.slug' => $slug),
    'recursive' => -1
    ));
    $this->set(compact('post'));
    }
    

    Create the view views/posts/view.ctp with the following contents:

    <h1><?php echo $post['Post']['title']; ?></h1>
    <p><?php echo $post['Post']['text']; ?></p>
    <?php echo $this->Html->link('Posts', array('action'=>'index')); ?>
    

    After creating some posts using the form at http://localhost/posts, the list of posts could look like the following screenshot:

    How to do it...
  4. If you hover over the links, you should see SEO-friendly links. For example, for the post entitled Automatic tasks with CakePHP, its URL would be:
    http://localhost/posts/view/automatic-tasks-with-cakephp
    
  5. Clicking on this URL would show the details for the post.

How it works...

The Sluggable behavior implements the beforeSave callback to automatically add the generated slug on the specified field. It ensures that all generated slugs are unique, and provides a full set of options to modify how a slug is generated. The following options can be specified when attaching the behavior to a model:

Option

Purpose

ignore

List of words that should not be part of a slug. Optional, and defaults to: and, for, is, of, and the.

label

Field name (string), or list of field names (in an array) that are used to create the slug. Defaults to a single field named title.

length

Maximum length of the generated slug. Defaults to 100.

overwrite

If set to true, the slug is generated even when modifying a record that already has a slug. Defaults to false

real

If set to true, it will ensure that the field names defined in the label option exists in the table. Defaults to true.

separator

Character to use when separating words in the slug. Defaults to -.

slug

Name of the field where the slug is stored. Defaults to slug.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.67.40