07.05.2024 10:08
Jekyll - eine performante Alternative
Wer heute eine Webseite baut, kann zwischen vielen unterschiedlichen Vorgehen und Frameworks (wie z.B. WordPress) wählen. Die meisten davon sind mit JavaScript überladen, oft über ein gesundes Maß hinaus. Sehr oft verursachen diese Frameworks auch eine relativ hohe CPU-Last auf dem Server, weil sie darauf ausgelegt sind, alles zu können – einen Editor für Posts mitzuliefern, mehrbenutzerfähig zu sein, erweiterbar durch Plugins, etc. Natürlich arbeiten solche Frameworks auch immer mit einer Datenbank. An Optimierung der Leistung denkt man heutzutage nicht mehr.
Grundsätzlich sind die Features solcher Frameworks sehr gut und nützlich, aber nicht unbedingt immer in vollem Umfang nötig. Vor allem stören sie, wenn man versucht, auf sehr kleiner Hardware (ca. auf dem Niveau eines IoT‑Devices) eine Webseite zu betreiben. Das Ergebnis sind stark ruckelnde Seiten, welche die kleine Hardware nur unnötig ins Schwitzen bringen.
Eine Alternative bieten Frameworks an, welche statische Webseiten (ohne Datenbank) aus Markdown-Dateien generieren – z.B. Jekyll.
Gerade persönliche Blogs lassen sich auf diese Art und Weise vortrefflich organisieren! Wenn man selbst der einzige schreibende Nutzer ist und auf einen Texteditor im Webbrowser verzichten kann (ganz ehrlich, es gibt bessere Programme, um mit Text zu arbeiten) – dann braucht man keine schwere Datenbank, keinen meilenlangen PHP‑Code! Kleine, stromsparende Server werden mit den so erstellten statischen Webseiten auch locker fertig!
Aber, was tun, wenn man einen mehrsprachigen Blog, oder eine mehrsprachige Webseite betreiben will? Zumindest bei Jekyll gibt es auf der Webseite keine Anleitung dazu.
Mehrere Sprachen - mehrere Probleme
Sucht man im Internet, findet man durchaus Anleitungen, die genau dieses Problem angehen. Man sollte sich aber davor hüten, einfach die erstbeste Anleitung zu nehmen und ihr zu folgen. Es mag sein, dass anfangs alles gut geht, aber es kann leicht passieren, dass der Autor dieser Anleitung nicht die Kompatibilität seines Vorgehens mit allen Plugins (ein sehr wichtiges Element bei Jekyll!) gecheckt hat. Es besteht die Gefahr, dass man tagelang an einer Webseite arbeitet, scheinbar Fortschritte macht, um dann vor eine Wand zu laufen, die nur noch durch hässliche Hacks zu umgehen ist. Viel Erfolg beim nächsten Update, wenn alles wieder zusammenbricht…
Grundsätzliche Tipps
Bei jedem Softwareprojekt gilt: Hüte dich davor, das Rad neu erfinden zu wollen. Genauso auch bei Webseiten mit Jekyll. Hier meine grundsätzlichen Tipps im Detail:
- Immer auf die offiziellen Ressourcen als Erstes zurückgreifen, nicht einfach drauflos suchen
- Auf GitHub gibt es viele Themes für Jekyll. Schau dir vor allem die an, welche die meisten Sterne haben. Nimm sie als Muster zur Erstellung eines eigenen Themes, oder verwende sie direkt weiter
- Versuche nicht, Funktionen von Jekyll zweckentfremdet zu benutzen. Collections sind z.B. nicht dazu da, mehrsprachigen Inhalt anzuordnen!
Was sind denn die offiziellen Ressourcen? Anlaufstelle Nr. 1 ist die Dokumentationsseite des Projekts. Dort findest du schon eine sehr gute Anleitung und Erklärung für erste Schritte. Sie ist auf Englisch, aber das sollte dich im Zeitalter von KI und in die Webbrowser integrierten Übersetzungstools nicht aufhalten ;-) Will man jedoch weitergehen und hat man etwas vor, was in dieser Anleitung nicht beschrieben ist, so werden weitere Nachforschungen nötig. Vor allem empfehle ich die Liste der Jekyll-Plugins.
Nach welchen Kriterien sucht man die Plugins oder Themes auf GitHub aus? Es ist wichtig, darauf zu achten, ob ein Projekt gut geführt wird. Wichtige Fragen sind dabei: Wie viele Sterne hat das Projekt? Wie aktiv wird es entwickelt? Wie viele Sterne hat es?
Im weiteren Verlauf dieser Anleitung setze ich voraus, dass die offiziellen Ressourcen mitbenutzt werden. Das Jekyll-Team hat eine Anleitung schon geschrieben und es wäre falsch, diese einfach zu kopieren.
Mehrsprachiger Blog, Anleitung
Wie baut man also genau einen mehrsprachigen Blog mit Jekyll, ohne gleich zu sehr auszuufern? Hier eine Liste der Plugins, welche m.M.n. die Mindestanforderung für diese Aufgabe darstellen:
- “jekyll-paginate-v2”
- “jekyll-polyglot”
- “jekyll-sitemap”
- “jekyll-seo-tag”
Trage diese Plugins im Gemfile ein, ungefähr so:
gem "jekyll-feed", "~> 0.12"
gem "jekyll-paginate-v2"
gem "jekyll-polyglot"
gem "jekyll-sitemap"
gem "jekyll-seo-tag"
Jekyll-feed ist dabei standardmäßig immer schon drin, wenn man eine neue Jekyll-Webseite anlegt.
Es gibt mehrere Plugins, die man auf GitHub unter “jekyll-polyglot” findet. Ich benutze untra/polyglot. Es hat viele Sterne, sieht aktiv aus und hat bei mir gut funktioniert.
Wenn man auf GitHub auf die Seite von diesem Plugin geht, kann man unter “Used By” sehen, wer alles in seinem Theme dieses Plugin verwendet. Kleiner Tipp: Nimm dir eines dieser Themes, oder benutze es als Template für dein eigenes ;-)
Datenstruktur
Die richtige Datenstruktur ist sehr wichtig, sonst kann einer der folgenden Fehler passieren: die Webseite sieht nach einem bundle exec jekyll serve funktionsfähig aus, sobald man aber in Produktion gehen will und den statischen Inhalt auf einen “normalen” Server (apache httpd, nginx, etc.) lädt, sind einige der Links kaputt und führen zu einem 404-Error Posts werden nicht als solche erkannt oder tauchen in der falschen Kategorie auf Unser Blog soll mehrsprachig werden. Außerdem brauchen wir mehrere Kategorien, wie z.B. einen Blog und ein Portfolio, sowie möglicherweise einen separaten News-Feed für Updates, welche die Seite selbst betreffen. Jede Kategorie braucht ein eigenes Unterverzeichnis. Die gesamte Verzeichnisstruktur kann so aussehen:
my-website
blog
photos
portfolio
Gib den Kategorien sprechende Namen, sie werden später in jedem Post im “Front Matter” gesetzt und zur Pagination genutzt! Die Posts sind unter dem jeweiligen Unterverzeichnis anzulegen. Posts gehören bei Jekyll in einen Ordner, der _posts heißt. Z.B. so:
my-website
blog
_posts
photos
_posts
portfolio
_posts
Da die Seite mehrsprachig werden soll, gehören da noch Unterverzeichnisse für die Sprachen rein:
my-website
blog
_posts
de
en
uk
photos
_posts
de
en
uk
portfolio
_posts
de
en
uk
Die Seiten werden aus Markdown-Dateien generiert (mit der Endung .md). Den Pfad, unter dem die generierte .html-Datei zugänglich wird, steuert man durch das Attribut permalink im “Front-Matter” der Seite sowie durch die permalink: ... Einstellung in der _config.yml.
Jede Sprache braucht eine andere .md-Datei, da im “Front-Matter” keine Variablen genutzt werden können, nur Klartext. Will man eine .md-Datei für mehrere Sprachen nutzen, wird das “title”-Attribut der generierten Seite immer gleich bleiben, sowie “description” usw.
- Ausschnitt aus der
_config.yml(Konfiguration von Polyglot, beliebige Sprachen hier hinzufügen):

Inhalte hinzufügen
Jetzt, wo das Grundgerüst steht, wird es Zeit, die ersten Inhalte anzulegen. Fangen wir an mit einer index.md-Datei. Sie braucht im Namen keine Bezeichnung für die Sprache zu tragen und sollte der Standardsprache der Webseite entsprechen (in diesem Fall Deutsch). Erstelle die entsprechende Datei einfach im Wurzelverzeichnis. Hier ist das “Front Matter”:
title: "Mehrsprachige Webseite!"
lang: de
permalink: /
page_id: index
link_title: "Start"
description: "Ein Blog in mehreren Sprachen"
Und dasselbe für die nächste Sprache, z.B. Englisch. Die Datei muss nun anders heißen, sonst wird ja die alte überschrieben. Ich nenne die Datei index.en.md:
title: "Multilang website!"
lang: en
permalink: /
page_id: index
link_title: "Home"
description: "A blog with multiple languages"
Mache genauso weiter, bis für jede benötigte Sprache eine passende Datei angelegt ist. Die geplante Webseite sollte etwas komplexer sein als ein einfacher Blog. Sie braucht Kategorien, um Posts im Blog von anderen Sachen abzugrenzen! Das ist grundsätzlich optional, aber wenn du das ebenfalls so nachbauen willst, brauchst du noch eine entsprechende Seite für jede Kategorie. Hier ein Beispiel für die Kategorie Blog, die Datei heißt blog.md und ist ebenfalls im Wurzelverzeichnis abzulegen:
title: Blog
page_id: blog
permalink: /blog
categories: blog
lang: de
description: "Blog"
pagination:
enabled: true
indexpage: blog
category: blog
Hier wird es schon etwas komplizierter. Das Attribut lang zeigt weiterhin die Sprache des Inhalts an. Es wird von Polyglot benutzt, um Links korrekt zu generieren (ca. nach dem Muster [lang]/[categories]/[permalink].html). Der Bereich pagination ist notwendig, damit bei wachsender Anzahl an Posts in dieser Kategorie irgendwann automatisch die Pagination einsetzt.
Vergiss nicht, hier eine gesonderte indexpage zu definieren, sonst überschreiben sich die Kategorien gegenseitig, sobald Pagination greift! Setze das Attribut category auf jeden Fall auf die passende Kategorie, damit die Posts aus anderen Kategorien hier nicht auftauchen. Leider versteht pagination nicht das Attribut lang. Daher tauchen zunächst mal Posts in allen Sprachen hier auf.
Jetzt wird es Zeit, sich um das Problem der mehrsprachigen Posts bei Pagination zu kümmern. Dafür erweiterst du das “Front Matter” von blog.md um das tag-Attribut, damit nur die Posts auf Deutsch angezeigt werden:
title: Blog
page_id: blog
permalink: /blog
categories: blog
lang: de
description: "Blog"
pagination:
enabled: true
tag: de
indexpage: blog
category: blog
Ich weiß, ich habe weiter oben geschrieben, dass man Funktionen nicht zweckentfremden sollte. Die “Tags” eines Posts sind im Normalfall Stichpunkte, die etwas über das Thema verraten. Möglicherweise wird das pagination Plugin irgendwann in Zukunft auch ein lang-Attribut verstehen. Zum Zeitpunkt der Erstellung des Artikels fand ich aber keinen besseren Weg, als den tag im Post auf die entsprechende Sprache zu setzen und hier nach eben diesem tag zu filtern.
Eigentlich sind die “Tags” in einem Post dazu da, um bei der Suche nach bestimmten Informationen zu helfen. Die Sprache als “Tag” in einen Post zu setzen ist m.M.n. unbedenklich, weil man sowieso viele davon haben kann und das Filtern der Suchergebnisse nach Sprachen ebenfalls ein sinnvoller Use-Case ist. Natürlich hat man damit im Post die Sprachinformation doppelt drin, was nicht ganz sauber ist. Aber die Hauptsache ist: mit diesem kleinen Trick wurde das Ziel erreicht! Jetzt werden bei Pagination nur noch Posts angezeigt, welche:
- in der passenden Sprache sind (wo
tag: [sprache]gesetzt ist) - welche zur passenden Kategorie gehören (wo
categories: [Name der Kategorie]gesetzt ist)
Vermutlich hast du schon ein Theme ausgesucht, oder du erstellst ein eigenes. Unabhängig davon musst du in einer der Layout-Dateien die Anzeige der Posts aktivieren. Angenommen, du hast eine default.html, wo das Layout für alle Seiten festgelegt wird. Dann muss dort an der Stelle, wo die Posts aufgelistet werden sollen, zumindest folgendes hin:

Wie man das paginate-v2-Plugin konfiguriert, ist am besten hier beschrieben. Jetzt musst du nur noch die .md-Dateien für alle anderen Seiten anlegen, je eine pro Sprache, genau wie oben beschrieben, und die mehrsprachige Webseite/Blog auf Jekyll-Basis mit minimalsten Hardware-Anforderungen ist fertig. Viel Spaß damit!
