Route: Structure Field To JSON

Soo…I’ve got a page that just contains a simple structure field (in addition to the title) that spits out this content:

Title: collections
----
Collections:
-
  collection: Dolor Sit
-
  collection: Lorem Ipsum

Now I’m trying to figure out how to turn it into a JSON file so that it can be used in a select field in another blueprint:

{"Dolor Sit", "Lorem Ipsum"}

My understanding is that I need to use a route to do this. I’ve set up the following route, but it doesn’t output anything:

c::set('routes', array(
  array(
    'pattern' => 'collections',
    'action'  => function() {
        $arr = $page->collections()->toStructure()->toArray();
        return response::json($arr);
    }
  )
));

I’ve tested $page->collections()->toStructure()->toArray() in the context of a template, and it returns the correct PHP array. I’ve also tested this example of returning JSON and it works properly. It just seems that $page->collections()->toStructure()->toArray() is not working in the context of this router. Any idea why, or am I’m going about this in a completely wrong way?

Thanks a bunch in advance — I’ve been beating my head against this wall for a few hours and can’t figure anything out. I know just enough PHP to get myself into corners like this. :\

I haven’t used it, but have you tried toJson() on your collection?

What does $page->collections()->toStructure()->toJson() do in your situation?

Thanks Paul, but unfortunately, that didn’t change anything. It still outputs nothing.

Considering a structure is a yaml list, you could try the yaml() method instead of toStructure(). Main difference is that yaml() returns an array instead of a Collection object.

If I’m not mistaken a::json($array) should be useful afterwards.

c::set('routes', array(
  array(
    'pattern' => 'collections',
    'action'  => function() {
        $arr = $page->collections()->yaml();
        return a::json($arr);
    }
  )
));

Makes sense to me, but again I can’t test this right now.

Thanks greatly again Paul, but it’s still a no-go. That aught to work, it seems to me, as it returns an array. But it doesn’t. Is there some trick to using the $page object in a route that I’m missing?

Solved it! Here’s my new and improved route:

c::set('routes', array(
  array(
    'pattern' => 'collections',
    'action'  => function() {
        $arr = page('collections')->collections()->yaml();
        $newArray = array();
        foreach ($arr as $subarr) {
            $value = $subarr["collection"];
            $newArray[$value] = $value;
        }
        return response::json($newArray);
    }
  )
));

As I surmised earlier, $page does not work in a router. Instead, use page("UID"), substituting UID with the actual uid of the page.

This results in a slightly complicated array, which needed to be simplified. So, I added a bit more code to get the values out of the old array and write a new array that would be more suitable.