Symfony Slugify Slug

Lately, I have been working alot with the PHP framework, Symfony.  So far, I’ve been pretty impressed with Symfony’s features.  Model associations are handled much more elegantly than what I have experienced with CakePHP.  The scaffolding and admin generator are also great for quick skeletons for the project models.  Good stuff.

An idea that I had known of from previous apps, but have never been familiar with the term is a slug.  A slug is basically a URL-friendly string for identifying a post, page, user, etc..  It provides a better idea of what the content the URL points to and will actually be about.

There are 4 basic steps in Symfony slugging.  

Create a route for the slugged model in the routing.yml config file using the sfDoctrineRoute class and pass to your model’s show action.  You can add requirements as well.

account_show_user:
  url: /member/:slug
  class: sfDoctrineRoute
  param: { module: account, action: show }
  options: { model: sfGuardUser, type: object }
  requirements:
    id: \d+
    sf_method: [get]

Add the Sluggable behavior to your model in schema.yml and define the field we want slugged.

sfGuardUser:
  actAs:
    Postable: ~
    Timestampable: ~
    Sluggable:
      unique: true
      fields: [username]
      canUpdate: true
  #...

Create a generic project class with the slugify method or behavior (replacing spaces with hyphens etc.).

class Slugz
{
  static public function slugify($text)
  {
    // replace all non letters or digits by -
    $text = preg_replace('/\W+/', '-', $text);

    // trim and lowercase
    $text = strtolower(trim($text, '-'));
 
    return $text;
  }
}

Create the show action within the model’s action file.  Make sure to reference the route object that the routing.yml config file has internally created.

public function executeShow(sfWebRequest $request)
{
  $this->account = $this->getRoute()->getObject();
  $this->forward404Unless($this->account);
}

That’s basically everything.  After you have completed these steps, you should be able to reference your content by a slug of your choosing.