Image block preview

I want to change the block preview for image blocks.

I tried to use

But I also saw here and there that it is not possible to overwrite the build in previews.

It looks like it is fixed here:

But when I copy the code from the first link, all plugins stop working.

What should I do to create a preview for the image block?

Thank you!

What have you tried?

You need to create a plugin with an image preview.

I followed this tutorial:

But when I converted it to the Vue component, all plugins stopped working, or at least the previews from custom block plugins.
So it is possible to overwrite the default preview?

Yes, that should actually work fine, can’t test now, though.

Apart from that, the tutorial does not work like it should.
Bellow my code. Maybe I do something wrong?

index.js

import Button from "./components/Buttonasa.vue";

panel.plugin("your-project/button-block", {
  blocks: {
    button: Button
  }
});

index.php:

<?php

Kirby::plugin('your-project/button-block', []);

components/button.Vue:

<template>
  <input
    type="text"
    :placeholder="placeholder"
    :value="content.text"
    @input="update({ text: $event.target.value })"
  />
</template>

<script>
export default {
  computed: {
    placeholder() {
      return "Button text …";
    }
  }
};
</script>

<style>
.k-block-type-button input {
    border: 2px solid #000;
    border-radius: 3rem;
    padding: .25rem .75rem;
    cursor: pointer;
    font: inherit;
    text-align: center;
}
.k-block-type-button input:focus {
    outline: 0;
    border-color: var(--color-focus);
}
</style>

Your file seems to be called button.Vue but you import Buttonasa.vue? Just a typo?

kirbyup should complain…

That was just to temporarly disconnect the vue file. When I repair the path the issue remains the same: No other plugins seem to work. Also the preview of the button block does not seem to be effected.

Other then that this is just an issue I bumped in too, while working towards a custom preview of the image block. When I get the button preview to work, I might be able to figure out the image preview too. Thanks!

The folder is called ‘site/plugins/button’.

The yaml does not mention a preview:

name: Button
icon: bolt
fields:
  location:
    label: field.blocks.image.location
    type: radio
    columns: 3
    default: "kirby"
    options:
      kirby: Kirby
      web: Web
      javascript: Javascript

I don’t think it matters but for the sake of completeness…

You need to assign the preview name in the yaml file.

And you also need to register your block blueprint in the index.php file.

What would be the name, in the case of the above?
And how do I register the block blueprint?

It is a bit strange that the tutorial is not leading towards a functional plugin right? or am I missing a step? Is there a page where I can learn more about the plugins, so I get a better understanding? I feel like I am asking stupid questions…

In the plugin I just want to change the preview of the block.
The yml and php file are good as they are.
Still in the dark here :frowning:

Please post the code you are using for the image block preview, so I can test it later.

Thanks all!

Bellow the code:

image blueprint:

name: field.blocks.image.name
icon: image
preview: image
fields: etc…

site/plugins/jv-image-block/

index.php:

<?php

Kirby::plugin('jv/image-block', []);

index.js:

import Image from "./components/Image.vue";

panel.plugin("jv/image-block", {
  blocks: {
    image: image
  }
});

components/Image.vue

<template>
	<k-block-figure
		:caption="content.caption"
		:caption-marks="captionMarks"
		:empty-text="$t('field.blocks.image.placeholder') + ' …'"
		:is-empty="!src"
		empty-icon="image"
		@open="open"
		@update="update"
	>
		<template v-if="src">
			<k-aspect-ratio v-if="ratio" :ratio="ratio" :cover="crop">
				<img :alt="content.alt" :src="src" />
			</k-aspect-ratio>
			<img
				v-else
				:alt="content.alt"
				:src="src"
				class="k-block-type-image-auto"
			/>
		</template>
	</k-block-figure>
</template>

<script>
/**
 * @displayName BlockTypeImage
 * @internal
 */
export default {
	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.location === "parent") {
				return this.content.imageparent[0].url;
			}
			if (this.content.location === "all") {
				return this.content.imageall[0].url;
			}
			if (this.content.location === "site") {
				return this.content.imagesite[0].url;
			}
			if (this.content.image[0]?.url) {
				return this.content.image[0].url;
			}
			return false;
		},
		ratio() {
			return this.content.ratio || false;
		}
	}
};
</script>
<style>
.k-block-type-image .k-block-figure-container {
	display: block;
	text-align: center;
	line-height: 0;
}
.k-block-type-image-auto {
	max-width: 100%;
	max-height: 30rem;
}
</style>

Where is your index.js located?

The plugin seems to have no other effect then to cancel the functionality of the other plugins.
Thanks in advance!

site/plugins/jv-image-block/index.js
site/plugins/jv-image-block/index.php
site/plugins/jv-image-block/components/Image.vue

But that doesn’t make sense. Since you are using a single file component, you need a package.json and the kirbyup bundler to create the final index.js next to the index.php.

Check out this recipe for an example: Creating a custom block type from scratch | Kirby CMS

It seems though that we have an error in the docs linked above, because the example doesn’t mention this.

See also: To bundle or not to bundle: differences of creating plugins with or without a build process | Kirby CMS

Schermafbeelding 2022-12-13 om 20.30.32

The other plugin work again now, but the image preview still seems to have no effect.
I added some text to see if it is used. But I don’t see the span :frowning:

<template>
<span>test</span>
	<k-block-figure
		:caption="content.caption"
		:caption-marks="captionMarks"
		:empty-text="$t('field.blocks.image.placeholder') + ' …'"
		:is-empty="!src"
		empty-icon="image"
		@open="open"
		@update="update"
	>
		<template v-if="src">
			<k-aspect-ratio v-if="ratio" :ratio="ratio" :cover="crop">
				<img :alt="content.alt" :src="src" />
			</k-aspect-ratio>
			<img
				v-else
				:alt="content.alt"
				:src="src"
				class="k-block-type-image-auto"
			/>
		</template>
	</k-block-figure>
</template>

<script>
/**
 * @displayName BlockTypeImage
 * @internal
 */
export default {
	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.location === "parent") {
				return this.content.imageparent[0].url;
			}
			if (this.content.location === "all") {
				return this.content.imageall[0].url;
			}
			if (this.content.location === "site") {
				return this.content.imagesite[0].url;
			}
			if (this.content.image[0]?.url) {
				return this.content.image[0].url;
			}
			return false;
		},
		ratio() {
			return this.content.ratio || false;
		}
	}
};
</script>
<style>
.k-block-type-image .k-block-figure-container {
	display: block;
	text-align: center;
	line-height: 0;
}
.k-block-type-image-auto {
	max-width: 100%;
	max-height: 30rem;
}
</style>

Here’s a typo, the value should be uppercase since your are importing as Image, so

    image: Image