lord-executor / kirby-json-api

The Kirby JSON API plugin is a fairly simple layer on top of the existing Kirby infrastructure that provides a language-aware, read-only (for now) JSON API to access the content tree from JavaScript and other external clients. It also provides some basic functionality for developers to easily add their own JSON-based APIs.
MIT License
93 stars 2 forks source link

Return structure field as JSON instead of YAML string #1

Closed woudsma closed 7 years ago

woudsma commented 7 years ago

I'm loving the API as is, but i would like to return JSON instead of a YAML string for structure fields. My output looks something like this:

{
  ...
  mystructurefield: "- \n  title: Title text\n  message: 'Did you know that **fact**?'\n  footer: Footer text\n  image: 580b585b2edbce24c47b2a2d.png\n- \n title: Title text\n  message: 'Some other **fact**'\n  footer: Footer text\n  image: 1.png",
  ...
}

This would require a YAML parser (and Markdown in this case) on the frontend. Doing this on the server would make more sense. I'm not sure how to approach adding this to the API. Would this be a quick fix? Suggestions would be appreciated!

Output i'm looking for:

{
  ...
  mystructurefield: [
    {
      "title": "Title text",
      "message": "Did you know that **fact**?",
      "footer": "Footer text",
      "image": "580b585b2edbce24c47b2a2d.png"
    },
    {
      ...
    }
  ],
  ...
}
lord-executor commented 7 years ago

First of all, thanks for pointing out this use case, I have not considered a scenario with structured fields that in turn contain fields that need their own processing.

When I was initially developing this, I was planning on making all of that possible out of the box, but unfortunately I could not figure out a reasonable way to access the blueprint information from the page object. This is why the default implementation treats everything the same way that Kirby does: every field is just a string value - including structured fields - the same way you have to "know" what your field value represents when writing templates.

In essence, you need to write your own custom API extension and field mappings for this. I don't know a lot about your specific situation, so the sample code is just to illustrate a rough idea on how this could be done.

<?php

use Lar\JsonApi\JsonApiUtil;

jsonapi()->register([
    // api/test
    [
        'method' => 'GET',
        'pattern' => 'test',
        'action' => function () {
            $page = page('test-structure');

            return JsonApiUtil::pageToJson($page)
                // the 'location' field contains a select-type link to another page
                ->mapField('mystructurefield', function ($field) {
                    // the field is a structured field, so we want to process the YAML.
                    $struct = array_map(function ($item) {
                        $item['message'] = kirbytext($item['message']);
                        return $item;
                    }, $field->yaml());

                    return $struct;
                });
        },
    ],
]);

Looking over my code, I realize that I could improve the APIs to work with Structure objects (e.g. created from $field->toStructure(), which wouldn't solve the issue of having to define the mappings manually, but it would make the custom code easier to read and more manageable. I'll look into that...

I could probably also add some features that would allow you to define custom (pseudo-)blueprint based mappings without having to create a custom API endpoint. I'll also look into that.

woudsma commented 7 years ago

Thanks for your reply! I didn't have time to do some tests with that code yet. Mapping over each field and test if a string starts with - \n, return json_encode($field->yaml()) could also be an idea, JSON string - Just guessing here, i really need to dive into it soon. Parsing the Markdown will be done on the front-end.

Side note, to get localized requests working, i added

$page = site()->visit($id, kirby()->request()->query()->lang());

to the get functions in JsonApiController.php This way querying e.g. ?lang=en returns the localized page from the panel. You mentioned languages in the readme but i had no luck. Hacky fix :]

lord-executor commented 7 years ago

I finally found some time to add the structured field detection and processing. The develop branch should solve the first of your problems. I'll have a look at some other issues before I'll make a new release, but it shouldn't be as long as it already has been ;)

I would appreciate it if you could give this a quick test.

woudsma commented 7 years ago

Awesome! I'll dive into that next week and keep you updated.

jklue commented 7 years ago

I would also love the ability to see structured fields in a more organized format after the API call. Are the updates in the develop branch? I'm getting the following in the response from a structure field:

{
    ...
    mystructurefield: "- ↵  pointx: "20"↵  pointy: "-10"↵  pointz: "50"↵  description: Go straight through the front doors...↵  icon: """
    ...
}

Thanks a ton!

woudsma commented 7 years ago

I've quickly tried v1.1.0, but also still getting results like @lukehatfield

lord-executor commented 7 years ago

Totally my bad... I did not properly channel my RegEx-Fu when writing the code that checks for structured fields. The only reason my tests still worked was that my editor is configured to remove all trailing white-space.

With Release v-1.1.1, this should now be fixed as well.

Thanks for pointing this out and sorry for the inconvenience.

jklue commented 7 years ago

Beautiful!! Using it to integrate Kirby in my capstone project (in development). http://orientable.io http://orientable.io/.

-- Luke Hatfield luke@lukehatfield.com 781-635-9464

On Apr 13, 2017, at 11:14 AM, lord-executor notifications@github.com wrote:

Totally my bad... I did not properly channel my RegEx-Fu when writing the code that checks for structured fields. The only reason my tests still worked was that my editor is configured to remove all trailing white-space.

With Relese v-1.1.1 https://github.com/lord-executor/kirby-json-api/releases/tag/v-1.1.1, this should now be fixed as well.

Thanks for pointing this out and sorry for the inconvenience.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/lord-executor/kirby-json-api/issues/1#issuecomment-293924976, or mute the thread https://github.com/notifications/unsubscribe-auth/AFJlh2LqufipeftE4J7XX58hVAigiZTOks5rvjvPgaJpZM4MW3vD.