Skip to content

Content from an API

Enrich your site with content fetched from any API

For this example, we use a freely accessible API, in this case the New York Times Movie Review API. To follow this example, create an account and an example app by following the instructions.

First, create a parent page, e.g. reviews in the /content folder and inside it, a reviews.txt text file.

/content/reviews/reviews.txt
Title: Movie reviews

----
Intro: This page lists all available movie reviews from the NYT movie review API.

This page will serve as our model for child pages.

The page model

In the Reviews page model, we redefine the children() method to get the subpages from the API instead of from the file system:

/site/models/reviews.php
<?php

class ReviewsPage extends Page
{
    public function children()
    {
        $results = [];
        $pages   = [];
        $apiKey  = 'put-your-api-key-here';
        $request = Remote::get('https://api.nytimes.com/svc/movies/v2/reviews/picks.json?api-key=' . $apiKey);

        if ($request->code() === 200) {
            $results = $request->json(false)->results;
        }

        foreach ($results as $key => $review) {
            $pages[] = [
                'slug'     => Str::slug($review->display_title),
                'num'      => $key+1,
                'template' => 'review',
                'model'    => 'review',
                'content'  => [
                    'title'    => $review->display_title,
                    'headline' => $review->headline,
                    'byline'   => $review->byline,
                    'summary'  => $review->summary_short,
                    'date'     => $review->publication_date,
                    'link'     => $review->link->url,
                    'linkText' => $review->link->suggested_link_text,
                    'cover'    => $review->multimedia->src
                ]
            ];
        }

        return Pages::factory($pages, $this);
    }
}


Replace api-key with the API key you got for your app.

Using the Remote::get() method, you connect to the API and fetch the results. Within the foreach loop, you feed the results into the $pages array and finally pass it all to the Pages::factory() method.

The overview template

The pages are now accessible in the template and you can loop through them like through a normal set of Kirby pages, using the fields defined in the content array:

/site/templates/reviews.php
<?php snippet('header') ?>

<main>
  <header>
    <h1><?= $page->title() ?></h1>
  </header>
  <ul>
    <?php foreach ($page->children() as $review): ?>
    <li>
      <h2><?= $review->title() ?></h2>
      <a href="<?= $review->url() ?>">Read review summary</a>
    </li>
    <?php endforeach ?>
  </ul>
</main>

<?php snippet('footer') ?>

The child page template

For the children themselves, you can create their own review.php template to access more defails:

/site/templates/review.php
<?php snippet('header') ?>

<main>
  <article class="review">
    <header>
      <h1><?= $page->title() ?></h1>
      <time><?= $page->date()->toDate('d F Y') ?></time>
    </header>

    <h2><?= $page->headline() ?></h2>
    <p>by <?= $page->byline() ?></p>
    <?= $page->summary() ?>

    <?php if ($page->cover()->isNotEmpty()): ?>
    <img src="<?= $page->cover() ?>" alt="">
    <?php endif ?>
  </article>
</main>

<?php snippet('footer') ?>

The result

The result could then look something like this: