Panel plugin: Structure field with fixed fields

Hi,

I am trying to create a panel plugin which basically consists of a structure field with fixed fields. So far I managed to add the fixed fields to a <k-structure-field> and when I click the “add” button, I can see the form for entering the data.

However, when I want to add and save the new data, I get an error message saying “e is null”. In the browser console I can see that a POST request seems to fail shortly before the error is thrown: POST http://localhost:8000/api/pages/home/fields/contact_form_stylish/validate return a 404 not found.

So I’m quite sure I messed up the endpoints. I am lost as to what would be correct in this case. I understood the “My first panel field” cookbook and the corresponding videos, but I can’t wrap my head around the endpoints topic as I don’t know which endpoints are used by default by which standard components.

Can anyone help me out?

Here is my Vue component:

<template>
    <k-structure-field
        :label="label"
        :fields="formFields"
        :endpoints="endpoints"
    ></k-structure-field>
</template>

<script>
export default {
    props: {
        label: String,
        endpoints: Object
    },
    computed: {
        formFields() {
            var fields = {};
            var field = {};
            fields = {
                entry1: {
                    label: "Entry 1",
                    type: "text",
                    required: false,
                    icon: "title"
                },
                entry2: {
                    label: "Entry 2",
                    type: "text",
                    required: false,
                    icon: "url"
                }
            }
            Object.keys(fields).forEach(name => {
                field = fields[name];
                field.section = this.name;
                field.endpoints = {
                    field: this.endpoints.field + "+" + name,
                    section: this.endpoints.section,
                    model: this.endpoints.model
                };
                fields[name] = field;
            });
            return fields;
        }
    }
}
</script>

<style lang="scss">
</style>

I had another try be means of extending the structure field:

index.php:

Kirby::plugin('my/plugin', [
    'fields' => [
        'extendedstruct' => [
            'extends' => 'structure',
            'props' => [
                'fields' => [
                    'entry1' => [
                        'label' => "Entry 1",
                        'type' => "text",
                        'required' => false,
                        'icon' => "title"
                    ],
                    'entry2' => [
                        'label' => "Entry 2",
                        'type' => "text",
                        'required' => false,
                        'icon' => "url"
                    ],
                ]
            ]
        ]
    ],
]);

index.js:

panel.plugin('my/plugin', {
    fields: {
        extendedstruct: {
            extends: "k-structure-field"
        }
    }
});

page blueprint defaut.yml:

title: Default Page
fields:
  testfield:
    type: extendedstruct
    label: Extended structure

This gives the error “Undefined index: fields”.

And indeed, if I define the fields in the blueprint like this

title: Default Page
fields:
  testfield:
    type: extendedstruct
    label: Extended structure
    fields:
      tf:
        type: text
        label: Test field
      tf2:
        type: text
        label: Test field 2

the blueprint is showing up “correctly” in the panel, but of course with the fields from the yml. My goal was to pre-define these fields.

So I have two ideas now how to achieve my goal, but none is working so far.

Any help is greatly appreciated.

The form method takes fields from the blueprint, you’ll have to tell it to use your predefined fields.
Structure Field

use Kirby\Cms\Form;
// [...]

'fields' => [
    'extendedstruct' => [
        'extends' => 'structure',
        'props' => [
            'fields' => function () {
                return [
                    'entry1' => [
                        'label' => "Entry 1",
                        'type' => "text",
                        'required' => false,
                        'icon' => "title"
                    ],
                    'entry2' => [
                        'label' => "Entry 2",
                        'type' => "text",
                        'required' => false,
                        'icon' => "url"
                    ],
                ];
            }
        ],
        'methods' => [
            'form' => function (array $values = []) {
                return new Form([
                    'fields' => $this->fields,
                    'values' => $values,
                    'model' => $this->model
                ]);
            },
        ]
    ]
],
1 Like

Thanks, perfect! That solved it!