Kirby 101

A rundown of Kirby.
A blazingly fast, ultra efficient & extremely fun CMS.

🎉

File based

There is no Database.

Databases are great for data.
Text files are great for... text.

Advantages

  • Easy setup
  • Easy transfer
  • Easy manipulation
  • Blazingly fast

How easy?!

really easy!

  • Transfering content is just an rsync away
  • Manipulating content is editing readable files
  • Manipulating structure is just dragging and renaming some folders

Blazingly fast?!

Average page rendering (TTFB) can be easily under 100ms. Even 50ms is in reach. (with caching disabled!)

  • Using only files utilizes the hardware cache of disks
  • The linux file system works magic
  • Server grade SSD is made for extreme file performance, so build right on it's core
  • ie: Fetching a single content item is fast as hell
  • and: Full text search over flat files is amazingly fast

again:

Databases are great for data.
Text files are great for... text

Limits?

Yes

Testing has shown that at sites larger than 5000 pages rendering of a full list of those pages can get a bit sluggish (over a second on a solid server). If you need more than that, see if there is content you can migrate to a database (ie: ecommerce products or stuff like that). Kirby has excellent functions to deal with database content as well. Or consider reconsider switching to a larger scalable CMS.

Consistent, transparent, Lightweight
Frontender friendly to the bone
🤓

  • Everything in Kirby is consistent
    Functions, locations, objects, etc
  • Folder & programming structure is as flat as possible
    No hellishly deep located files & objects
  • Only what's needed is loaded
    No overhead, not half the internet is preloaded *just in case*
  • Only basic building blocks are provided
    You're not pushed in structures with prefab templates. Build what you need!

Folder structure

/contentSite content
/kirbyThe Kirby app (frontend rendering)
/panelThe Panel app (cms)
/site/accountsUser accounts
/site/blueprintsPage definitions for the CMS
/site/configSite config
/site/controllersTemplate controllers
/site/fieldsCustom CMS fields
/site/modelsContent models
/site/pluginsCustom functionality goes here
/site/snippetsReusable snippets: snippet('mysnip')
/site/templatesTemplates

And then there's some cache folders: /thumbs & /site/cache

Content & Templates

Folders are the base of the website structure (urls).
Text files (YAML format) contain the content and sibling files are available as related content.

Folder hierachy

The numbers are for sorting, other sorting formats are available.
An unsorted folder is tagged "invisible".

content
| 1-about-us
| 2-projects
| |  1-beautiful-project
| |  2-another-great-project-we-did
| |  an-unpublished-project
| 3-contact
| home.txt
| error.txt
| site.txt

Note: An invisible content item is not unreachable. The URL does exist. It also does show up if you request $pages->index() but not if you request $pages->index()->visible()

Page rendering

URL > content > template

Folder name translates to page url, file names translate to template

The URL:
https://mysite.com/blogs/some-blog-about-something

Will translate to the content file:
/content/blogs/1-some-blog-about-something/blog.txt

And because the file is named "blog.txt" it will try to render with the template:
/site/templates/blog.php.

If not found it defaults to the default template:
/site/templates/default.php

Content files are in YAML format

i.e: /content/1-about-us/default.txt might look like this:

