Change content representation in page controller?

How do I change the content representation in a page controller?
I’d like to respond with json if a form was submitted to that page. fetch(...page.json) with a POST request feels wrong.

I don’t really follow. What exactly doesn’t feel right?

Post to a .json endpoint :slight_smile:

hehe ok. If you really can’t live with that, why not setup your own route then?

I don’t want to setup a route for every page that has a form. It seems to be a better solution to handle the request in the page controller that is loaded anyways.

Well, you can put an if statement into your controller and return what you need from there. If post request, return a snippet that contains some JSON, otherwise return your usual variables for the template.

The page is always rendered with the regular template, no matter what I return in the controller.
Or I do not understand how to…

return function (Kirby\Cms\Page $page, Kirby\Cms\App $kirby) {
    return "<html></html>"
   // or  return json_encode($variables)
});

That was a common form handling pattern in Kirby 2…is this approach wrong for Kirby 3?

Instead of returning the data, have you tried to echo it?

e.g. in your controller:

echo '<html><body>test</body></html>';
die;

While this seems to work, I have no clue if it’s the way to do so?

Thx for this idea @bvdputte, I haven’t tried it yet. die in the controller might have side effects?

I’m not sure.
It stops PHP execution, but since you echo what you wanted just before, it’s kinda what you want?

True. I am also creating pages before responding to the form and I am not sure when Kirby writes to the filesystem. Will give it a try.

Kirby behaves as I expected. When I create a page in the page controller and abort the script with die(), no data is written to the file system and the page is not created. <-- was due to typo in code

Any other ideas how to change the response to json instead of sending the standard template?

I don’t quite understand why page creation gets aborted; could you post some code? Using die($jsonResponse) would be right way to achieve this if you don’t want to post to the content representation. Or use the router, as already suggested, for a clean approach. How many different forms that need a different approach are there in your project that it would result in so much more effort.

I had a typo in my code and the pages were created in a folder I was not watching :expressionless:

So it actually works!

return function (Kirby\Cms\Page $page, Kirby\Cms\App $kirby) {
    if ($kirby->request()->method() == "POST") {
        // create some sub pages

        // then
        $kirby->response()->code(200)->type('application/json');
        die(json_encode($response));
    }
}