A rundown of Kirby.
A blazingly fast, ultra efficient & extremely fun CMS.
🎉
There is no Database.
Databases are great for data.
Text files are great for... text.
really easy!
rsync
away
Average page rendering (TTFB) can be easily under 100ms. Even 50ms is in reach. (with caching disabled!)
again:
Databases are great for data.
Text files are great for... text
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.
/content | Site content |
---|---|
/kirby | The Kirby app (frontend rendering) |
/panel | The Panel app (cms) |
/site/accounts | User accounts |
/site/blueprints | Page definitions for the CMS |
/site/config | Site config |
/site/controllers | Template controllers |
/site/fields | Custom CMS fields |
/site/models | Content models |
/site/plugins | Custom functionality goes here |
/site/snippets | Reusable snippets: snippet('mysnip') |
/site/templates | Templates |
And then there's some cache folders: /thumbs
& /site/cache
Folders are the base of the website structure (urls).
Text files (YAML format) contain the content and sibling files are available as related content.
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()
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
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
$page | The current page object |
---|---|
$site | The site object with the content of site.txt and more |
$pages | A collection of all pages |
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
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
Pro-tip
😜
The "site options" page is also fully customisable. Create a blueprint calles /site/blueprints/site.yml
and you're good to go!
A single checkbox field
A list of checkbox fields
A date picker field
A date and time picker field
An email input field with autocompletion and validation
Creates a headline to group fields
Creates a hidden field
A drag and drop image select field with preview thumbnail
A plain HTML field for user instructions
Draws a horizontal line to separate fields
A number input field with validation
A single page input with autocompletion
A list of radio buttons
A simple selectbox field
Structured data input, which stores data in a field as YAML.
An interactive tags input field with autocompletion
A phone number input field
A standard, single-line input field
A textarea field, which auto-resizes and has built-in format buttons.
A time picker field
Yes/no or on/off toggle
A URL input field with validation
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
💩
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'); ?>
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
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 can be anything from dashboard extensions to page render functionalities.
Readmore: Kirby plugin docs
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
There's so much more
Read all about it: