Statische Websites mit Lektor

von Robin Schubert am Montag, 9. April 2018

Lektor ist ein Content Management System (CMS) das schnell einsetzbar ist, und erlaubt in einem praktischen File system einfach statische Webseiten zu bauen. Das CMS macht das Pflegen und Hinzufuegen von Inhalten auch ohne Programmierkenntnisse leicht.

Die hervorragende Dokumentation beinhaltet unter anderem Anleitungen fuer verschiedene Design-Beispiele die extrem hilfreich sind und auf die auch dieser Blog aufgebaut wurde.

Diese gesamte Seite wird mit Lektor betrieben und gepflegt, und wer gerne ein deutsches Tutorial haette wird in diesem Post vielleicht fuendig.

Die Funktionsweise

Damit Lektor eine Webseite rendern kann benoetigt es mindestens ein Model, ein Template und ein Lektor-File (.lr) mit den entsprechenden Inhalten.

Models

Models sind in Lektor .ini Dateien, in denen Felder und Eigenschaften deklariert werden welche die zukuenftige Seite haben soll. Das koennen bestimmte Variablen sein wie z.B.

Die Felder werden jeweils mit dem entsprechenden Datentypen deklariert, wie string, integer, date, markdown etc. Im Admin Bereich von Lektor koennen dann Instanzen des Models erstellt und mit Inhalt gefuellt werden. Natuerlich kann man auch ganz auf den Admin Bereich verzichten und direkt in plain text schreiben.

Das Model das fuer diese Seite genutzt wird sieht in etwa so aus:

[model]
name = Blog Post
label = {{ this.title }}

[fields.title]
label = Title
type = string

[fields.pub_date]
label = Publication date
type = date

[fields.author]
label = Author
type = string

[fields.body]
label = Body
type = markdown

Fuer jedes Feld muss es mindestens die Attribute label und type geben, damit im Lektor Admin Bereich eine entsprechende Instanz erstellt werden kann.

Templates

Als Template Engine verwendet Lektor Jinja2, eine sehr flexible und effektive Mischung aus HTML und Python. Jinja2 erlaubt das einbinden von einfacheren Schleifen oder If-Else Bedingungen und auch Zugriff auf die im Model deklarierten Variablen und Eigenschaften, direkt zwischen dem HTML code.

Per Konvention soll jedes Template denselben Namen haben wie das dazugehoerige Model. Lektor erlaubt allerdings auch das manuelle Festlegen von unterschiedlichen Templates und Models, was allerdings nur begrenzt sinnvoll ist.

Dieses uebersichtliche Template wird aktuell fuer diese Seite genutzt:

{% extends "layout.html" %}
{% block title %}{{ this.title }} | News {% endblock %}
{% block body %}
<h1>{{ this.title }}</h1>
<p class="meta" >
    von {{ this.author }}
    am {{ this.pub_date|dateformat('full') }}
    <div class="body">
        {{ this.body }}
    </div>
</p>
{% endblock %}

Jinja2 ermoeglicht Vererbung; in der ersten Zeile wird zunaechst auf das zu erweiternde Master Template referenziert. Das Master Template definiert einige Blocks deren Inhalte hier festgelegt werden. Das erspart unnoetige Wiederholung von Code. Das Master Template beinhaltet ausserdem noch weiteren HTML code wie z.B. den gesamten Header mit allen CSS Referenzen und Meta-Informationen und das rohe Skelett.

Auf Variablen und Felder kann zwischen zwei geschweiften Klammern {{ ... }} zugreifen, Schleifen und weitere Jinja2 Kommandos landen zwischen geschweiften Klammern und Prozent Zeichen {% if condition %} ... {% endif %}.

Haeufig genutzte Jinja2-Snippets lassen sich auch als Makros auslagern und in verschiedene Templates importieren.

Contents.lr

Wie der Name erahnen laesst befinden sich die eigentlchen Inhalte der Webpages in den Dateien mit dem Namen Contents.lr. Die einzelnen Webseiten werden in je einem Ordner pro Seite verwaltet, jeder Ordner enthaelt dabei eine Contents.lr Datei und wahlweise verschiedene Anhaenge und Bilder die in der entsprechenden Seite gezeigt bzw. verfuegbar gemacht werden sollen.

Diese Dateiverwaltung kann man leicht haendisch uebernehmen, wird aber fuer weniger versierte Nutzer auch von dem dem Lektor Admin uebernommen.

Die Felder des zu Grunde liegenden Models werden dabei ueber key: value Paare zugewiesen wie in diesem Beispiel:

_model: blog-post
---
title: Lektor
---
author: Robin Schubert
---
pub_date: 2018-04-09
---
body:

Hier steht der Inhalt als Markdown vormatiert, wie im Model-Type angegeben.
---

Dateistruktur

Um ein neues Projekt zu initialisieren, erstellt Lektor die benoetigte auf Wunsch voll automatisch ueber die Kommandozeile: lektor quickstart fragt einige Parameter wie z.B. den Namen und Pfad des Projektes ab und erstellt folgende Dateien:

├── assets
│   └── static
│       └── style.css
├── content
│   ├── about
│   │   └── contents.lr
│   ├── contents.lr
│   └── projects
│       └── contents.lr
├── models
│   └── page.ini
├── templates
│   ├── layout.html
│   ├── macros
│   │   └── pagination.html
│   └── page.html
└── MyProject.lektorproject

Ansehen, Bauen und Verwalten der Seiten

Ueber den Befehl lektor server laesst sich das Projekt leicht unter localhost:5000 ansehen. Lektor baut die Seite on the fly in einem temporaeren Verzeichnis und aktualisiert solange der Server laeuft auch nach jeder Aenderung automatisch.

In diesem Modus laesst sich nun auch der Admin Bereich aktivieren um ueber das Web Interface neue Seiten, Blog Posts etc. zu erstellen, und wahlweise die Aenderungen auch gleich auf den Deploy Server zu pushen.

Sollen einfach nur statische HTML Seiten erstellt werden, reicht ein einfaches lektor build, wahlweise mit option --output-path.

Bis hierher

Die Moeglichkeiten sind selbstverstaendlich weitaus vielfaeltiger, und dieser Artikel kratzt gerade eben an der Oberflaeche. Dieser Post zielt allerdings nicht darauf ab, die bereits vorhandene Doku voll ins Deutsche zu uebersetzen, sondern soll vielleicht ein bisschen neugierig machen. Lektor bietet als CMS mehr Komfort als es vielleicht ein Flask Projekt geben koennte, kommt aber gleichzeitig mit deutlich weniger Overhead daher als ein Framework wie Django, und duerfte fuer viele eine attraktive Alternative sein, sowohl fuer kleinere Anwendungen wie den eigenen Blog als auch fuer grosse und professionelle Projekte.