Json representation doesn't work

hey there,
I followed the docs, but when displaying the page, there’s just the default page with title “API”.

in content, i got api/api.txt (empty file)
in templates, i got api.php (structure field with only 1 entry, title):

<?php

header("Access-Control-Allow-Origin: *");
header('Content-type: application/json; charset=utf-8');

$data = $site->api()->toStructure();
$json = array();

foreach($data as $api) {

  $json[] = array(
    'title' => (string)$api->title()
  );

}

echo json_encode($json);

?>

pls help!

I think you need a blueprint too, which is why its falling over to the default template.

Hm, the code is OK. Are you in a multi-language environment maybe (then your text file needs a language code)? Or some spelling mistake?

A blueprint is not needed, no.

On a side note: PHP-only files shouldn’t have a closing PHP tag.

Ah,… i have a blueprint to stop the template showing up as a choice for new pages, but your right its not essential.

The example(s) in the docs page has a closing tag.

That’s correct! - Just copied it right over … but deleting it doesn’t make any difference

The closing PHP tag was just a side note, it will not solve your problem. If it’s in the docs, I will remove it.

The more interesting question was the language setup. Or use of capital letters in file names, maybe?

!! totally, multi-lang is active (maybe add it to the docs) … will check

// Edit:

Absolutely positively working now! Once again, @texnixe saved the day.

1 Like

The API documentation is quite old, I’d use a route now to return the JSON instead of a page folder, anyway.

Makes sense, but for it to work, the template would still have to exist?

No, you can return your JSON directly from the route. See “Returning a response object” in the docs: https://getkirby.com/docs/developer-guide/advanced/routing

1 Like

Well, deleting content/api & api template and this:

// config.php
<?php

c::set('routes', array(

  // ...

  array(
    'pattern' => '(:all)/api',
    'action'  => function() {

      $data = $site->api()->toStructure();
      $json = array();

      foreach($data as $api) {
        $json[] = array(
          'title' => (string)$api->title()
        );
      }

      return response::json($json);
    }
  )
));

… didn’t work, restoring said files leads to default page with “API” title …

Your route should look like this, if you want to call it with http://example.com/api. Note that you have to define $site.

c::set('routes', array(

  // ...

  array(
    'pattern' => 'api',
    'action'  => function() {
      $site = site();
      $data = $site->api()->toStructure();
      $json = array();

      foreach($data as $api) {
        $json[] = array(
          'title' => (string)$api->title()
        );
      }

      return response::json($json);
    }
  )
));

Had a feeling that I missed the $site part … :slight_smile: thx again!

Well, still when template is empty, nothing is displayed when I visit the URL …

What template? I thought we were using routes now?

Yeah, and I deleted it, but it doesn’t work. I’ll look into it and come back at you if I can’t resolve it.

If nothing is displayed when you call the URL, maybe your field in site.txt does not exist, is empty, is called differently? The above works for me in a starterkit, if I add an api structure field to site.txt.

// site.de.txt

Title: Site Title

----

Description:

----

Copyright:

----

Api:

-
  title: Name 1
-
  title: Name 2
-
  title: Name 3

<?php

// config.php

c::set('routes', array(

  // ...

  array(
    'pattern' => 'api',
    'action'  => function() {

      $site = site();
      $data = $site->api()->toStructure();
      $json = array();

      foreach($data as $api) {
        $json[] = array(
          'title' => (string)$api->title()
        );
      }

      return response::json($json);
    }
  )
));

content/api/api.de.txt exists
site/templates/api.php doesn’t exist

= doesn’t work …

I forgot about multi-language, you probably need two routes here, one with just api and another one with the language code…, otherwise it only works for the default language. And then use $site->content('lang-code')->api()->structure() for the non-default language.

c::set('routes', array(

  // ...

  array(
  'pattern' => 'api',
    'action'  => function() {

      $site = site();
      $data = $site->api()->toStructure();
      $json = array();

      foreach($data as $api) {
        $json[] = array(
          'title' => (string)$api->title()
        );
      }

      return response::json($json);
    }
  ),
  array(
  'pattern' => 'de/api', //or 'en' if 'de' is the default lang, or a placeholder if you have more language
    'action'  => function() {

      $site = site();
      $data = $site->content('de')->api()->toStructure();
      $json = array();

      foreach($data as $api) {
        $json[] = array(
          'title' => (string)$api->title()
        );
      }

      return response::json($json);
    }
  )
));

The page folder is not necessary when using routes.