Hello Kirby, I like you.

Marc Wieland
CMS Decision
Published in
10 min readJul 10, 2019

This post was originally published on my personal blog:
https://marcwieland.name/hello-kirby-i-like-you/

I’d like to show you the basics of Kirby by creating a simple website. Kirby is a file-based CMS, which means that it needs no database — the content is stored inside multiple text files.

On a daily basis, I’m a WordPress developer, but I like to try out new applications and frameworks. This way I can learn new stuff and keep my eyes open for new things.

It’s my first time working with Kirby. By the way, a file-based CMS is also a new solution for me.

Following I’ll build a website for my former company motionstudio based on Kirby (the site is not online anymore). I’ll show you the key points of the CMS, so you get a good insight and get an idea of how it works. Now, let’s get started.

Disclaimer: The site was built on Kirby 2. There’s Kirby 3 available with a complete rebuild of the UI in VueJS and some nice improvements. But overall it’s not completely different.

Facts

Pros:

  • Simple templating (easy to understand)
  • Flexible fields

Cons:

  • Price (129$ per site)
  • Not for large websites (because of no DB)

Backend

Blueprints

It’s quite easy to set up your content in the backend to get started. Just create a blueprint. Kirby uses blueprints to define fields in the backend, for example, title, content and tags. It doesn’t have to exist in special fields. You're free to create what you need. You can create inside “site/blueprints” a file or edit the default.php and create your needed “form-types” in the YAML-syntax.

There are a lot of predefined field types, especially for text-based content (text, url, mail, telephone, etc.). Sadly there is no predefined form type for images or other media types.

For images, there is a possibility to set “files” to true inside a blueprint. In my case, a form type would be better. However, with files set to true, I can select an image (or also multiple) on the left side of the content.

title: Page
pages: false
files: true
fields:
title:
label: Title
type: text
subtitle:
label: Subtitle
type: text
text:
label: Text
type: textarea

After the blueprint is set, you can create a new site and fill in the content.

After I created all normal pages I can go forward an create the portfolio.

Portfolio

I create a new blueprint for the portfolio main page.

title: Arbeit
pages:
template: reference
files: false
fields:
subtitle:
label: Subtitle
type: text

After that, I create one more blueprint for all subpages, the reference by itself. I already referenced the template in the code above (template: reference). This way we set the references as a subpage to the portfolio.

title: Reference
pages: false
files:
sortable: false
fields:
title:
label: Title
type: text
year:
label: Year
type: text
tags:
label: Tags
type: tags

After all, the blueprint is created, it’s time to create the page in the backend. Select the right template and everything is configured based on the blueprints.

Create a “Work” page to show all references

It isn’t possible to change the template after you created the page. The only thing you can do, if you decided to change the name of a template, is to delete the page and create a new one.

ATTENTION: Maybe you can’t select a template. Then you have the tag “pages: default” set on a blueprint file (maybe in site.php).

Don’t get confused by the naming “blueprint” and “template”. These two features are working quite near together. This is also why you can’t change the template after you created the page.

After the main portfolio page is created I can create every single reference as kind of subpage inside the portfolio page.

I assigned some fields to the reference inside the blueprint before, which were the title, year and tags. Just fill in the information in the fields and the content is ready.

We’ve created all pages and references now. The biggest part inside the backend is done. We just have to create the front page and add some contact/footer information.

Contact

I create one more blueprint for the contact page. In this example, you can see how powerful and flexible the blueprint can be.

We can create a lot of different predefined fields and also create them in different sizes. We can also add placeholder text, default text and also hints.

Easily create fields in Kirby

Frontend

Snippets

To structure your code you can use snippets in Kirby. These snippets live inside “site/snippets”. I create one for the header, the navigation and the footer. By using snippets we can keep the templates very lean.

You can include snippets inside snippets itself and nest these or also include these inside templates for sure. Just do this:

<?php snippet(‘header’) ?>

Head

Kirby gives you some helpers to do stuff simpler. But you’re also free to do everything by yourself.

For example, for including scripts and styles there exists a helper function. This looks like this:

<?php echo css(‘assets/css/style.css’) ?><?php echo js(‘assets/js/script.js’) ?>

Included title and description looks like this:

<title><?php echo $site->title()->html() ?></title>
<meta name=”description” content=”<?php echo $site->description()->html() ?>”>

Navigation

As far as I know, there is no helper function to create navigation out of the box, similar to what I know from WordPress.

Because I create a one-pager this doesn’t matter. I just go through every page which is visible and print out the slug with a “#” before as the link and add the normal title inside the link. That’s it — no magic.

<ul>
<?php foreach($pages->visible() as $p): ?>
<li>
<a href=”#<?php echo $p->slug() ?>”>
<?php echo $p->title()->html() ?>
</a>
</li>
<?php endforeach ?>
</ul>

Content

I’ve got some different types of pages, which has to look different. There are no real pages on my site because it’s a one-pager, but this doesn’t matter so far. I created a similar structure in the backend (panel).

Default content

The following types exist:

  • Home (frontpage)
  • Normal page (text and image)
  • References (preview of all projects)
  • Contact page (form and contact info)

To make a difference between the different content types, I created the blueprints in the backend. To output the different fields in the frontend I create special templates for every type. Make sure to use the blueprints wisely.

A dynamic solution would be a dropdown field in the backend (panel) to choose a template from. Then I can later read out this value and do whatever I want to do.

