Cannot extend existing field

Hi there,

I am trying to extend an existing field, however in the panel I keep getting the error The field type "hello" does not exist. After reducing the issue to its simplest form, I still get the error.

My code is simply

<?php

use Kirby\Cms\App as Kirby;

Kirby::plugin('trych/field-defaults', [
  'fields' => [
    
    'hello' => [
      'extends' => 'text'
    ]

  ]

]);

In my blueprint I use it like this:

hello:
  label: Test
  type: hello

Yet, I keep getting the error:

20220516-223311_Screenshot_quick.test

What am I doing wrong?

Thanks!

Have you also created the JS part?

Oh, I was not aware that I also have to create the JS part when I just want to extend and existing field (I basically just want to change an existing field’s defaults, but have it available under a different field name then).

I now added the JS part from the docs:

panel.plugin("your/plugin", {
  fields: {
    hello: {
      extends: "k-text-field"
    }
  }
});

The error is gone now, however I just have a strange line showing up in my panel now:

20220516-234701_Screenshot_quick.test

Going over the documentation again, I assume this might be because I have no template output defined in the JS file? However, I am now wondering if there is an easier way to accomplish what I need to do. Because what I eventually do want to do is modify a date field and setting some other defaults. Recreating the entire date field template for that sounds kind of complicated.

This is kinda a hack, but maybe it works for you:

<?php

use Kirby\Cms\App as Kirby;

Kirby::plugin('trych/hellofield', [
    'fields' => [
        'hello' => [
            'extends' => 'text',
            'props' => [
                'type' => 'text',
            ]
        ]
    ]
]);

No JS part needed


Otherwise, if you wanna do stuff to the date field, it might just work like you did it. The text, url, number, etc., fields do some magic that depends on the field type name. Like, having a field type “hello” tries to create a k-hello-input component that doesn’t exist; while the date field, afaik, does not. So it should just work.

1 Like

Thanks @rasteiner. I tried the date only approach first (before creating the post actually) and that didn’t work. Your “hack” works beautifully though, thanks a lot. Should maybe even find a mention in the docs as a quick way to create a “clone” of a field with different defaults.

Sorry, while the original problem is solved, I now have another issue (that even fits the thread’s title). When I try to extend a blocks field to set some different defaults, I get an error:

'blocks' => [
  'extends' => 'blocks',
  'props' => [
    'pretty' => fn($value = true) => $value
  ]
]

In the panel I get this error:

20220517-162257_Screenshot_quick.test

For the other fields the exact same setup works without any issues. Is the blocks field special somehow and how could I set custom defaults for the blocks field?

Yes. The blocks and layout fields are the only fields in core that aren’t configured as an array somewhere in kirby/config/fields but instead have their own classes in kirby/src/Form/Field.
I don’t really have an explanation, but I guess the 'extends' => 'blocks' part doesn’t really work because of this.

It’s becoming hackier and hackier… But you might get it to work like this:

<?php 

use Kirby\Cms\App as Kirby;
use Kirby\Form\Field\BlocksField as BaseBlocks;

class BlocksField extends BaseBlocks {
    public function __construct(array $params = []) {
        $params['pretty'] ??= true;
        parent::__construct($params);
    }
}

Kirby::plugin('trych/blockdefaults', [
    'fields' => [
        'blocks' => '\BlocksField',
    ]
]);

Notice that your class has to be called BlocksField for the magic to work; while the fact that it’s another namespace doesn’t seem to bother Kirby… This is because for FieldClasses Kirby derives their type by default from the class name. This behavior is implemented here.
You could also write the type explicitly like this:

<?php 

use Kirby\Cms\App as Kirby;
use Kirby\Form\Field\BlocksField;

class PrettyBlocks extends BlocksField {
   public function __construct(array $params = []) {
       $params['pretty'] ??= true;
       parent::__construct($params);
   }

   public function type(): string {
       return 'blocks';
   }
}

Kirby::plugin('trych/blockdefaults', [
   'fields' => [
       'blocks' => '\PrettyBlocks',
   ]
]);
1 Like

Wow, thanks for digging into this and figuring it out, @rasteiner! While this looks indeed quite hacky, it seems to work quite well. Thanks a lot!

@texnixe I suspect that part of the docs pre-dates blocks and layout fields, but it might be worth to mention in the Fields Plugin docs that the Blocks and Layouts fields cannot be extended in the way that is currently mentioned in the docs.