Confusion about field plugins and extending UIKit

I’m at a bit of an impasse trying to understand how to write a custom field plugin. I am 100% sure it is just a lack of understanding, but I have read through the documents numerous times and tried to find a very basic example of how this all fits together.

For example, to simply extend a basic text field, I create the following:

plugins/hello/index.php

<?php
Kirby::plugin('your/plugin', [
    'fields' => [
        'hello' => [
            'extends' => 'text',
            'props' => [
                'text' => function (string $myNewProp = null) {
                    return $myNewProp;
                }
            ]
        ]
    ]
]);

plugins/hello/index.js

panel.plugin("your/plugin", {
  fields: {
    hello: {
      props: {
        text: String
      },
      extends: "k-text-field",
      template: `<k-text-field v-model="text" label="Boring text" @input="updateField" />`,
      methods: {
        updateField() {
          // How do I trigger the draft/save update?
        }
      }
    }
  }
});

blueprints/pages/default.yml

title: Default Page
preset: page
fields:
  text:
    label: Text
    type: textarea
    size: large
  hello:
    type: hello
    message: This is my very first field

Am I supposed to be writing my own methods to trigger the updating/saving of this field when text is entered? How does one go about this? I feel like the documentation is so close to clarifying how these pieces fit together but I’m missing the last bits to really understand how it all works.

Perhaps once this is clarified, we could put up a very basic example of a fully functioning basic custom field extension plugin?

Also, apologies if this is a silly question but what is the difference between <k-text-field> and <k-text-input>?

I currently can’t answer your questions but wondering why you put the double quotes around your variable.

Hi @texnixe sorry that was just a typo, I’ve corrected it for now!

I feel like a clear documentation or fully functioning example basic plugin would be a huge boon.

Yes, I’ll do a cookbook recipe as soon as I can, but currently a bit under water.

Completely understand, in the meantime, if anyone else has any ideas/tips please feel free to nudge me in the right direction and hopefully the outcome can help with the cookbook recipe too!

To trigger the update you need to emit the input event. Also you should not use the text prop in v-model (One-Way-Data-Flow). Following example should work:

panel.plugin("your/plugin", {
  fields: {
    hello: {
      props: {
        text: String
      },
      data() {
        return {
          value: this.text
        }
      },
      extends: "k-text-field",
      template: `<k-text-field v-model="value" label="Boring text" @input="updateField" />`,
      methods: {
        updateField() {
          this.$emit('input', this.value);
        }
      }
    }
  }
});
1 Like

Wow thank you @lukaskleinschmidt for this tiny clarification, perhaps it was so obvious to people, but it really made everything click. Also, to be reminded to just think of this properly as a vue component. This works perfectly, thank you! Though I do have to say, it is confusing not to see the requirement for the emit event documented anywhere.

My only question now, is how does the php side of things take the value and work with it?

Hi again @texnixe and @lukaskleinschmidt I’m sorry to dredge up an old issue, but I’m wondering if there was any further information on how this whole cycle works?

This is my understanding so far:

  1. When the field is changed, the ‘input’ event is emitted and updates the content of the parent <KSections>
  2. When the page is saved, the panel sends a PATCH to the API with the updated data

I’m trying to build a custom date-time field and am seeing the date saved but not the time, although I see the correct date/time being logged in the console and in the PATCH request:

plugin/index.php

Kirby::plugin('test/datetime', [
    'fields' => [
        'test_datetime' => [
            'extends' => 'date',
            'props' => [
                'value' => function ($value = null) {
                    return $value;
                },
            ]
        ]
    ],
]);

plugin/index.js

panel.plugin("test/datetime", {
  fields: {
    test_datetime: {
      props: {
        value: String
      },
      extends: "k-date-field",
      template: `<k-input v-model="value" type="datetime" theme="field" name="datetime" @input="updateField" icon="calendar" />`,
      methods: {
        updateField() {
          console.log(this.value)
          this.$emit('input', this.value);
        }
      }
    }
  }
});

My questions are mainly (apart from what I’m doing wrong):

  1. What events can be emitted by a component? Ah, it is clearly documented: https://getkirby.com/docs/reference/plugins/ui/date-time-input#events

  2. How does this tie into the php side of the plugin? Looking at kirby/config/fields/date.php I can see the blocks for props, computed, methods, save, validations etc… When is the save function called?

  3. In index.js should I be extending k-date-field or k-date-time-input?

  4. In index.php should I be extending date or something else?

  5. When this is all working, how could I go about processing the date-time either before save or on load as I am trying to fix the timezone issue I’m having as per this github issue: https://github.com/getkirby/kirby/issues/1813 (unless the PR will get merged hopefully)

Sorry for all the questions, I feel like I am close to understanding how this all works but am just a bit stuck here.