Implement URL aliases in CakePHP
I'm new to CakePHP, though not new at all to MVC frameworks for web development. I'd normally go with Drupal when doing web sites that are not web apps but my employee feels that coding stuff from the ground up is far better than using pre built well tested and working solutions. Sigh.
Anyways, he agreed to at least let me use a framework, and I chose CakePHP because a) I've always wanted to learn it, and b) I love Rails so much I can't honestly go back to Zend once more :) Whatever, I decided to have some Cake so bear with me :)
I set up a whole lot of controllers and stuff implementing all the features of the site, and now I'd need to set up Drupal-like url aliases. Such an alias is something that lets you request http://www.example.com/this-be-me-page and display the same page that you'd have seen if you requested http://www.example.com/pages/42 for example. Or return the same as /article/301 when you type /blog/the-most-excellent-post-ever — I guess you got how it works.
I set up a database and a model such that I can query for the "alias" and retrieve the "internal url", then I'm stuck. It seemed that calling
$html = $this->requestAction($internal_url, array('return'));
would have returned the fully rendered HTML as if my user directly requested $internal_url but it's not the case. I only get the HTML for the action's view, without all the awesome layout stuff.
I'm going this database/controller way because I'd like site's admins to be able to edit the aliases via browser, not by editing some obscure routing directives or the .htacces. It's also much quicker to log in, create a page, set the alias and go out for lunch.
Now: how do I do it?
EDIT Mimicking the be开发者_如何转开发haviour of app/webroot/index.php I wrote this action for my AliasController:
public function parse() {
$alias = $this->request->params['url'];
$record = $this->Alias->findByAlias($alias);
$request = $record['Alias']['request'];
$Dispatcher = new Dispatcher();
$Dispatcher->dispatch(new CakeRequest($request), new CakeResponse(array('charset' => Configure::read('App.encoding'))));
die;
}
Except for the name (it doesn't really parse anything, does it?) it works fine… at least it does what I wanted it to do. But I still feel dirty :) Does anybody have suggestions?
Sorry for the late answer.
What you want to do is to re-do the parse method that CakeRoute uses. This way you can do as you want and parse the entry, and even use database to get the id of a slug like url. it is explain in more detail here you can do it like in the example, and add a if clause that if didn't find anything and (is numeric && !empty()) go as usual id...
Hope this works, i test it in 1.3 it SHOULD work in 2.0 since this is a feature NEW to 1.3 so you can create custom routes (i imagine lot of people had the same problem as you do) so i think it's going to work :)
精彩评论