-
-
Notifications
You must be signed in to change notification settings - Fork 10
3.1: Output Formatting
The module automatically runs json_encode on the output data, so your function can return a classic PHP-array and it will be transformed to a JSON-response.
<?php
namespace ProcessWire;
class Example {
public static function test () {
return [
'message' => 'test successful',
'status' => 200
];
}
}
Calling that Example::test()
function will result in a response like this:
{
"message": "test successful",
"status": 200
}
That works very well with all basic datatypes (like string, integer, boolean, ...) which json_encode can handle.
More complex data, let's say a ProcessWire-Page object, must be transformed simpler datatypes. I added a little helper-function AppApi::getAjaxOf()
, that can transform objects of ProcessWire's Page
, PageArray
, Template
, PageImage
, PageFile
and PageFiles
to arrays with the basic data that they contain.
<?php
namespace ProcessWire;
class Example {
public static function pageOutput () {
return AppApi::getAjaxOf(wire('pages')->get('/'));
}
}
Calling that Example::pageOutput()
function will result in an array of the basic information of your homepage:
{
"id": 1,
"name": "home",
"title": "Homepage",
"created": 1494796565,
"modified": 1494796588,
"url": "/",
"httpUrl": "https://my-website.dev/",
"template": {
"id": 1,
"name": "home",
"label": "Home-Template"
}
}
Look at the code of AppApi::getAjaxOf()
- it does nothing overcomplicated. If these basic outputs are not sufficient for your use case, you have to convert the values of the respective field itself into something that can be output as JSON.
Let's have a look at a typical RepeaterMatrix-field, that I like to use for the main-contents of a page in most of my projects.
The field offers several different types of content blocks that can be freely created, swapped and changed. I like to use this very much instead of a complete free text field to provide some structure for the editors. In addition, these content blocks are much easier to style.
Our field named "contents" holds its data-values as an iterable list of Pages, that represent the created content-blocks. Each type can have different sub-fields. Let us concentrate on the following examples:
- text
- title (InputText)
- freetext (InputTextarea)
- image
- image (InputImage with max 1)
- gallery
- title (InputText)
- description (InputTextarea)
- images (InputImage)
We assume, that our example-page with id 4242 does have our contents-field. We want to output its contents via api, so we must transform the values to an PHP-array of simple values.
<?php
namespace ProcessWire;
class Example {
public static function pageOutput() {
$page = wire('pages')->get(4242);
if (!$page || !$page->id) {
throw new NotFoundException();
}
$output = [
'contents' => []
];
foreach ($page->contents as $contentblock) {
if($contentblock->type === 'text'){
$output['contents'][] = SELF::getAjaxOfTextblock($contentblock);
}else if ($contentblock->type === 'image') {
$output['contents'][] = SELF::getAjaxOfImageblock($contentblock);
}else if ($contentblock->type === 'gallery') {
$output['contents'][] = SELF::getAjaxOfGalleryblock($contentblock);
}
}
return $output;
}
private static function getAjaxOfTextblock($block) {
return [
'type' => 'text',
'depth' => $block->depth,
'title' => $block->title,
'text' => $block->freetext
];
}
private static function getAjaxOfImageblock($block) {
return [
'type' => 'image',
'depth' => $block->depth,
'image' => AppApi::getAjaxOf($block->image)
];
}
private static function getAjaxOfGalleryblock($block) {
return [
'type' => 'gallery',
'depth' => $block->depth,
'images' => AppApi::getAjaxOf($block->images),
'title' => $block->title,
'description' => $block->freetext
];
}
}
That will result in an output like the following, depending on which content-blocks were created on the page:
{
"contents": [
{
"type": "text",
"depth": 0,
"title": "Example-Headline",
"text": "Lorem ipsum..."
},
{
"type": "image",
"depth": 0,
"image": {
"basename": "example-image.0x300.jpg",
"name": "example-image.0x300.jpg",
"description": "",
"created": 1596037618,
"modified": 1596037618,
"filesize": 71585,
"filesizeStr": "70 kB",
"page_id": 5678,
"ext": "jpg",
"basename_mini": "example-image.0x300.600x0.jpg",
"width": 683,
"height": 300,
"dimension_ratio": 2.28,
"original": {
"basename": "example-image.jpg",
"name": "example-image.jpg",
"filesize": 305906,
"filesizeStr": "299 kB",
"ext": "jpg",
"width": 910,
"height": 400,
"dimension_ratio": 2.28
}
}
},
{
"type": "text",
"depth": 0,
"title": "Second Example-Headline",
"text": "Lorem ipsum..."
}
]
}
With version 1.1.0 you can influence the HTTP status code of the server response (default is 200). If you specify a 'responseCode' in the response array, this value becomes the new response code.
<?php
class AppApiTest {
public static function test($data) {
return [
'success' => true,
'responseCode' => 202
];
}
}
➡️ Continue with 3.2: Error Handling
⬅️ Back to 3: Creating Endpoints
AppApi
Connect your apps to ProcessWire!
ProcessWire-Module: | https://modules.processwire.com/modules/app-api/ |
Support-Forum: | https://processwire.com/talk/topic/24014-new-module-appapi/ |
Repository: | https://github.com/Sebiworld/AppApi |
Wiki: | https://github.com/Sebiworld/AppApi/wiki |