Kirby CMS erkunden: die Sicht eines Frontend-Entwicklers

Was ich beim Einsatz von Kirby gelernt habe — von Marketing-Websites bis zu flexiblen, inhaltsgetriebenen Plattformen.

Meine erste Erfahrung mit Kirby CMS liegt etwa zwei Jahre zurück: Wir sollten das Frontend eines Kirby-Basisprojekts überarbeiten — so etwas wie ein White-Label-Produkt. Solche Projekte sind für sich genommen schon anspruchsvoll, erst recht, wenn sie auf einem System aufbauen, von dem man wenig bis gar nichts weiß.

Dieses Gefühl änderte sich fast in dem Moment, in dem ich das Panel öffnete. Vor mir lag ein minimalistisches, intuitives Control Panel, und ich wusste sofort, wo ich die Dinge finde, die ich ändern wollte. Aus Sicht von Admins oder Redaktionen fühlt es sich vertraut an: ein Ort, an dem man sich bewegen und seine Arbeit erledigen kann, ohne gegen das System zu kämpfen.

Beim Coden in Kirby ging es mir ganz ähnlich. Die Ordnerstruktur ist klar, und es gibt sehr wenig Rauschen, wenn man an einem bestimmten Teil einer Website arbeitet. Blueprints beschreiben die Inhaltsstruktur in YAML, der Rest ist PHP mit einer gut dokumentierten API. Man fühlt sich nicht von einem völlig neuen Stack erschlagen, bevor man überhaupt etwas geschafft hat.

Seitdem habe ich an verschiedenen Kirby-Projekten gearbeitet, von geradlinigen Marketing-Websites bis zu komplexeren Seiten mit generischen Layouts und wiederverwendbaren Block-Strukturen, die ganze Blogs tragen. Nach zwei Jahren echter Projektarbeit ist mir Folgendes aufgefallen.

Der Einstieg

Eine Sache vorweg: Kirby ist nicht vollständig Open Source. Lokal könnt ihr es so lange laufen lassen, wie ihr wollt, aber der Einsatz auf einem öffentlichen Server braucht eine Lizenz. Die Preise sind fair, und für Non-Profits und Bildung gibt es Rabatte — es ist also keine Pauschale für alle. Mich stört dieser Kompromiss nicht. Es ist ein direkter Weg, das Team zu unterstützen, das die Software baut, auf die man sich verlässt.

Auf der Backend-Seite sind Blueprints YAML-Dateien, die das Inhaltsmodell und die Redaktionsoberfläche beschreiben. Wer aus der TYPO3-Welt kommt und gerne mit Content Blocks arbeitet, wird die Idee wiedererkennen — nur dass Blueprints in Kirby überall verwendet werden.

Ihr habt einen konsistenten Satz an Feldtypen, die sich überall einsetzen lassen. Egal ob ihr eine komplexe Datenstruktur oder einen einmaligen Abschnitt definiert: Ihr müsst nicht zwei völlig verschiedene Ansätze lernen.

DDEV hat außerdem einen Kirby-CMS-Quickstart auf Basis des offiziellen Starterkits — Kirby auszuprobieren und erste Änderungen zu machen kostet also kaum Aufwand.

Templating und Frontend

Als Frontend-Entwickler muss ich früh ins Templating einsteigen. Anfangs hat mich das erschreckt: Es gibt keine eigene Template-Sprache. Stattdessen schreibt ihr schlichtes HTML und drumherum PHP für Bedingungen, Schleifen und Ausgabe.

Dann merkt man schnell den Vorteil: Auch hier gibt es sehr wenig Neues zu lernen.

Kirby stellt Inhalte über verschiedene PHP-Objekte bereit, deshalb ist PHP auch der direkteste Weg, damit zu arbeiten. Dazu kommen nützliche HTML-, URL-, Übersetzungs- und String-Helper, die Templates sauber halten.

Der Helper Html::attr() macht zum Beispiel aus einem Array von Attributen einen fertigen String und lässt automatisch alles weg, was zu false oder null aufgelöst wird:

php
<a <?= Html::attr([
    'href' => $url,
    'class' => 'button',
    'target' => $external ? '_blank' : null,
    'rel' => $external ? 'noopener noreferrer' : null,
]) ?>>
  <?= htmlspecialchars($label, ENT_QUOTES, 'UTF-8') ?>
</a>

