Iām creating a route to a json template, for which there is no ārealā page content, so Iām using a custom route. In my config:
'routes' => [
[
'pattern' => 'otherstuff.json',
'action' => function () {
return new Page([
'slug' => 'otherstuff',
'template' => 'otherstuff.json',
]);
}
]
]
Which works, in that it renders templates/otherstuff.json
but as a standard html response, not as application/json
.
I can get around that by including
$kirby->response()->code(200)->type('application/json');
in the template, but that doesnāt feel it has the usual Kirby elegance about it! i.e that route is not really content representation aware.
Is there a āproperā way of building a route that would work for both the default and other content representations?
Use headerā¦ something like thisā¦
'action' => function() {
header('Content-type: application/json; charset=utf-8');
// More stuff...
}
Thats how i did it in Kirby 2, i think it will still fly. If it doesnt, lookup āheaderā in the reference and see what the new syntax is.
And please also mark you thread as a kirby 3 question
Thanks, yes there are a number of places/ways I can set that as a header, but that doesnāt really use the power of content representations as I would like to believe is possible.
For instance this more generic route will match all content representations of that slug:
[
'pattern' => 'otherstuff(.?[a-z]*)', //page with any .ext
'action' => function ($ext) {
return new Page([
'slug' => 'otherstuff',
'type' => $ext, // try and set type (no effect)
'contentType' => $ext, // try and set contentType (no effect)
'template' => 'otherstuff'.$ext, // set template. this works
]);
}
]
On a ārealā page, Kirby would automagically recognise that file extension as a content representation and set headers accordingly. That doesnāt work on this route. Iām sure there is a way to set that in the Page object, but all my guesses have had no effect so far!
Provided that the content representation application.json.php
exists, you can use the render()
method like this:
'routes' => [
[
'pattern' => 'otherstuff.json',
'action' => function () {
$newPage = new Page([
'slug' => 'otherstuff',
'template' => 'otherstuff.jspn',
]);
return $newPage->render([], 'application/json');
}
]
]
Thank you @texnixe, that looks more like it.
Though weirdly, it still doesnāt seem to be setting the contentType headers.
I needed to set the template to the base representation, and the contentType to ājsonā like so:
[
'pattern' => 'otherstuff.json',
'action' => function () {
$newPage = new Page([
'slug' => 'otherstuff',
'template' => 'otherstuff',
]);
return $newPage->render([], 'json');
}
],
Which renders the otherstuff.json.php template, but as if it were html.
I canāt see anything different in comparing the Page object here with a route composed directly of a content pageā¦
(This isnāt critical to me right now btw, more of a theoretical scenario, I guess it would be important if I wanted to set a lot of routes as API endpoints?)
What is in your otherstuff.json.php
template, then??
Not much:
<?php
// $kirby->response()->code(200)->type('application/json');
// ^ required if called via custom route, but not normally.
$data = [];
foreach($kirby->collection("otherstuff") as $child) {
$childArray = $child->toArray();
}
echo json_encode($data);
I have a similar json template that is rendered from a real page, which works fine, so am fairly sure it is related to creating this via a route. But it may not be possible right now, sounds like it could be related to https://github.com/getkirby/kirby/issues/1364