Sluggable behavior will build the slug of predefined fields on a given field which should store the slug
Features:
Update 2011-04-04
Update 2010-12-23
Notice:
Portability:
This article will cover the basic installation and functionality of Sluggable behavior
Content:
If you using the source from github repository, initial directory structure for the extension library should look like this:
...
/DoctrineExtensions
/lib
/Gedmo
/Exception
/Loggable
/Mapping
/Sluggable
/Timestampable
/Translatable
/Tree
/tests
...
...
First of all we need to setup the autoloading of extensions:
$classLoader = new \Doctrine\Common\ClassLoader('Gedmo', "/path/to/library/DoctrineExtensions/lib");
$classLoader->register();
To attach the Sluggable Listener to your event system:
$evm = new \Doctrine\Common\EventManager();
// ORM and ORM
$sluggableListener = new \Gedmo\Sluggable\SluggableListener();
$evm->addEventSubscriber($sluggableListener);
// now this event manager should be passed to entity manager constructor
Notice: that Sluggable interface is not necessary, except in cases there you need to identify entity as being Sluggable. The metadata is loaded only once then cache is activated
namespace Entity;
/**
* @Table(name="articles")
* @Entity
*/
class Article
{
/** @Id @GeneratedValue @Column(type="integer") */
private $id;
/**
* @gedmo:Sluggable
* @Column(name="title", type="string", length=64)
*/
private $title;
/**
* @gedmo:Sluggable
* @Column(name="code", type="string", length=16)
*/
private $code;
/**
* @gedmo:Slug
* @Column(name="slug", type="string", length=128, unique=true)
*/
private $slug;
public function getId()
{
return $this->id;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
public function setCode($code)
{
$this->code = $code;
}
public function getCode()
{
return $this->code;
}
public function getSlug()
{
return $this->slug;
}
}
namespace Document;
/**
* @Document(collection="articles")
*/
class Article
{
/** @Id */
private $id;
/**
* @gedmo:Sluggable
* @String
*/
private $title;
/**
* @gedmo:Sluggable
* @String
*/
private $code;
/**
* @gedmo:Slug
* @String
*/
private $slug;
public function getId()
{
return $this->id;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
public function setCode($code)
{
$this->code = $code;
}
public function getCode()
{
return $this->code;
}
public function getSlug()
{
return $this->slug;
}
}
Yaml mapped Article: /mapping/yaml/Entity.Article.dcm.yml
---
Entity\Article:
type: entity
table: articles
id:
id:
type: integer
generator:
strategy: AUTO
fields:
title:
type: string
length: 64
gedmo:
- sluggable
code:
type: string
length: 16
gedmo:
- sluggable
slug:
type: string
length: 128
gedmo:
slug:
separator: _
style: camel
# or simply:
# - slug
indexes:
search_idx:
columns: slug
$article = new Article();
$article->setTitle('the title');
$article->setCode('my code');
$this->em->persist($article);
$this->em->flush();
echo $article->getSlug();
// prints: the-title-my-code
style (optional, default="default") - "default" all letters will be lowercase, "camel" - first word letter will be uppercase
class Article {
// ...
/**
* @gedmo:Slug(style="camel", separator="_", updatable=false, unique=false)
* @Column(name="slug", type="string", length=128, unique=true)
*/
private $slug;
// ...
}
And now test the result:
$article = new Article();
$article->setTitle('the title');
$article->setCode('my code');
$this->em->persist($article);
$this->em->flush();
echo $article->getSlug();
// prints: The_Title_My_Code
If you want to attach TranslationListener also add it to EventManager after the SluggableListener. It is important because slug must be generated first before the creation of it`s translation.
$evm = new \Doctrine\Common\EventManager();
$sluggableListener = new \Gedmo\Sluggable\SluggableListener();
$evm->addEventSubscriber($sluggableListener);
$translatableListener = new \Gedmo\Translatable\TranslationListener();
$translatableListener->setTranslatableLocale('en_us');
$evm->addEventSubscriber($translatableListener);
// now this event manager should be passed to entity manager constructor
And the Entity should look like:
namespace Entity;
/**
* @Table(name="articles")
* @Entity
*/
class Article
{
/** @Id @GeneratedValue @Column(type="integer") */
private $id;
/**
* @gedmo:Translatable
* @gedmo:Sluggable
* @Column(name="title", type="string", length=64)
*/
private $title;
/**
* @gedmo:Translatable
* @gedmo:Sluggable
* @Column(name="code", type="string", length=16)
*/
private $code;
/**
* @gedmo:Translatable
* @gedmo:Slug
* @Column(name="slug", type="string", length=128, unique=true)
*/
private $slug;
public function getId()
{
return $this->id;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
public function setCode($code)
{
$this->code = $code;
}
public function getCode()
{
return $this->code;
}
public function getSlug()
{
return $this->slug;
}
}
Now the generated slug will be translated by Translatable behavior
Easy like that, any sugestions on improvements are very welcome