Ihr definiert die Attribute dynamisch und überlasst dem Helper die Entscheidung, was gerendert wird. Kein manuelles String-Zusammenkleben und kein übrig gebliebenes target="", wenn die Bedingung nicht greift.

Komplexe Logik gehört ohnehin in einen eigenen Controller, und einen einzurichten ist unkompliziert. Der Controller trägt denselben Dateinamen wie das Template, zu dem er gehört:

plaintext
/site/templates/article.php
/site/controllers/article.php

Das Array, das der Controller zurückgibt, steht im zugehörigen Template zur Verfügung. Auf beiden Seiten arbeitet ihr mit denselben $page-, $site- und $kirby-Objekten, es muss also nichts umgeformt werden, nur um diese Grenze zu überqueren. Ohne Template-Engine zu arbeiten ist wirklich kein Weltuntergang.

Wiederverwendbare Template-Fragmente heißen Snippets. Es sind schlichte PHP-Dateien im Ordner snippets, die mit snippet() ins Template geholt werden. Ihre Daten übergebt ihr explizit, statt euch darauf zu verlassen, was gerade im Scope liegt:

php
<?php snippet('teaser', ['item' => $item]) ?>

In snippets/teaser.php arbeitet ihr direkt mit $item — kein Nachschlagen, keine Magie. Wer von TYPO3 und Fluid kommt: Es ist ziemlich genau wie das Rendern eines Partials:

html
<f:render partial="Teaser" arguments="{item: item}" />

Das Ergebnis ist ein in sich geschlossenes Fragment, das nur die Daten kennt, die ihr ihm gebt — es lässt sich also wiederverwenden, ohne still und heimlich von der umgebenden Seite abzuhängen.

Template-Engines von Dritten

Für PHP-basierte Template-Sprachen gibt es ebenfalls Community-Integrationen. Wer von Laravel kommt, kann die Blade-Integration von Lukas Leitsch nutzen. Für alle mit Symfony-Hintergrund gibt es außerdem eine Twig-Integration vom JUST-Team.

Reicht das nicht, könnt ihr über Kirbys Plugin-Schnittstelle eure eigene Template-Engine mitbringen. Wir haben da selbst etwas Spannendes in Arbeit — bleibt dran.

Bringt euer eigenes Frontend mit

Kirby hat keine Meinung dazu, welches Frontend-Framework oder Build-Tooling ihr mitbringt. Wenn ihr Vite nutzen wollt, ist das community-gepflegte Plugin kirby-vite von Arnoson ein guter Startpunkt.

In meinem Fall hatte ich bereits eine erprobte Vite-Integration für TYPO3- und DDEV-Umgebungen. Sie deckt alles ab, was wir täglich brauchen, und gibt mir volle Kontrolle über diesen Teil des Stacks. Sie auf Kirbys Plugin-System zu portieren war überraschend wenig Aufwand.

Vue-Kenntnisse helfen, wenn ihr das Panel erweitern wollt, denn Kirbys Panel ist selbst mit Vue gebaut und stellt Plugins ein Komponentensystem bereit. Es lohnt sich zu prüfen, welche Vue- und Panel-APIs eure konkrete Kirby-Version unterstützt, bevor ihr ein Plugin startet — diese Kompatibilität wiegt hier schwerer als im öffentlichen Frontend.

Komplett headless zu gehen ist ebenfalls möglich. Kirby zwingt euch nicht, HTML zu rendern; das Headless-Cookbook ist ein guter Ausgangspunkt, wenn ihr diesen Weg einschlagt.

Spannender finde ich allerdings, dass ihr euch nicht vollständig auf einen Ansatz festlegen müsst. Kirby kann denselben Inhalt je nach Anfrage in verschiedenen Formaten ausliefern. Eine Seite kann als HTML für den Browser und als JSON für einen API-Konsumenten rendern, ohne das Inhaltsmodell zu duplizieren.

Ihr könnt eine Repräsentation page.json.php neben das reguläre Template page.php legen, und Kirby wählt anhand der angefragten Endung die richtige aus. Gleicher Blueprint, gleiche Felder, andere Repräsentation beim Ausliefern. Ein schöner Mittelweg, wenn ein Teil eines Projekts eine normale Website braucht und ein anderer eine mobile App oder ein separates Frontend füttern soll.

Panel, Blueprints und Backend

