Generate JSON collection of subpages with a route?


I followed this “4-year old” blog-post ( to generate a json file containing a collection of subpages. All is good.

Since I read in other forum posts that you can return a json file of a page more easily by setting up a route, is it possible to get also a collection of subpages in this way?

Related question, how can you style a json template in order to break the content down into a more readable format. eg. with line breaks etc? I mean, I saw there are frameworks but was wondering if kirby does handle this as well.

echo json_encode($json, JSON_PRETTY_PRINT);


Short answer: yes, of course.

1 Like

Have you figured it out or do you need more help?

Thank you for the follow-up:

While looking up for help, I found:

But then I went back to clean up the code for outputting my json in a precise way (Output JSON entry with multidimensional array—YAML adds extra syntax)

I’ll get back to this tomorrow!

In case I’ll write here again.


So I’ve been able to convert the json method from using a template + a folder and empty text file, to the one shown here, below (it’s divided in three files):

// plugins/api.php

$prefix = "api/v1";

    'method' => 'GET',
    'pattern' => "{$prefix}/events",
    'action' => function() {

      // Get the events pages
      $events = page('events')->children()->visible();
      $data = [];

      // Transform for API delivery
      foreach ($events as $event) {
        $data[] = $event->serialize();

      return response::json($data);



// controllers/events.php

return function ($site, $pages, $page) {
  if (get('format') == 'json') {
    $data = [
      'uid'   => $page->uid(),
      'title' => $page->title()->toString(),
      'text'  => (string) $page->kirbytext(),

    die(response::json($data, 200));


// models/event.php

class EventPage extends Page {
  public function serialize() {
    return [
      'uid'     => $this->uid(),
      'url'     => $this->url(),
      'title'   => $this->title()->html()->toString(),
      'text'    => $this->text()->kirbytext()->toString()


Everything works.

I now use this other method to expose my json page’s url to Javascript, as suggested here by the person who made _kirby-json-api.

<script type="text/javascript">
     * Kirby JavaScript settings object. It contains settings and functions that JavaScript code
     * potentially needs to know about when dealing with Kirby
    window.Kirby = {
        baseUrl: '<?php echo $site->url() ?>',
        url: function (path) {
            return this.baseUrl + (path && path[0] === '/' ? path : '/' + path);