Remove need for Template files when using JSON API

Hi,

I’m quite new to using Kirby. I’m looking to use the JSON Content Representation in conjunction with my front-end Nuxt app. I’ve been following along with the docs here:

https://getkirby.com/docs/guide/templates/content-representations#creating-a-representation

However, I’m unsure how to completely remove the need for the .php template files, leaving just the .json.php files to identify the data I want to retrieve from Kirby.

Is there a way to make the $data array in just one file, removing the need to have an empty template file alongside the JSON one?

I’d appreciate any help on this.

Thanks

Yes, use the default template (without the json bit) to return your json.

When I do that I get the following error:

http://127.0.0.1:8000/about.json not found

Would this be due to my routing being set up in a certain way?

You would have to remove the json bit from your request in that case as well…

I’ve removed the .json from the end of the request. I now get a 304 Not Modified. Does this mean that my data has not been added to the response?

For ref my about.php now looks like this:

<?php

$data = [
    'title' => $page->title()->value(),
    'email' => $page->email()->value(),
    'phone' => $page->phone()->value(),
    'address' => ['html' => $page->address()->kt()->value()],
    'text' => ['html' => $page->text()->kt()->value()],
    'social' => array_values($page->social()->toStructure()->map(function ($social) {
        return [
            'url' => $social->url()->value(),
            'platform' => $social->platform()->value()
        ];
    })->data())
];

echo json_encode($data);

What if you call the endpoint in a Rest tool or open it directly in the browser?

If i hit localhost:3000/about.json I only get some of the data back:

{
title: "About us",
text: {
html: "<p>Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts. Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean. A small river named Duden flows by their place and supplies it with the necessary regelialia. It is a paradisematic country, in which roasted parts of sentences fly into your mouth. Even the all-powerful Pointing has no control about the blind texts it is an almost unorthographic life One day however a small line of blind text by the name of Lorem Ipsum decided to leave for the far World of Grammar.</p> <p>The Big Oxmox advised her not to do so, because there were thousands of bad Commas, wild Question Marks and devious Semikoli, but the Little Blind Text didn’t listen. She packed her seven versalia, put her initial into the belt and made herself on the way. When she reached the first hills of the Italic Mountains, she had a last view back on the skyline of her hometown Bookmarksgrove, the headline of Alphabet Village and the subline of her own road, the Line Lane. Pityful a rethoric question ran over her cheek, then she continued her way. On her way she met a copy.</p>"
}
}

I’m expecting all the data from the array in the above post to be returned…

But with a standard about.php template, your request should go to /about not /about.json. There shouldn’t be an about.json.php template anymore.

Content representations only make sense, if you also use the standard PHP template, that’s why they are called representations. And that’s why the standard template is required.

So you have to either add an empty standard template, and use the json variant for your JSON stuff. Or remove the JSON template, and use the standard template for your JSON.

Okay. So if I remove the json from the file name, leaving me with about.php, what url do I need to enter to access to the api data?

Only about without .json.

I now don’t have acess to the data in the same way I did before… must be something wrong with my Vue setup. I’m getting:

Cannot read property 'title' of undefined

When trying to output page.title

This is my request:

const getPage = async id => {
  const resp = await axios.get(`${apiUrl}/${id}`)

  console.log(resp.data)

  return resp.data
}

Your template doesn’t set the response type header. Try this:

<?php

$data = [
    'title' => $page->title()->value(),
    'email' => $page->email()->value(),
    'phone' => $page->phone()->value(),
    'address' => ['html' => $page->address()->kt()->value()],
    'text' => ['html' => $page->text()->kt()->value()],
    'social' => array_values($page->social()->toStructure()->map(function ($social) {
        return [
            'url' => $social->url()->value(),
            'platform' => $social->platform()->value()
        ];
    })->data())
];

echo $kirby->response()->json($data);

This is only necessary because you don’t use the content representation feature as Kirby now can’t know what the content type of your template is.