Templates

You can use different templates to display the content differently.

Kirby will automatically display your content in your defined template if it has the same name. The content is stored in “/content/PAGENAME.txt” and if in “/site/templates” a file with the name PAGENAME.php exist it will take this.

A nice part about Kirby is that it has built-in support for controllers. Now we can just use markup inside our templates and do the logical stuff inside the controller.

Because we’re using a one-page layout we just use one template called “home.php”. From this file, we just include snippets and do the logical stuff inside this file.

Social

There is also a section for general options available. In this part, there are fields like page title, description, author, etc. there to edit. Like in every page you can easily add custom fields to it. The blueprint is called “site.php”.

Custom fields inside the site options

I do this for the social media links at the bottom of the page. I created a URL-field for every social media platform in the main setting panel. To access this information we can easily call $site->FIELDNAME and we’ve got the URL.

<?php if( $site->facebook()->isNotEmpty() ): ?>
<li>
<a href=”<?= $site->facebook() ?>” target=_blank>
<i class=icon>F</i>
</a>
</li>
<?php endif; ?>

The icons are created with Font Awesome.

Home section

To make the image on the frontpage changeable, we use inline styles. Because the image is set with CSS background, we could include the source file in the CSS. This has the downside, that we can’t change the picture very fast (we have to edit the CSS (file). So we set all properties through CSS and just set the background-image property inline in the HTML.

<section id=”<?= $section->uid() ?>” 
style=”background-image:url(<?= $bgImage ?>)”>

We’ve got also a scroll down button on the first page. To keep this dynamic we just do the following:

$scrollTo = $pages->visible()->first()->next()->uid();

Inside Kirby, you can achieve a lot through different methods like in the code snippet above. Additionally, it’s very readable.

After we grabbed the right page, we can just add a link to the arrow.

<div id=”down_button” class=”fade-it”>
<a href=”#<?= $scrollTo ?>”><span>Scrollen</span></a>
</div>
Frontpage

Default content

The normal content, where all services of the company are located, is very simple. Just a title, a subtitle, a text and an image. This content is wrapped inside a section with an anchor to jump from the menu to it. To make it dynamic we put this inside a foreach statement. Just like we know it from other content management systems.

<?php foreach($pages->visible() as $section): ?> <section id=”<?= $section->uid() ?>”>  // The content </section><?php endforeach ?>

To echo out a title we just to this:

$section->title()

The subtitle looks very similar. Remember that this is a custom field created by the blueprint.

<?= $section->subtitle() ?>

The image is as simple as the title.

$section->images()->first()->url()

Instead of the URL, we can use alt or caption or whatever field (metadata) we like to output.

I like the simplicity and the customizability of the fields.

We can add metadata fields to the files (e.g images) similar to how we created normal fields to the pages.

files: true
fields:
alt:
label: Alternative Text
type: text
Image metadata (custom fields)

On every new page, the text and image position changes. On the first page the image is left and the text right. On the second page the other way around (image right, text left) and so on. To do this, we easily get the page number (index).

$index = $section->num();
$position = $index % 2;

And modulo this with 2. Following that we get 0 or 1 which stands for the two states. With an if-statement, we check the position value and set the image to the left or right side depending on the value.

Contact Page

Inside the contact page is nothing very special. There are just a lot of custom fields to use, but this is no problem. I created all fields above in the blueprint and just have to include these inside my snippet. I created this much fields because I use the schema markup for the contact information.

<p itemprop=”telephone”><?= $section->phone() ?></p>
Contact page

Portfolio

The portfolio is also quite easy to create. Check if there’s an image, then yes, then output the URL inside an “img” tag and include two span elements for the reference information after this image (reference title and tag).

<img src=”<?= $imageUrl ?>” alt=”<?= $reference->title()->html() ?>”/>
<span><?= $reference->title()->html() ?></span>
<span class=”work-slider”><?= $reference->tags() ?></span>

Around the markup of the reference, we create a foreach loop, where we query all pages from the portfolio. We limit the amount to 9 elements as a maximum.

foreach(page(‘work’)->children()->visible()->limit(9) as $reference):
// ...content...
endforeach
Reference section

Summary

After finishing this simple website I really like Kirby. The learning curve is very low, especially when you ever worked with another CMS. All features are very well thought-out and if you try to stick to the philosophy of the CMS, as I try, there’s a lot of fun building with it.

I also see that Kirby isn’t ready and also meant for every site. For bigger websites, Kirby isn’t the CMS of choice. But for small and simple website Kirby is a great choice.

Kirby’s documentation is very good and you’ll find a lot in it.

Remember that Kirby isn’t free to use. It has a very unique license model. First try, then buy.

Kirby’s license model is based on a single idea: you should be happy with Kirby first, before you buy a license. — Kirby’s Website

Kirby (https://getkirby.com/)
Kirby Docs (https://getkirby.com/docs)

The community is very active and you get answers very fast. I had some questions and got within a few hours the answer(s) — as you can see it was 2016:
https://github.com/getkirby/panel/issues/750

Thanks for reading and hitting the “recommend” button if you liked the article.
I hope you got an insight into Kirby and try it out by yourself.


Marc Wieland
WordPress. Front-End Development. UX. Cinematography. Landscape Photography. Time-Lapse Video.

--

--

Marc Wieland
CMS Decision

WordPress. Web Development. UX. Cinematography. Landscape Photography. Time-Lapse Video.