Grundsätzlich bietet CakePHP über Routen recht einfach konfigurierbare Urls. Als Beispiel nehme ich mal das Blog Tutorial. Die folgende Route ruft die Add Methode im PostController auf, um das Template für einen neuen Blog Beitrag zu rendern.
routes.php
$Route->connect('/beitrag/anlegen', array('controller'=>'posts', 'action'=>'add'));
posts_controller.php
function add() {
if (!empty($this->data)) {
...
}
}
Das ist also kein Problem. Jetzt möchte ich aber den neuen Beitrag in der Url nicht über seine ID referenzieren, sondern auch hier eine sprechende Url verwenden.
routes.php
$Route->connect('/beitrag/anzeigen/*', array('controller'=>'posts', 'action'=>'view'));
posts_controller.php
function view($url) {
if ($post = $this->Post->findByUrl(urldecode($url))) {
$this->set('data', $post);
}
}
Falls man das ‘anzeigen’ in der Url weglassen möchte, dann müssen in der routes.php auf jeden Fall alle anderen statischen Urls vor der ‘beitrag/*’ Route stehen.
Jetzt wäre es natürlich schön wenn man neben dem Anlegen, die restlichen CRUD Funktionen auch sprechend verlinken könnte. D.h. man ruft das Editieren eines Beitrags nicht über /beitrag/editieren/nette-urls/ sondern per /beitrag/nette-urls/editieren/ (oder auch /kommentar/anlegen/nette-urls/ vs. /beitrag/nette-urls/kommentar/anlegen/) auf.
routes.php
$Route->connect('/beitrag/:post_url/editieren/', array('controller'=>'posts', 'action'=>'edit'));
posts_controller.php
function edit() {
if ($post = $this->Post->findByUrl(urldecode($this->params['post_url']))) {
$this->set('data', $post);
}
}
Am besten nutzt man eine Komponente, die beim Anlegen eines Beitrags den Titel in eine valide Url konvertiert. Die Url muss natürlich auch eindeutig sein, ein UNIQUE auf das Datenbankfeld und eine entsprechende Prüfung in der Komponente sind also noch nötig. Das könnte dann z.B. so aussehen:
class UrlComponent extends Object {
/**
* lower case without special chars
*/
function getNiceUrl($str, $except=array()) {
$str = strtr($str,"ÀÃÂÃÄÅà áâãäåÇçÒÓÔÕÖØòóôõöøÈÉÊËèéêëÌÃÃŽÃìÃîïÙÚÛÜùúûüÿÑñ",
"AAAAAAaaaaaaCcOOOOOOooooooEEEEeeeeIIIIiiiiUUUUuuuuyNn");
$str = strtolower(trim ($str) ) ;
$str = preg_replace ('/[^a-z0-9\-\.,\*]/', '-', $str) ;
$str = preg_replace ('/([\-\.,\*]{2,})/ue', "substr('\\1', 0, 1)", $str) ;
$str = preg_replace ('/^[^a-z0-9]|[^a-z0-9]$/', '', $str ) ;
$i = 1;
while(in_array($str, $except)) {
$str = $str . '-' . $i;
$i++;
}
return $str;
}
}
3 Responses
andreas waidelich // weblog
August 5th, 2006 at 6:27
1Freundliche URLs, haut ab!…
Allerdings gibt es auch eine Tendez, die den Nutzen von “freundliche URLs” in Frage stellt ……
teemow
August 6th, 2006 at 4:21
2Danke für den Hinweis, das sehe ich genauso. Ich kann zwar nicht behaupten, dass ich schonmal einen Beitragstitel geändert habe, aber das könnte theoretisch mal passieren. Allerdings gibt es neben den URLs für Einträge in einem Blog durchaus noch andere Möglichkeiten, z.b. Tags (http://flickr.com/photos/tags/cake/) oder Userseiten (http://beta.plazes.com/whereis/teemow/). Dort findet sich nach wie vor eine sinnvolle Verwendung für die freundlichen Urls. Und wie oft hat man schon bei php.net im Manual direkt über die Url gesucht?
CakeBakery » favicon.ico und die Nebenwirkungen
September 18th, 2006 at 9:20
3[...] Und wenn man in CakePHP so schön mit netten URLs arbeitet (das ist keine Kritik an den Nice-URLs!), steht im Browser oft sowas hier: http://mein-cooles-projekt.de/produkte/neu/. Für den Browser ist das ein Verzeichnis und so versucht er, aus /produkte/neu/ das Favicon zu laden. Aufrgrund der Verarbeitung der Routen in CakePHP wird dabei aber erneut die Controller-Action aufgerufen, darin wieder die Seite gerendert, nochmal ein Link auf das Favicon gesetzt, usw.. Warum der Controller nun genau drei Mal aufgerufen wird, kann ich nicht genau sagen. Vielleicht ist dies dann auch nur eine Race-Condition, die eine Endlosschleife verhindert. [...]
RSS feed for comments on this post · TrackBack URI
Leave a reply
Letzte Kommentare
Links
Kategorien
Meta