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/
-
class PermanentLinkComponent extends Object
-
{
-
function startup(&$controller)
-
{
-
$this->controller =& $controller;
-
}
-
-
function genLink($text){
-
$noaccent = "aaaaaaaceeeeiiiidnoooooouuuuybsaaaaaaaceeeeiiiidnoooooouuuyyby";
-
$accent = "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûýýþÿ";
-
}
-
-
function makePermanentLink($model, $field, $string)
-
{
-
$i = "";
-
$gen = $this->genLink($string);
-
do{
-
-
$data = $this->controller->{$model}->findCount("$field = '$gen$i'");
-
if ($data>0){ $i = ($i=="") ? 2 : ($i+1); }
-
-
}while($data>0);
-
-
return $gen.$i;
-
}
-
}
-
-
?>
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:
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:
-
$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:
-
$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)
-
class NoticiasController extends AppController
-
{
-
var $name = 'Noticias';
-
-
-
function ler($id, $url=""){
-
-
$this->set("dados", $this->Noticia->findById($id));
-
}
-
-
}
-
-
?>
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!

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!
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?
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!
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
Vai mandar pro view uma váriavel url com o valor tulio-faria.
Inté
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!
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,