Okay, this will require some setup:
I'm working on a method of using nice post title "slugs" in the URL's of my cakePHP powered blog.
For example: /blog/post-title-here
instead of /blog/view_post/123
.
Since I'm obviously not going to write a new method for every post, I'm trying to be slick and use CakePHP callbacks to emulate the behavior of PHP 5's __call()
magic method. For those who do not know, CakePHP's dispatcher checks to see if a method exists and throws a cakePHP error before __call()
can be invoked in the controller.
What I've done so far:
In the interest of full disclosure ('cause I have no Idea why I'm having a problem) I've got two routes:
Router::connect('/blog/:action/*', array('controller' => 'blog_posts'));
Router::connect('/blog/*', array('controller' => 'blog_posts'));
These set up an alias for the BlogPostsController so that my url doesn't look like /blog_posts/action
Then in the BlogPostsController:
public function beforeFilter() {
parent::beforeFilter();
if (!in_array($this->params['action'], $this->methods)) {
$this->setAction('single_post', $this->params['action']);
}
}
public function single_post($slug = NULL) {
$post = $this->BlogPost->get_post_by_slug($slug);
$this->set('post', $post);
//$this->render('single_post');
}
The beforeFilter
catches actions that do not exist and passes them to my single_post
method. single_post
grabs the data from the model, and sets a variable $post
for the view.
There's also an index
method that displays the 10 most recent posts.
Here's the confounding part:
You'll notice that there is a $this->render
method that is commented-out above.
- When I do not call
$this->render('single_post')
, the view renders once, but the$post
variable is not set. - When I do call
$this->render('single_post')
, The view renders with the$post
variable set, and then renders again with it not set. So in effect I get two full layouts, one after the other, in the same document. One with the content, and one without.
I've tried using a method named single_post
and a method named __single_post
and both have the same problem. I would prefer the end result to be a method named __single_post
so that it cannot be accessed directly with the url /blog/single_post
.
Also
I've not yet coded error handling for when the post does not exist (so that when people type random things in the url they don't get the single_post view). I plan on doing that after I figure out this problem.