Design & Develop Your Own Blog

Learn to build a lean & flexible blogging platform

Extending Kirbytext

A couple of chapters ago, we’ve had a closer look at Kirbytext - and we saw that it’s really a perfect mixture of plain text, Markdown syntax, and its own “Kirbytags”. It offers a host of elements: from lists to hyperlinks, from very flexible image tags to download links it covers most use cases.

However, there may come times when the specifics of your project demand for your own, custom Kirbytags. And luckily, Kirbytext is indeed extensible.

As an example, let’s write our own “button” tag. Our goal is that the we can use the following in our content:

( button:Read more link:posts/pencil class:red)

…and automatically and comfortably have it render to something like this:

<a class=“button red” href=“http://localhost:8888/posts/pencil”>Read more</a>

The code examples on this website cannot display Kirbytags 100% accurately: in real code, there should be no space between the bracket and the Kirbytag's keyword: "( button:...", for example.

This inaccurancy is due to the fact that this website is itself made with Kirby. The code on GitHub, however, contains the correct formatting.

Creating Our Custom Tag File

Your custom Kirbytags all live in a “tags” subfolder in “site”. Let’s start by creating a file named “button.php” inside of this tags directory.

Tag Boilerplate

The basic structure of a custom Kirbytag is simple:

kirbytext::$tags[‘tagname’]() = array(
  'attr' => array('attr1’, ‘attr2’),
  'html' => function($tag) {    
    return $output;

The tag is defined as an array with two items:

  • In “attr”, all attribute names for this tag are defined. Kirby has to know what keywords to watch out for when parsing the tag contents; in our case, it needs to look for “button:”, “link:” and “class:”.
  • In “html”, we define a function that returns the final HTML that we want to output.

Defining Our “button” Tag

We’ll start by defining the tag and its attributes. The tag’s name (“button” in our case) is automatically available as an attribute and doesn’t have to be defined explicitly in the “attr” array:

kirbytext::$tags['button']() = array(
  'attr' => array(
    'link', 'class'

The “html” function is where we can generate the output that our tag should generate.

'html' => function($tag) {

Via its $tag parameter, we have access to the following information:

  • An attribute value via $tag->attr(‘attr-name’)
  • The current page via $tag->page()
  • All files in this page’s folder via $tag->files()
  • A concrete file via $tag->file('myfile.jpg')

Let’s start by getting all relevant attribute values:

$class = $tag->attr('class', 'button');
$link = $tag->attr('link', false);

Notice that the attr() method takes a default value as its second parameter (for cases where this particular attribute wasn’t specified in the content).

With this information at hand, we can start assembling our actual HTML output:

  $html  = '<a href="'. url($link) .'" class="'. $class .'">';
  $html .= $tag->attr('button');
  $html .= '</a>';

  return $html;

Code on GitHub

Using Our New Kirbytag

Finally, it’s time for our tag’s maiden voyage - let’s use it on content/05-chevron/chevron.txt:

…this fine portion of facial hair. 

( button:Magnum link:

Lorem ipsum dolor…

Notice how we deliberately left out the “class:” attribute. We’ve defined a proper default value for it and therefore don’t have to use it (unless we want to override that default value).

Here’s how our beautiful new tag renders in the browser:

About Us

As the makers of Tower, the best Git client for Mac and Windows, we help over 100,000 users in companies like Apple, Google, Amazon, Twitter, and Ebay get the most out of Git.

Just like with Tower, our mission with this platform is to help people become better professionals.

That's why we provide our guides, videos, and cheat sheets (about version control with Git and lots of other topics) for free.