Implementing custom tags

I’m wanting to expand the output of the image kirbytag, and this is exactly what I’m after: Quicktip: Reusing KirbyTags in custom tags | Kirby CMS. However, I’m just trying to get my head around how to implement this.

So far, I’ve placed this code in /site/plugins/custom-tags/index.php and changed the tag name to just ‘image’ so that it replaces the original custom tag.

In my templates, the content is being output with:

<?= $page->text()->kt() ?>

What am I missing? Do I need to change the 'your/plugin' path? Or rename the plugin folder? Thanks in advance!

Thats not actually a path, its an identifier for the plugin. I could be wrong I think if you already have a plugin installed called ‘your/plugin’, the first one kirby loads takes precedence. Try change it to something like hicksdesign/customtags.

please also post the contents of /site/plugins/custom-tags/index.php incase theres something a miss in there.

Thanks James! The contents of that file are now:


$originalTag = Kirby\Text\KirbyTag::$types['image'];
Kirby::plugin('hicksdesign/customtags', [
		'tags' => [
				'image' => [
						'attr' => array_merge(

						'html' => function($tag) use ($originalTag)  {

								$file = $tag->file($tag->value());
								$srcset = $tag->srcset ? explode(',', $tag->srcset): null;
								$result = $originalTag['html']($tag);

								if (! $file === true || is_null($srcset) === true) {
										return $result;

								$pattern = '/<img.*?>/i';

								// build a new image tag with the srcset
								$image = Html::img($tag->src, [
										'width'  => $tag->width,
										'height' => $tag->height,
										'class'  => $tag->imgclass,
										'title'  => $tag->title,
										'alt'    => $tag->alt ?? ' ',
										'srcset' => $file->srcset($srcset),
										'decoding' => 'async',

								// replace the old image tag
								$result = preg_replace($pattern, $image , $result);

								return $result;

I just set that up using your code above in a basic project and it works fine when i do this in the text area:

(image: 3sbk0w5f9o.jpg srcset: 300, 800, 1024)

Thanks, it does! I think my issue is then with what the custom tag does - I was looking to output the images’ height and width as well as the src and alt attributes. I guess with this snippet the width and height are entered as values via the tag, rather than taken from the image itself.

For instance, if I’m handling the image in the template, I can do this to output the dimensions:

<?php if($image = $page->mainimage()->toFile()): ?>
   <img src="<?= $image->url() ?>" width="<?= $image->width() ?>" height="<?= $image->height() ?>" alt="<?= $image->alt() ?>">
<?php endif ?>

OK, If you tweak the custom tag so that the part that makes image tag looks like this:

$image = Html::img($tag->src, [
    'width'  => $tag->width ?? $file->width(),
    'height' => $tag->height ?? $file->height(),
    'class'  => $tag->imgclass,
    'title'  => $tag->title,
    'alt'    => $tag->alt ?? $file->alt(),
    'srcset' => $file->srcset($srcset),
    'decoding' => 'async',

That will cause it to use the images physical width and height if you dont supply those values on the kirby tag in the textarea.

edit: just noticed you want the alt as well, you can do the same thing there too. :point_up:

Many thanks for all your help James! After implementing your code changes I found it only worked if I included the srcset attribute in the kirby tag, so I removed the $srcset portion (it was the dimensions I was after), and I’m sorted!

Do you have a ‘donate a coffee’ link at all>

Awesome :slight_smile: my pleasure. Very kind… PayPal