Generating JSON with Kirby
With Kirby, you cannot only generate HTML output. In this recipe, we will explain how to generate JSON with Kirby using content representations. If you've never heard about JSON, this tutorial is probably not for you, but you should definitely learn more about it – it's awesome!
Kirby's template system does not really care what you build with it. In fact you could even generate an Excel spreadsheet with the data of your site – though nobody wants that :)
Content representations allow you to output the content in different formats. Be it JSON for your AJAX script or to use Kirby as API for other tools, an automatic RSS feed representation of your blog or a plain text representation of your résumé.
For this tutorial we are going to build a little JSON content representation for our blog (alongside your HTML blog template), which will provide a list of articles as JSON string. You could use that to add endless scrolling for your blog for example, or to load blog articles dynamically in an app or some other fancy way.
Content structure
The content structure for the blog will be something like this:
Please read the article about how to build a blog with Kirby, if this seems weird to you.
Content representation for the blog
In this example we will create a JSON representation of the blog
template. After we are done, our blog page will not only be able to viewed as HTML but also be available in JSON. We will see below how exactly that works.
A representation is defined by its representation template. For our JSON representation, let's create a file blog.json.php
in our /site/templates
directory.
Create the template
Open the new template file and add the following code:
It might look a bit frightening first, but let me explain this a bit more.
1. Fetching the data
What we want is to fetch the same list of articles, which we use to build our regular blog template. First we are going to find the blog page -> then we select all children -> make sure to get the published children only -> and finally flip them to get the latest article first.
2. Building the result
Once we've got our list of articles, we should build a nice array out of it, which we can use to generate JSON. The main goal of JSON is to reduce the amount of data, which is transfered between the client and the server, so you should only go on with the data you really need. In this case I create one big array of arrays ($json
), with an nested array for each article.
There's one little thing you need to consider, when building that array. All the custom variables (title, text, date, etc.) are not just simple strings in Kirby, but objects. It's beyond the scope of this article to explain why, but what you need to do is to make sure those objects will be converted to strings by using (string)
:
3. Returning JSON
Once your $json
array is ready, you need to convert this to a json string with the native PHP json_encode
function.
This will echo the entire array as a JSON encoded string. The template does not generate any HTML at all.
You don't need to manually send a content type header as Kirby will do that for you based on the representation type. Here, the response will automatically be sent with the content type application/json
.
Using your JSON representation
You can now access the JSON of your blog with javascript or however you plan to use it. I'm using plain javascript here to make a little example call. I guess it will be the most common tool to do this.
Example call
Using content representations, the URL for the JSON will become https://yourdomain.com/blog.json.
Securing your JSON
If you want to avoid that someone else is accessing the JSON, you can add a custom header to your request which may then be validated by the server. In contrast to the superseded XMLHttpRequest()
, fetch()
doesn't set a X-Requested-With
header by default. We simply add it ourself.
First, modify your JavaScript code to pass along the header with a body of your choice:
Since the custom header alone won't secure anything, we will have to create a route for JSON requests, which validates the header's body.
Because it is a convenient way to test the generated JSON directly in the browser via the URL, we only validate the requests in production mode.
Now whenever a regular request is coming in and the X-Requested-With
doesn't match, go(url('error'))
will be called, which redirects the visitor to the error page.
Pagination
Depending on the size of your blog, you migh want to add pagination to your JSON response.
Since we added ->paginate(10)
to the definition of our pages collection, you can now easily jump to different pages like this:
The entire code
Here is the entire code for this example:
Next steps
It's up to you what you build with this on the front-end. I'm sure you already got some great ideas :)
This tutorial is not limited to a blog-scenario. You can easily adapt this to make other parts of your site available as JSON. You could even build a port to XML or CSV. There are hardly any limits.