Die tägliche Arbeit mit dem Panel bestätigt, was der erste Eindruck versprochen hat. Es bleibt intuitiv, auch wenn man ein echtes Projekt baut statt nur herumzuklicken.

Die Konsistenz der Blueprints trägt viel dazu bei. Wenn ihr einen geschrieben habt, kennt ihr im Grunde die Form aller anderen — egal ob ihr eine ganze Seite, einen einzelnen Tab oder einen Block in einem Layout-Builder beschreibt.

Nehmt einen Tab für seitenweite Firmeneinstellungen in site.yml:

site.yml
company:
  label: Company Info
  fields:
    companyname:
      label: Company Name
      type: text
    logo:
      label: Logo
      type: files
      max: 1

Vergleicht das nun mit einem Zitat-Block in blocks/quote.yml:

blocks/quote.yml
name: Quote
icon: quote-right
fields:
  text:
    label: Quote
    type: textarea
  author:
    label: Author
    type: text

Derselbe Schlüssel fields, dieselben Labels und Typen, dieselben Felddefinitionen tauchen im ganzen System auf. Ein text-Feld bleibt ein text-Feld — ob in einem globalen Tab, auf einer normalen Seite oder verschachtelt in einem Block.

Berechtigungen folgen demselben gut lesbaren Ansatz. Festzulegen, was eine Editor-Rolle darf und was nicht, ist wieder eine YAML-Datei:

yaml
title: Editor
permissions:
  files:
    changeName: false
  pages:
    delete: false

Sobald ein Feld in einem Blueprint existiert, holt ihr es ins Template, indem ihr es als Methode auf dem Page-Objekt aufruft. Zurück kommt ein Field-Objekt mit Helfern wie kirbytext() für KirbyText und html() für escapten Klartext.

Inhalte sind naturgemäß optional — irgendjemand lässt immer ein Feld leer —, also könnt ihr mit isNotEmpty() prüfen, bevor ihr etwas ausgebt:

php
<?php if ($page->text()->isNotEmpty()): ?>
  <?= $page->text()->kirbytext() ?>
<?php endif; ?>

Ihr müsst kein !empty() über das Template streuen und nicht raten, ob ein fehlendes Feld null oder einen leeren String zurückgibt. Das Field-Objekt weiß es bereits und sagt es euch.

Flexibilität — und wann man sie begrenzen sollte

Kirby lässt euch so generisch werden, wie ihr wollt, und genau da habe ich gelernt, vorsichtig zu sein.

Es ist verlockend, eine mega-flexible Block- oder Feldstruktur zu bauen, die theoretisch jedes Layout abdeckt, das eine Kundin sich ausdenken könnte. In der Praxis kann diese Flexibilität gegen euch arbeiten. Redaktionen starren am Ende auf eine Wand optionaler Felder, ohne zu wissen, welche auf der Seite, die sie gerade bearbeiten, überhaupt zählen. Und Entwickler schreiben defensiven Template-Code für Kombinationen, die nie eintreten werden.

Manche Einschränkungen dienen beiden Seiten besser. Entscheidet vorab, wofür ein Abschnitt da ist, statt alle Türen offen zu lassen.

Wo Kirbys Flexibilität wirklich auszahlt, ist das Panel-Layout. Blueprints erlauben es, Spaltenbreiten zu steuern, Felder in Tabs zu gruppieren und Inhalte als Grid, Liste, Tabelle oder Cards darzustellen. Nichts davon verlangt einen neuen Ansatz; es ist einfach mehr Konfiguration rund um die Felder, die ihr ohnehin nutzt.

Zwei zusammengehörende Felder nebeneinanderzulegen ist eine simple width-Option. Praktisch etwa für Start- und Enddatum eines Events, wo es wirklich hilft, beides gleichzeitig zu sehen:

yaml
fields:
  startdate:
    label: Start Date
    type: date
    width: 1/2
  enddate:
    label: End Date
    type: date
    width: 1/2

Ein Blueprint in Tabs aufzuteilen funktioniert ganz ähnlich:

yaml
tabs:
  content:
    label: Content
    fields:
      text:
        type: textarea
  seo:
    label: SEO
    fields:
      metatitle:
        type: text

Ihr könnt außerdem sinnvolle Vorschauen konfigurieren, damit Redaktionen nicht jeden Eintrag öffnen müssen, nur um das richtige Bild oder die richtige Überschrift zu finden. Ein Structure-Feld kann zum Beispiel Cards mit Vorschaubild und Beschriftung nutzen:

