# Difficulties building a custom image block plugin

**URL:** <https://forum.getkirby.com/t/difficulties-building-a-custom-image-block-plugin/33082>\
**Category:** Questions\
**Tags:** v4\
**Created:** [December 16, 2024, 12:54pm UTC](https://forum.getkirby.com/t/difficulties-building-a-custom-image-block-plugin/33082 "2024-12-16T12:54:23Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![whitmoa](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/whitmoa/32/16395_2.png) [@whitmoa](https://forum.getkirby.com/u/whitmoa)\
**Post date:** [December 16, 2024, 12:54pm UTC](https://forum.getkirby.com/t/difficulties-building-a-custom-image-block-plugin/33082/1 "2024-12-16T12:54:23Z")

</div>

I’m trying to create a custom image block plugin that adds a handful of fields to the image blueprint and controls the behaviour of the image block preview in the Panel.

I followed this [Cookbook lesson](https://getkirby.com/docs/cookbook/plugins/to-bundle-or-not-to-bundle#moving-the-script-part) to split out the parts of the default [Image.vue file](https://github.com/getkirby/kirby/blob/main/panel/src/components/Forms/Blocks/Types/Image.vue) into the `index.js` and `index.css` files but I’m struggling with a couple of challenges.

**1. Import/extend script affecting other plugins**  
The first section of script that imports and extends `Block from "./Default.vue";` seems to be causing some problems.

- If I leave that code out, no image preview appears in the Panel (of course)
- If I include it, I get problems with other plugins, for example…
  - The [Clear Cache](https://plugins.getkirby.com/owebstudio/clear-cache) page is completely empty
  - The Panel preview for my custom button block disappears

My questions are…

- Should that script section go before or after the line `panel.plugin("brandsistency/image-block", {`? If after, I get code errors that I can’t resolve. Either way, it impacts the other plugins.
- Or should I be building in actual code from `Default.vue`?

**2. Adding new field classes to the preview \<template\>**  
One of the additional fields I’m adding to the blueprint is an alignment setting where the user can set the image to be centred or right-aligned. It works perfectly in the front-end via the snippet but I want to be able to centre the Panel preview as well. What I can’t figure out is how to ‘mix’ the existing classes and my dynamic class. I know that having both `class` and `:class` is wrong but I can’t figure out how to combine them.

* * *

This is my **index.js** code as it stands. What am I doing wrong?

```auto
import Block from "./Default.vue";
/** 
* @displayName BlockTypeImage
*/
export default {
  extends: Block,
  data() {
    return {
      back: this.onBack() ?? "white"
    };
  }
};

panel.plugin("brandsistency/image-block", {
  blocks: {
    image: {
      computed: {
        captionMarks() {
          return this.field("caption", { marks: true }).marks;
        },
        crop() {
          return this.content.crop ?? false;
        },
        src() {
          if (this.content.location === "web") {
            return this.content.src;
          }
          if (this.content.image?.[0]?.url) {
            return this.content.image[0].url;
          }
          return false;
        },
        ratio() {
          return this.content.ratio ?? false;
        },
        className() {
          let value = this.content.alignment;
          let className = value === 'center' ? 'txt-c' : value === 'right' ? 'txt-r' : ''; return className;
        },		
      },
      methods: {
        onBack(value) {
          const id = `kirby.imageBlock.${this.endpoints.field}.${this.id}`;
          if (value !== undefined) {
            this.back = value;
            sessionStorage.setItem(id, value);
          } else {
            return sessionStorage.getItem(id);
          }
        }
      },
      template: `
        <k-block-figure
          :back="back"
          :caption="content.caption"
          :caption-marks="captionMarks"
          :empty-text="$t('field.blocks.image.placeholder') + ' …'"
          :disabled="disabled"
          :is-empty="!src"
          empty-icon="image"
          @open="open"
          @update="update"
        >
          <template v-if="src">
            <k-image-frame
              v-if="ratio"
              :ratio="ratio"
              :cover="crop"
              :alt="content.alt"
              class="k-block-type-image-auto"
              :class="className"
              :src="src"
            />
            <img
              v-else
              :alt="content.alt"
              class="k-block-type-image-auto"
              :class="className"
              :src="src"
            />
            <k-block-background-dropdown :value="back" @input="onBack" />
          </template>
        </k-block-figure>
      `
    }
  }
});

```

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [December 16, 2024, 1:12pm UTC](https://forum.getkirby.com/t/difficulties-building-a-custom-image-block-plugin/33082/2 "2024-12-16T13:12:56Z")

</div>

That whole import/export stuff should not be there, and in any case not at the top of the file.

---

<div class="post-metadata">

**Author:** ![whitmoa](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/whitmoa/32/16395_2.png) [@whitmoa](https://forum.getkirby.com/u/whitmoa)\
**Post date:** [December 16, 2024, 3:06pm UTC](https://forum.getkirby.com/t/difficulties-building-a-custom-image-block-plugin/33082/3 "2024-12-16T15:06:13Z")

</div>

Thanks, Sonja. But if I remove that section completely, the image blocks do not appear at all in the Panel. It’s still there in the front-end but not in the Panel. I can add new image blocks but, as soon I’ve finished filling in the fields in the modal, the block disappears from view.

Here is a screenshot of the Panel **with** that import section included in `index.js`. You can see some of the extra fields I’ve added, including the alignment setting. The image blocks appear in the preview. (I’ve set one of them to be centred but it is not centred in the Panel because I can’t figure that bit out.) Other plugins are affected in this case.

 ![image](https://europe1.discourse-cdn.com/flex017/uploads/getkirby/original/2X/c/ca5c18a43a3b7d0157372cf67875e55148a3fd93.png)

**Without** the import section, all the image block previews disappear…

 ![image](https://europe1.discourse-cdn.com/flex017/uploads/getkirby/original/2X/f/fc061bc90e9f924c6c9b7552cb314f96509547e5.png)

But everything is still there in the front-end because the snippet works. (You can see the centred image.)

 ![image](https://europe1.discourse-cdn.com/flex017/uploads/getkirby/original/2X/6/6cfda1f7902c88f1e492705430a74244847d8d9b.png)

I’m struggling to work out how to get my `index.js` to work properly.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [December 16, 2024, 5:05pm UTC](https://forum.getkirby.com/t/difficulties-building-a-custom-image-block-plugin/33082/4 "2024-12-16T17:05:24Z")

</div>

Could you post the complete code or do you have it in a repo?

---

<div class="post-metadata">

**Author:** ![whitmoa](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/whitmoa/32/16395_2.png) [@whitmoa](https://forum.getkirby.com/u/whitmoa)\
**Post date:** [December 17, 2024, 5:18pm UTC](https://forum.getkirby.com/t/difficulties-building-a-custom-image-block-plugin/33082/5 "2024-12-17T17:18:31Z")

</div>

It’s not in a repo yet but I’ll add one. Link to follow.

---

<div class="post-metadata">

**Author:** ![whitmoa](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/whitmoa/32/16395_2.png) [@whitmoa](https://forum.getkirby.com/u/whitmoa)\
**Post date:** [December 17, 2024, 9:38pm UTC](https://forum.getkirby.com/t/difficulties-building-a-custom-image-block-plugin/33082/6 "2024-12-17T21:38:06Z")

</div>

Sonja, I’ve created a new repo – [kirby-image-block](https://github.com/brandsis/kirby-image-block) – with the full code in its current state. I look forward to feedback. Thanks.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [December 17, 2024, 9:57pm UTC](https://forum.getkirby.com/t/difficulties-building-a-custom-image-block-plugin/33082/7 "2024-12-17T21:57:09Z")

</div>

I think the problem here is that you will have to give your custom block a new name. Then move the data part inside the block definition:

```auto
panel.plugin("brandsistency/image-block", {
	blocks: {
		myimage: {
			data() {
				return {
					back: this.onBack() ?? "white"
				};
			},
			computed: {
				captionMarks() {
					return this.field("caption", { marks: true }).marks;
				},
				crop() {
					return this.content.crop ?? false;
				},
				src() {
					if (this.content.location === "web") {
						return this.content.src;
					}
					if (this.content.image?.[0]?.url) {
						return this.content.image[0].url;
					}
					return false;
				},
//...

```

```auto
Kirby::plugin('brandsistency/image-block', [
	'blueprints' => [
		'blocks/myimage' => __DIR__. '/blueprints/blocks/myimage.yml'
	],
	'snippets' => [
		'blocks/myimage' => __DIR__. '/snippets/blocks/myimage.php'
	]
]);

```

`myimage` is probably a stupid name, but you get the idea. And everything will work as expected.

Note that export/import statements only every work in single file components that require a build system. But it doesn’t really make sense to require this default.vue here.

---

<div class="post-metadata">

**Author:** ![whitmoa](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/whitmoa/32/16395_2.png) [@whitmoa](https://forum.getkirby.com/u/whitmoa)\
**Post date:** [December 18, 2024, 11:02pm UTC](https://forum.getkirby.com/t/difficulties-building-a-custom-image-block-plugin/33082/8 "2024-12-18T23:02:19Z")

</div>

Thank you. That’s worked in general but I’m still struggling with addition of the classes in the Panel preview, which is the main reason for creating a plugin rather than just a custom blueprint and snippet.

With my custom button block plugin everything works perfectly. If I set the alignment to centred, the button is centred in the Panel as well as the front-end. That’s because the class `txt-c` is added in the Panel, which I’ve then been able to style…

```auto
panel.plugin("brandsistency/button-block", {
  blocks: {
    button: {
      computed: {
        placeholder() {
          return "Button text...";
        },
        className() {
          let value = this.content.alignment;
          let className = value === 'center' ? 'txt-c' : value === 'right' ? 'txt-r' : ''; return className;
        }
      },
      template: `
        <button :class="className" type="button" @click="open">{{ content.text }}</button>
      `
    }
  }
});

```

I’ve included exactly the same `className` code in the relevant places in the custom image block `index.js` file but it isn’t working the same way. It does not add the `txt-c` class in the Panel. In fact, it’s adding the class `k-block-type-image-auto` even though I temporarily removed that.

As a test, I also tried overriding some of the styling in the `index.css` file but that has no impact.

Could it still be picking up ‘instructions’ from the standard image block `Image.vue` file? Do I need to do something to bypass that?

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [December 19, 2024, 8:46am UTC](https://forum.getkirby.com/t/difficulties-building-a-custom-image-block-plugin/33082/9 "2024-12-19T08:46:42Z")

</div>

Did you also set the preview to the new block name and the block type, see [Custom block examples | Kirby CMS](https://getkirby.com/docs/guide/page-builder/block-examples)

```auto
k-block-type-nameOfBlock

```

---

<div class="post-metadata">

**Author:** ![whitmoa](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/whitmoa/32/16395_2.png) [@whitmoa](https://forum.getkirby.com/u/whitmoa)\
**Post date:** [December 20, 2024, 11:29am UTC](https://forum.getkirby.com/t/difficulties-building-a-custom-image-block-plugin/33082/10 "2024-12-20T11:29:48Z")

</div>

I’ve replaced instances of `k-block-type-image` with `k-block-type-myimage` in what I think are all the relevant places. I’ve cleared both the Kirby and the browser cache. But still the Panel preview seems to be picking up the ‘old’ image template.

I can’t figure out what I’m missing.

I’ve updated the [GitHub repo](https://github.com/brandsis/kirby-image-block) with the latest version of my code and I’d be grateful if you’re able to spot any other errors.

---

<div class="post-metadata">

**Author:** ![distantnative](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/distantnative/32/11319_2.png) [@distantnative](https://forum.getkirby.com/u/distantnative)\
**Post date:** [December 21, 2024, 2:28pm UTC](https://forum.getkirby.com/t/difficulties-building-a-custom-image-block-plugin/33082/11 "2024-12-21T14:28:32Z")

</div>

Your new `myimage` block blueprint is still using the `image` block preview, not your `myimage`: [kirby-image-block/blueprints/blocks/myimage.yml at main · brandsis/kirby-image-block · GitHub](https://github.com/brandsis/kirby-image-block/blob/main/blueprints/blocks/myimage.yml#L3)

---

<div class="post-metadata">

**Author:** ![whitmoa](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/whitmoa/32/16395_2.png) [@whitmoa](https://forum.getkirby.com/u/whitmoa)\
**Post date:** [December 31, 2024, 9:03pm UTC](https://forum.getkirby.com/t/difficulties-building-a-custom-image-block-plugin/33082/12 "2024-12-31T21:03:32Z")

</div>

Thanks, Nico. That solved it. It had to be something obvious, didn’t it! 😉