Title: Over ons
----
Text: This is the content of this field in (link:https://daringfireball.net/projects/markdown/syntax text:markdown) syntax
----
Customfield: Value of the field

The content is then available in the template:

<article>
  <h1><?= $page->title() ?></h1>
  <?= $page->text()->kirbytext() ?>
  <footer>
    <?= $page->customfield() ?>
  </article>
</article>

kirbytext() is one of the many base functions for content rendering in Kirby.
Find all of them in the Kirby Cheat Sheet

Templating objects

$pageThe current page object
$siteThe site object with the content of site.txt and more
$pagesA collection of all pages

No CMS yet?!

Panel, the Kirby CMS

We could stop here... URL > content > template > rendering is enough te get things going. But this requires all content to be edited by hand.

Luckily Kirby comes with an optional CMS called "Panel"

"Blueprints" are linked with your content and can auto generate and modify the content in your site.

The CMS is located at https://site.com/panel

The panel

  • Responsive
  • Single page focus
  • Fully customizable

Dashboard

Page

Site options

Blueprints / Fields

Blueprints

Blueprints shape & customise your CMS for your content

Create "blueprints" with the same name as your templates in de the /site/blueprints folder to define the layout of the fields in the CMS.

title: Bloglist
pages:
  template:
    - blog
options:
  template: false
files: true
fields:
  title:
    label: Title
    type:  text
  intro:
    label: Text
    type:  textarea

Site blueprint

Pro-tip

😜

The "site options" page is also fully customisable. Create a blueprint calles /site/blueprints/site.yml and you're good to go!

Panel field types

Checkbox

A single checkbox field

Checkboxes

A list of checkbox fields

Date

A date picker field

Datetime

A date and time picker field

Email

An email input field with autocompletion and validation

Headline

Creates a headline to group fields

Hidden

Creates a hidden field

Image

A drag and drop image select field with preview thumbnail

Info

A plain HTML field for user instructions

Line

Draws a horizontal line to separate fields

Number

A number input field with validation

Page

A single page input with autocompletion

Radiobuttons

A list of radio buttons

Select

A simple selectbox field

Structure

Structured data input, which stores data in a field as YAML.

Tags

An interactive tags input field with autocompletion

Tel

A phone number input field

Text

A standard, single-line input field

Textarea

A textarea field, which auto-resizes and has built-in format buttons.

Time

A time picker field

Toggle

Yes/no or on/off toggle

Url

A URL input field with validation

User

A user input field with autocompletion for registered users.

Full list: Kirby Cheatsheet

Not satisfied yet?! Custom field types are rather easy to build: Kirby docs on custom form fields

Advanced shit

💩

  • Snippets
  • Template controllers
  • Page models
  • Plugins
  • Routes

Snippets

Snippets are reusable parts that can be inserted with the snippet() function.

/site/snippets/nav.php could look like this:

<ul class="navlist">
  <?php foreach($pages->visible() as $p): ?>
    <li<?php e($p->isOpen(), ' class="active"') ?>>
      <a href="<?php echo $p->url() ?>"><?php echo $p->title() ?></a>
    </li>
  <?php endforeach ?>
</ul>

And it can be used in a template like <?php snippet('nav'); ?>

Template controllers

PHP templating is efficient but requires some discipline. Keep your templates clean. Put logic into template controllers (or models).

For a template /site/templates/bloglist.php
create a controller /site/controllers/bloglist.php

<?php
return function($site, $pages, $page) {
  // get all articles and add pagination:
  $articles = $page->children()->visible()->flip()->paginate(20);
  // create a shortcut for pagination:
  $pagination = $articles->pagination();
  // return the $articles & $pagination object to the template:
  return compact('articles', 'pagination');
}

Now $articles is a collection of paginated articles in the bloglist.php template
and $pagination is the pagination object

Page models

A page model extends the default page object with extra functionality.

For a content item called blog.txt the model is /site/models/blog.php

  <?php
  class BlogPage extends Page {
    public function cover() {
      return $this->image('cover')->or('assets/img/default-cover.jpg');
    }
  }
  

The cover image is then available as $page->cover()

Plugins

Plugins can be anything from dashboard extensions to page render functionalities.

Readmore: Kirby plugin docs

Routes

In the core URLs are rendered by conten dirs. But routes are another way to catch an URL.

routes(array(  
  array(
    'pattern' => '(.*)/json', 
    'action'  => function($uid) {
      $data = $pages->find($uid)->serialize();
      return response::json($data);
    }
  )
));

This will make every url available in json format.

Read more: Kirby routing docs

Resources

There's so much more

  • Multilanguage
  • User roles
  • Custom fields
  • Kirby CLI
  • ...

Read all about it: