matthew ephraim

Archive for the ‘cakephp’ Category

Some CakePHP requestAction….action

Tuesday, November 6th, 2007

I’ve spent the last few months writing a portfolio system for Columbia College using CakePHP. One of the requirements was a template system that would allow students to choose different templates for their personal sites. I thought it would be a nice feature for users to have a template preview page that allowed them to choose a template from a menu and see what the template would look like with their data.

Initially, I built two separate views. One for the displaying the actual live site, and one for displaying the preview of the site. The two views were nearly identical, aside from a small menu bar at the top of the preview page. I didn’t like the idea that the code was repeated, so I thought that an element might be the solution. However, the templating system required some setup in the controller before the view was actually rendered. This was a problem because the template preview page was not in the same controller as the view for the user’s public page. More repeated code.

I started looking into the requestAction method, but I couldn’t find a whole lot of information about it. Some of what I did find was pretty negative. The manual suggests that one of the uses of requestAction is to retrieve data from another controller. I’m not so sure about using it for that sort of thing. To me, it seems like common data retrieval functions should go in the model. But rendering one action inside of another seemed like the perfect use of requestAction.

To create a dynamic preview page, I created a view with the menu bar that I wanted to appear above the site when it was being previewed. Then, where I wanted the templated page to be rendered I used requestAction to call the action that displayed the public site:

CakePHP
$this->requestAction("/$site_url/$preview_path", 
                      array('template_id' => $template_id));

URLs for the site are structured with the student name and the name of the action being called: /student_name/action_name. Using requestAction I can call those urls, which get handled by the public controller. One caveat is that a view called by requestAction will render without a layout. In this case, that was exactly what I wanted, because the preview page was providing the layout for view.

But how does controller choose which template to render? That’s where the second parameter to requestAction comes in. The preview controller sets a template id based on the template the student chooses from the preview menu. The public controller also uses a template id, but that template id is stored as part of the user’s profile. To get the public controller to use the template id from the preview controller, I needed to pass it on somehow. The second parameter to requestAction allows you to pass an array of extra parameters on to the controller being called. Those extra parameters show up under $this->params in the controller being called. On the preview page I pass on a parameter called template_id. In the public controller I check for that parameter and if it’s not present I default to the user’s selected template:

CakePHP
$template_id = isset($this->params['template_id']) ? 
	             $this->params['template_id'] :
		     $this->user['Options']['template_id'];

Aside from the template id change, the public controller behaves like it normally would, allowing the user to see a templated preview of their site.

So far, I haven’t seen any other practical uses for requestAction that couldn’t be better addressed by other features of CakePHP, but I’m curious about what other reasons people can find to use it.