I've got a relatively simple setup running using SilverStripe 3.2.1 with the restfulserver addon and using a variety of widgets which are associated to a Page using the elemental addon.
When I make a GET request via the API to retrieve some of Page #1's data, I can see the associated ElementAreaID:
# GET /api/v1/Page/1.json?fields=Title,URLSegment,Content,ElementArea
{
"Title": "Welcome",
"URLSegment": "home",
"Content": "A bunch of HTML here from all the widgets in the page...",
"ElementArea": {
"className": "ElementalArea",
"href": "http://ss.local:3000/api/v1/ElementalArea/11.json",
"id": "11"
}
}
If I follow the links through the ElementalArea API calls it will list out all of the elements in my page:
# GET /api/v1/ElementalArea/11.json
{
"ID": "11",
"Widgets": [
{
"className": "Widget",
"href": "http://ss.local:3000/api/v1/Widget/9.json",
"id": 9
},
{
"className": "Widget",
"href": "http://ss.local:3000/api/v1/Widget/8.json",
"id": 8
},
...
]
}
And if I follow those API paths it will serve up the contents of the latest version of each of the Widgets.
My question is how can I include certain fields from the Widget DataObjects within the original Page field list?
I'd like ideally to have the Content field from each Widget be returned in an array with the initial Page API request.
For reference:
ElementArea
ElementArea
has many Widget
sWidget
contains content that I want for my Page
Preamble: It doesn't seem there's currently a way to output array-like datastructures with the RESTful server module (except for relations of course). The proposed solution is a hack that abuses how JSONDataFormatter
formats output.
Since JSONDataFormatter
uses forTemplate
to render a field before converting it to JSON, we can create our own Object renderer that returns an array instead of a string via forTemplate
. This might look like this:
class FlatJSONDataList extends ViewableData
{
protected $list;
public function __construct(array $list)
{
parent::__construct();
$this->list = $list;
}
public function forTemplate()
{
return $this->list;
}
}
Then in your Page, it should be sufficient to have an additional method, like so:
public function getWidgetContents()
{
return FlatJSONDataList::create(
$this->ElementArea()->Widgets()->column('Content')
);
}
Then you can include WidgetContents
in your Field-list to get all widget Content
fields in an array:
GET /api/v1/Page/1.json?fields=Title,URLSegment,Content,WidgetContents
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With