yaml
fields:
  team:
    type: structure
    layout: cards
    image:
      query: item.photo.toFile
    info: "{{ item.role }}"
    fields:
      name:
        type: text
      role:
        type: text
      photo:
        type: files
        max: 1

Diese Layout-Arbeit passiert allerdings nicht im luftleeren Raum. Sich mit den Redaktionen zusammenzusetzen und ein paar Varianten durchzugehen, bevor man sich festlegt, ist die Zeit wert. Was für Entwickler effizient aussieht, fühlt sich für die Person, die es täglich ausfüllt, nicht immer natürlich an. Ein Fünf-Minuten-Gespräch am Anfang spart später viel Nacharbeit.

Kirby erweitern

Kirbys Plugin-API ist unkompliziert, sobald man drin ist. Es gibt klare Erweiterungspunkte im ganzen System statt eines einzigen Allzweck-Hooks. Ihr könnt Blueprints registrieren, eigene Methoden ergänzen, auf Events reagieren oder Templates und Snippets bereitstellen — alles als Teil eines Plugins gebündelt, sodass das Ergebnis nicht nachträglich angeflanscht wirkt.

Das Panel zu erweitern ist anfangs eine andere Geschichte. Herauszufinden, was es genau bereitstellt, braucht etwas Graben, bevor der Groschen fällt. Danach fühlt sich der Bau einer Panel-Komponente an wie normales Vue, ergänzt um Kirbys Komponenten und Helfer.

Kirbys Panel Lab und die UI-Dokumentation sind hier besonders nützlich. Panel-Erweiterungen hängen eng an der Kirby-Version, auf die sie zielen — ich würde also immer die passende Komponenten-Dokumentation prüfen, bevor ernsthafte Plugin-Arbeit beginnt.

Dokumentation, Ökosystem und Community

Kirbys Dokumentation verdient Lob. Sie war beim Einstieg eine große Hilfe, mit Property-Listen und lauffähigen Beispielen für nahezu jeden Teil des Systems. Ich habe einen guten Teil meiner ersten Tage in der Referenz verbracht und dabei sichergestellt, dass ich nichts neu erfinde, was es längst gibt.

Natürlich hindert einen die vollständige Dokumentation nicht daran, gelegentlich zum falschen Werkzeug zu greifen. Genau da verdient sich das Cookbook seinen Platz. Es steckt voller Praxisbeispiele für gängige und einige weniger gängige Szenarien — herauszufinden, welchen Weg Kirby bevorzugt, dauert damit selten lange.

Wenn Dokumentation und Cookbook etwas nicht abdecken, tut es oft die Community. Das Kirby-Forum ist aktiv genug, dass viele meiner Probleme dort bereits eine Antwort hatten — manchmal direkt vom Core-Team.

Auch das Plugin-Ökosystem hält stand. Es gibt eine gesunde Mischung aus kostenlosen und kostenpflichtigen Optionen, darunter robuste SEO- und Formular-Plugins für anspruchsvollere Projekte. Das Plugin-Verzeichnis ist gut organisiert, das Stöbern wird also nicht zur Qual.

Das kratzt immer noch nur an der Oberfläche. Allein auf der Dokumentations- und Plugin-Seite gibt es viel mehr zu entdecken, und auf einiges davon kommen wir in künftigen Artikeln zurück.

Fazit

Nach ein paar Jahren mit Kirby ist es eines der CMS geworden, zu denen ich ganz selbstverständlich greife. Es hält sich raus, wenn ein Projekt einfach ist, gibt euch aber genug Flexibilität, wenn Inhaltsmodell und Frontend anspruchsvoller werden.

Am meisten schätze ich die Konsistenz. Blueprints, Felder, Templates und Plugins wirken wie Teile desselben Systems und nicht wie über die Zeit gesammelte Features. Das macht Kirby angenehm zu lernen — und, noch wichtiger, angenehm im Weiterarbeiten, wenn das erste Projekt fertig ist.

Wenn ihr Kirby für eure nächste Website in Betracht zieht, helfen wir euch nicht nur beim Frontend, sondern auch bei der Inhaltsarchitektur und der redaktionellen Erfahrung dahinter. Meldet euch bei Digital Zombies, und wir schauen gemeinsam, ob Kirby zu dem passt, was ihr baut.