Adding JSON Feed to your site

Find out how to implement a JSON-based content feed as an alternative to RSS

The XML-based feed formats RSS and Atom have been established for years. They work fine, and have broad support, but they’re also bloated and really inconvenient to implement. RSS was a bet on the back of XML becoming the standard format for content interchange across the web. While XML had a good run, its popularity has started to wane.

One big reason for the decline of XML is that it’s really inpleasant to work with. JSON has rapidly replaced XML as the favoured way to exchange data across the web. In response to this, the JSON Feed spec has been developed as a way to replace XML with JSON for content subscriptions.

Implementing JSON Feed

The format of JSON Feed is really simple, and as ever, you don’t need specific support from Perch or Runway to implement it. We added a JSON Feed for our main news page in a matter of minutes. If your browser supports displaying JSON, you can see it here.

Our news items are held in a Runway Collection called News, so I started by creating a new Master Page as news/json.php and pointed a route to news/feed.json to serve it.

PHP can handle JSON natively, so the best way to build up the feed is not to use a template, but to just work with the data directly.

Setting the top-level information

If you look at the JSON Feed spec you’ll see that, much like RSS, the feed is broken down into a top-level section with information about the feed itself, and then an items section containing the content items themselves.

So the first job is to create a variable $feed to be our data structure, and to start setting those top-level items. As you can see below, I’ve set up items as an array, so we can then loop through our content and append it to the feed.

<?php

	$feed = [
		'version'       => 'https:/​/jsonfeed.org/version/1',
		'title'         => 'Perch CMS News',
		'home_page_url' => 'https:/​/grabaperch.com/',
		'feed_url'      => 'https:/​/grabaperch.com/news/feed.json',
		'icon'		=> 'https:/​/grabaperch.com/assets/img/feedburd.png',
		'favicon'	=> 'https:/​​/grabaperch.com/assets/img/burd1.png',
		'items'         => [],
	];

Adding the content items

As mentioned, the news I want to add is in a collection called News, so the next job is to fetch those items back using the skip-template option. Skip-template gives us access to the content as a PHP data structure, without running it through a template and turning it into a big HTML string.

$items = perch_collection('News', [
				'sort'          => 'entry_date',
				'sort-order'    => 'DESC',
				'skip-template' => true,
				'count'         => 10,
	           ]);

We can now loop through $items and format them according to the properties defined in the JSON Feed spec.

As the body of our news item is entered as Markdown and stored with an HTML version, it makes sense for us to use the content_html property rather than content_text. This will make sure that things like links in the item will be correctly represented in the feed.

if (count($items)) {
	foreach($items as $item) {
		$feed['items'][] = [
			'id'             => $item['_id'],
			'date_published' => date('c', strtotime($item['entry_date'])),
			'title'          => $item['entry_heading'],
			'content_html'   => $item['entry_body'],
			'url'            => 'https:/​/grabaperch.com/news/'.$item['slug'],
		];
	}
}

Output the result

The final steps are to tell the browser that we’re about to send a JSON document, convert our $feed array to JSON, and then output it to the page.

header('Content-Type: application/json');
echo json_encode($feed);

As simple as that!

Who’s to say whether JSON Feed will catch on as a format. What’s promising is that the spec envisages its use for timeline feeds (like Twitter and Facebook use) and not just the basic subscription model we’re used to with RSS. So perhaps that opens the door for more creative uses of JSON Feed in the future, but ultimately only time will tell.

What we can say is that it’s so quick and easy to implement on a Perch or Runway site, you might as well give it a go and see what happens.