PermanentLink Component

Com o intuito de deixar minhas aplicações web mais elegantes, eu sempre costumo usar pretty urls ao invés de passar códigos (ids) pela URL. Ou seja, ao invés de usar: /lerNoticia.php?id=1, eu prefiro usar: /noticia/noticia-qualquer/ . Com isso temos algumas conseqüências boas em relação aos sites de buscas, e umas outras dores de cabeça, mas vamos pensar nas boas primeiro, ok? rs

Com o intuito de gerar essas URLs, criei um component para ser usado no CakePHP. Tá certo que já tem um desses rolando na padaria, mas eu tinha feito o meu primeiro. :)

Primeiramente, salve o seguinte script como: permanent_link.php na pasta /controllers/components/

PHP:
  1. class PermanentLinkComponent extends Object
  2. {
  3. function startup(&$controller)
  4. {
  5. $this->controller =& $controller;
  6. }
  7.  
  8. function genLink($text){
  9. $noaccent    = "aaaaaaaceeeeiiiidnoooooouuuuybsaaaaaaaceeeeiiiidnoooooouuuyyby";
  10. $accent        = "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûýýþÿ";
  11. $text        = strtr(trim($text),$accent,$noaccent);
  12. return preg_replace('/([^.a-z0-9]+)/i', '-', strtolower($text));
  13. }
  14.  
  15. function makePermanentLink($model, $field, $string)
  16. {
  17. $i = "";
  18. $gen = $this->genLink($string);
  19. do{
  20.  
  21. $data = $this->controller->{$model}->findCount("$field = '$gen$i'");
  22. if ($data>0){ $i = ($i=="") ? 2 : ($i+1); }
  23.  
  24. }while($data>0);
  25.  
  26. return $gen.$i;
  27. }
  28. }
  29.  
  30. ?>

Agora no seu controller, você vai usá-lo da seguinte forma:

Primeiro temos que indicar que iremos usar o component PermanentLink neste controller, então:

PHP:
  1. var $components = array("PermanentLink");

E depois é só usar. Para usar temos dois modos. O primeiro gera somente a URL sem verificar se a mesma é única no BD.

Para usá-la:

PHP:
  1. $this->PermanentLink->genLink("texto para gerar a url") ;

isso retornaria:

texto-para-gerar-a-url

A segunda maneira, é verificando se já não existe uma url dessa forma no banco de dados, para usá-la:

PHP:
  1. $this->PermanentLink->makePermanentLink("ModelName","fieldName", "texto para gerar a url");

O retorno será o mesmo. Porém se a url não for única para o campo fieldName do ModelName, ele será automaticamente incrementado. Por exemplo, se a URL gerada fosse: texto-para-gerar-a-url mas ela já existisse no banco, iríamos ter o retorno texto-para-gerar-a-url2 e assim por diante.

Para a técnica de usar URLs mais agradáveis, nem sempre precisamos armazenar a URL no banco, as vezes podemos usar um modelo de URL como a seguinte: /noticias/ler/10/titulo-da-noticia/ sendo que continuamos passando o id (no caso 10) da notícia e passando também a URL gerada, mas consideramos na consulta apenas o id.

No Cake essa noticia poderia ser lida da seguinte maneira: (arquivo /controllers/noticias_controller.php)

PHP:
  1. class NoticiasController extends AppController
  2. {
  3. var $name = 'Noticias';
  4.  
  5. var $components = array("PermanentLink");
  6.  
  7. function ler($id, $url=""){
  8.  
  9. $this->set("dados", $this->Noticia->findById($id));
  10. }
  11.  
  12. }
  13.  
  14. ?>

Assim caso venha ou não a URL, o método seria chamado com sucesso, pegando a notícia equivalente ao id recebido.

Bom pessoal, é isso...

Espero que isso seja útil a alguém, até mais.... Dúvidas, comentem!

6 Comentários »

  1. Danilo Miguel said,

    Janeiro 10, 2007 @ 19:27

    Excelente componente! Estou usando e o resultado é ótimo. Parabéns pela criatividade e disposição em colaborar com a comunidade open source.

    Você vai longe menino!

  2. Guilherme Medeiros said,

    Outubro 12, 2007 @ 01:05

    Seguindo os video tutoriais, resolvi parar na segunda video-aula e implementar o PermanentLink, só que como iria usar no view, transformei o codigo em HELPER, fiz errado?

  3. Guilherme Medeiros said,

    Outubro 12, 2007 @ 03:08

    Hmm, voltei ^^
    Se eu usar como component, como eu faço pra gerar os links? tem alguma forma de usar a função genLink no view, mesmo sendo um componente?? (só consegui com helper..)

    vlww!

  4. Tulio Faria said,

    Outubro 12, 2007 @ 18:54

    Opa Guilherme,

    a idéia de ser um componente não impede de ele vir a ser um helper... :)

    Mas a minha idéia inicial é usar o PermanentLink para gerar um id baseado em um texto o qual seja único e depois fosse persistido no banco de dados.

    Para usar no view, sem precisar criar um helper, use o

    PHP:
    1. $this->set("url", $this->PermanentLink->genLink("Tulio Faria"));

    Vai mandar pro view uma váriavel url com o valor tulio-faria.

    Inté

  5. Guilherme Medeiros said,

    Outubro 13, 2007 @ 02:45

    Opa, também é interessante, mas a minha idéia é gerar o link a partir do foreach (na view) de um findAll. Entende?

    Se não eu teria que pegar o findAll e fazer um foreach no controller pra criar mais um valor na array com a url gerada pelo permanentLink.

    abraços!

  6. Tulio Faria said,

    Outubro 13, 2007 @ 17:26

    Nesse caso compensa usar o makePermanentLink e guardar como um "id" no banco... e ele já será retornado juntamente com os demais dados...

    abraços,

RSS feed for comments on this post · URI do TrackBack

Deixe seu comentário