Skip to content

Quicktip: Reusing KirbyTags in custom tags

Extend existing KirbyTags in custom tags with less hassle.

Sometimes, you may want to extend an existing KirbyTag in a custom KirbyTag, for example, to add attributes or to modify the HTML output.

To prevent having to copy the complete code, you can reuse parts of the original tag. With…

Kirby\Text\KirbyTag::$types['image']

…you get access to the original image KirbyTag.

With…

Kirby\Text\KirbyTag::$types['image']['attr'],

…you have access to the original attributes.

And with…

Kirby\Text\KirbyTag::$types['image']['html'],

…to the original HTML.

Using the following code we can thus reuse the attributes array and put a wrapper around the original HTML.

/site/plugins/custom-tags/index.php
<?php

Kirby::plugin('your/plugin', [
    'tags' => [
        'custom-image' => [
            'attr' => Kirby\Text\KirbyTag::$types['image']['attr'],

            'html' => function($tag) {

                $image =  Kirby\Text\KirbyTag::$types['image']['html'];
                $markup = $image($tag);

                $html = '<div class="imagewrapper">' . $markup . '</div>';

                return $html;
            }
        ]
    ]
]);

We can also extend the attributes array by merging it with new attributes, and replace parts of the original HTML using string replacement:

/site/plugins/custom-tags/index.php
<?php

Kirby::plugin('your/plugin', [
    'tags' => [
        'imageset' => [
            'attr' => array_merge(
                Kirby\Text\KirbyTag::$types['image']['attr'],
                [
                    'srcset'
                ]),

            'html' => function($tag) {

                $file = $tag->file($tag->value());
                $srcset = $tag->srcset ? explode(',', $tag->srcset): null;
                $result = Kirby\Text\KirbyTag::$types['image']['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),
                ]);

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

                return $result;
            }
        ]
    ]
]);