Sluggable Behavior / 10.06.2009

» Leia este post em português aqui.

On the web, “slug” is a short text used in a URL to identify and describe a resource. As Mariano Iglesias’ Sluggable Behavior decription says:

This is particularly useful to create SEO links out of, for example, a table of articles. Instead of seeing those ugly /articles/view/4 URLs, use the Sluggable Behavior and easily accept URLs such as /articles/view/my-seo-friendly-article. It handles the slug creation, slug collision, and allows you to specify different settings such as the separator to use, maximum width of a slug, among other useful parameters.

My Sluggable Behavior is a simpler version of Mariano Iglesias’ Sluggable Behavior with a few add-ons. It’s basically the same thing but instead of implementing all the slug logic on the behavior, it just uses Cake’s Inflector::slug() method. With CakePHP 1.3, this method is really powerful and flexible.

To use it, just place the behavior file on the proper place and call it on the model you want to “slugify”:

var $actsAs = array('Sluggable');

By default, this will automatically create slugs from a field named “title” and place it under a field named “slug”. If you want, you can customize everything. Checkout the configuration keys:

var $actsAs = array(
	'Sluggable' => array(
		'fields' => 'title',
		'scope' => false,
		'conditions' => false,
		'slugfield' => 'slug',
		'separator' => '-',
		'overwrite' => false,
		'length' => 256,
		'lower' => true
	)
);

Those are all the default values. Let’s check what they can do, one by one:

  • fields: as you can see, this is where you define which field will provide the content to the slug. You can inform more than one with an array.
  • scope: after generating a slug, the system will check for similar slugs on the database in order to generate a unique slug. By default, it will scan all your registries, but you can define scopes. Example: you want the system to use an already registered slug on a different category. You can define an array like this: ‘scope’ => array(‘category_id’). The system will only check for records where the “category_id” is the same from the data being saved.
  • conditions: these are extra conditions you can inform. The system will scan for similar slugs previously registered on the database using those conditions as well. They work just like a normal find conditions array.
  • slugfield: the name of the field that will store the slug on the database.
  • separator: the character that will be used to replace white spaces on the slug.
  • overwrite: if true, this will replace the slug from a record on update, otherwise it will be kept untouched on a update.
  • length: this defines the length of the slug text.
  • lower: if false, the behavior won’t make the slug all lower case.

Once again, this behavior is totally inspired by Mariano Iglesias’ Sluggable Behaviour. If you want to help, please comment! Here is the source code:


  • http://blog.ftgoncalves.com Felipe Theodoro Gonçalves

    Olá gostei do seu behaviour porem nos seus exemplos esta errado quando for passar parametros para o behaviour você tem que assosiar

    http://book.cakephp.org/view/90/Using-Behaviors

    seu:
    var $actsAs = array(‘Sluggable’, array(
    ‘fields’ => ‘titulo’,
    ‘slugfield’ => ‘url’
    ));

    certo:
    var $actsAs = array(‘Sluggable’ => array(
    ‘fields’ => ‘titulo’,
    ‘slugfield’ => ‘url’
    ));

  • http://www.eberfdias.com Éber

    @Felipe

    Você está correto! Eu já corrigi ali no artigo ;) Valeu!

  • Mauro George

    Olá Éber sou novo no cakePHP fui testar o seu behavior e encontrei um Big ao tentar incluir o caractere ã, ou º ª §, como você ja esta a mais tempo do que eu no cakePHP ve se tem como seguir a logica de que como definimos no core o charset que estamos trabalhando automaticamente ele o definir aqui, ao invés de como no do Mariano temos que definir ‘translation’ => ‘utf-8′ caso saiba como fazer aconselho ate passar isso ao mariano pois seria mais logico o sistema buscar do proprio core.

    Boa iniciativa, abraço e sucesso,
    Mauro George

  • http://www.eberfdias.com Éber

    @Mauro

    Poisé. O Behaviour que eu fiz usa o método do Core, em Inflector::slug(). Talvez seja o caso de enviar um ticket pro time e pedir que façam essas adições ao método.
    Você pode enviar estes tickets aqui: http://code.cakephp.org/tickets

    Na verdade, eu já divia ter feito isto porque sempre que sai uma versão nova, modifico o core pra suportar pelo menos o ã :P

  • Mauro George

    Uma dica em relação ao behavior do Mariano no site ele diz All future official releases will be posted on this article, no entanto não sei se o projeto foi abandonado ou o que, só sei que estou utilizando a revisão 48 ao inve da anterior que ele fala que sempre mantera atualizada pois a que esta oficial é 36 e esta gera um problema de não adicionar um numero ao final da slug ou seja se criar meu-artigo, duas vezes, depois ele substituira e com a versão 48 ele criara meu-artigo-1 o link da ultima versão é http://cake-syrup.svn.sourceforge.net/viewvc/cake-syrup/trunk/app/models/behaviors/sluggable.php?view=markup

  • eberfreitas

    Oi Mauro!

    Eu não sei se entendi muito bem o seu comentário mas o fato é que o meu behaviour faz exatamente isto, então eu perceber que já existe algum slug com aquele registro, ele vai incrementando um número até encontrar um slug disponível!

blog comments powered by Disqus