Custom icon text for panel pages section

Hi all,
I want to add some eye candy for my clients’ panel: In a pages section with a cards layout, I thought it would be cute to override the icon with a custom text. In general, I thought it would be a nice thing to be able to do something like

  headline: Published Topics
  type: pages
  status: listed
  templates: topic
  layout: cards
  image: '{{ page.number }}'


# page.yml
icon: '{{ page.number }}'

so this:

becomes this:

since it’s not natively possible, does anybody have a suggestion how to write a quick custom plugin to add this functionality? Maybe it’s not worth the effort after all, just thought it would be cute.

quick custom plugin

The quickest (and it’s really not that quick) that comes to mind would be:

  • creating a page method that returns an Asset to a non existing svg file
  • a custom route that responds to requests made to the URL of this non existing svg file, that renders the svg “on the fly” with your number inside of it.
  • setting the image property of the pages section to the above method:
    image: page.makeNumber(page.number)

Disclaimer: haven’t tried it, maybe kirby won’t let you create Asset objects to non existing files…

I’m not sure, but maybe this is what You’re looking for.

quick custom plugin

you could also create your own Asset class (extending the kirby one) and use it to return a base64 encoded svg image as url.

I’ve hacked something together for you:



namespace bruno\textpreview;

use Kirby\Cms\Asset;
use Kirby\Cms\App as Kirby;

class VirtualAsset extends Asset {
    protected $text = '';

    public function __construct(string $text) {
        $this->text = $text;

    public function url(): string {
        $text = $this->text;
        return 'data:image/svg+xml;base64,' 
          . base64_encode(
              "<svg xmlns=''>" . 
                "<text fill=\"white\" x=\"50%\" y=\"50%\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-size=\"24\">$text</text>" .

Kirby::plugin('bruno/textpreview-pagemethod', [
    'pageMethods' => [
        'textPreview' => function($text) {
            return new VirtualAsset($text);

then use it like this:

    type: pages
    image: page.textPreview(page.children.count)

Looks like this:

Now make it pretty :slight_smile:


wheeeeee, thanks so much! This is amazing!

also thanks @Cris, had no idea, this might come in handy at a different point in time.