Using JSON in CakePHP 1.2

05/06/2007

May 8th 2008 – Controller::$beforeFilter has been deprecated a while ago, i’ve updated the example using Controller::beforeFilter()

Almost an half year ago I created jsonComponent for CakePHP, since then it has been used by quite a few people including myself.

About 3 months ago I started developing with CakePHP 1.2, one of the projects I’m working on is Pagebakery. Pagebakery relies heavily on AJAX and JSON and it’s therefore a perfect opportunity to experiment with CakePHP’s new features.

One of those features is Router::parseExtensions(). ParseExtensions allows you to parse the extension in your request and let Cake select alternate layouts and views automatically.
Another feature I found is JavascriptHelper::object(), this method is also available in CakePHP 1.1 but I only stumbled on it recently. It’s build-in JSON support in CakePHP, we no longer need the jsonComponent!

I’m going to explain you how to setup CakePHP 1.2 to output JSON with help of Router::parseExtensions() and the JavascriptHelper::object() method.

In this example we’re going to use a simple posts controller like the one in the Cake blog tutorial.

First we need to let Cake know to parse .json extentions. Add the following to /config/routes.php

Router::parseExtensions('json');

Because JSON is not a default content type in CakePHP currently, we need to add it. We also need enable the RequestHandler component. Add the following to your app_controller.php

var $components = array('RequestHandler');
function beforeFilter() {
	$this->RequestHandler->setContent('json', 'text/x-json');
}

Note: if you use beforeFilter in your controllers you need to call parent::beforeFilter()

Now we need to create our JSON layout.
Create: /layouts/json/default.ctp
Paste the following code in the new layout

< ?php
header("Pragma: no-cache");
header("Cache-Control: no-store, no-cache, max-age=0, must-revalidate");
header('Content-Type: text/x-json');
header("X-JSON: ".$content_for_layout);

echo $content_for_layout;
?>

Note: the X-JSON header is used by prototype.js and is automatically evaluated into a JSON object.

Next is our view, we’ll use the index action of the posts controller.
Create: /views/posts/json/index.ctp
And insert the following code in the view

< ?php
echo $javascript->object($aPosts);
?>

Note: the object method will convert the posts array into a json string, just like the jsonComponent.

Just to be clear here is the index action from the posts controller

function index() {
	$this->set('aPosts', $this->Post->findAll());
}

Now access your posts controller in your browser, /posts/index/ will output the regular html view and /posts/index.json will output your json object!

Note that you can also use xml, rss (supported by default in CakePHP 1.2) to create your own feed in a snap!

Let me know if you have comments or additions.

Bookmark and Share
Filed under: Cakephp,Webdevelopment