QuickTip: Pesky missing layout when requesting extensions
In CakePHP you can use a different layout (other than default.ctp) for all your views by simply changing the $layout property in your controller. I use this to deliver a different layout for, let’s say, the admin panel of the application – or maybe a member area.
Let’s stick with the admin panel example:
$this->layout = 'admin';
Now we all do some neat Ajax or XML here and there sometimes, and for Ajax we probably end up delivering JSON from the very same actions (”Yes, CakePHP is smart like that”). For that you usually start by adding Router::parseExtensions('json') to the routes.php file.
This works fine as long as you don’t call the action for JSON while it is using a different $layout. If we, for example, call /admin/users/index.json, CakePHP will tell us that it is missing the layout view file: APP/views/layouts/json/admin.ctp. Meh!
I am not saying that this is bad. It is actually quiet useful in some scenarios, but in general most people will be happy sharing the same old APP/views/layouts/json/default.ctp with all parts of the application. So… how to fix this?
Add the RequestHandler component to your app and add the following code to your AppController::beforeFilter() method (create the method if needed):
if ($this->RequestHandler->isAjax() && $this->RequestHandler->prefers('json')) {
$this->layout = 'default';
}
Now everytime the browser (client) prefers “json” the layout is switched back to “default”. Simple as that.
You can extend the checks to other formats.
if ($this->RequestHandler->isAjax() || $this->RequestHandler->isRss() || $this->RequestHandler->isXml()) {
$this->layout = 'default';
}
Hope this helps

