Mein Blog ist endlich statisch dank Hugo

Was lange währt, wird endlich gut – dieser Spruch passt nun wirklich zu meinem Projekt, mein Blog auf einen Static Site Generator umzustellen. Ich habe nämlich vor sage & schreibe 5 Jahren damit angefangen, wie ihr im Beitrag Statisch, praktisch, gut: Pelican nachlesen könnt.

Warum doch nicht Pelican, sondern Hugo?

Damals stand noch Pelican im Titel, womit ich dann schließlich meine Agentenwebsite gebaut habe. Deshalb erkläre ich zunächst mal, warum es letztlich Hugo geworden ist.

Dafür muss ich mich über die Programmiersprache Python auslassen, in der Pelican geschrieben ist. Die gefällt mir als Programmiersprache sehr, allerdings stößt mich das Ökosystem drumherum zunehmend ab. Mit meinem Gentoo Linux-System gerate ich in schöner Regelmäßigkeit in die Dependency Hell, wenn mal wieder eine neue Python-Version zum Standard wird. Auch dass neue Python-Versionen nicht abwärtskompatibel sind (insbesondere der Sprung von Python 2.7 auf Python 3), macht das Leben nicht gerade einfacher. Das hat sich übrigens sogar im Zuge der Blog-Umstellung zu Hugo negativ bemerkbar gemacht, aber dazu später mehr.

Für ein zeitweises Webprojekt habe ich dann mal probehalber Hugo genommen und war recht zufrieden damit; es handelte sich allerdings auch um eine ganz einfache Landingpage. Was mich sehr für Hugo einnimmt, ist, dass es wie alle in Go geschriebenen Programme ein einzelnes Binary ohne weitere Abhängigkeiten ist (s.o.).

Diesen Vorteil von Go gegenüber Python habe ich bei meinem Standard-Backupprogramm seit über 2 Jahren, restic, ebenfalls erlebt. Und dieses Programm bestätigte auch meinen Eindruck, dass in Go geschriebene Programme ziemlich schnell sind.

Weshalb hat es dann doch 5 Jahre gedauert?

Trotz des guten Eindrucks von Hugo bei dem Landingpage-Projekt blieb ich für mein Blog immer wieder daran hängen, dass ich kein passendes Theme fand, das zumindest meine wichtigsten Anforderungen erfüllt. Das Landingpage-Theme inspirierte mich Anfang letzten Jahres zu meinem ersten Commit bei GitHub. Dabei fing ich auch an, die Mechanik von Hugo-Themes in groben Zügen zu verstehen. Für mein Blog wurde ich allerdings lange Zeit nicht fündig, obwohl ich in größeren Abständen immer wieder mal in den Themes gestöbert & auch mehrere davon ausprobiert habe.

Bei der Gelegenheit stellte ich übrigens fest, dass Hugo zwar sehr schnell sein kann beim Bauen meines Blogs, das hängt aber sehr vom verwendeten Theme ab. Bei manchen ging es in Sekundenbruchteilen, bei anderen dauerte es teilweise bis über eine Minute. Das jetzt verwendete Theme braucht derzeit etwa 15 Sekunden für alles.

Anfang des Jahres hatte ich sogar einen Anlauf genommen, einen auf Hugo spezialisierten Webdesigner zu engagieren, um ein Theme nach meinen Vorgaben zu basteln. Das Projekt sollte schließlich endlich Gestalt annehmen, und das fehlende Theme war der einzige Hinderungsgrund. Allerdings fand ich niemand für diese Aufgabe.

In meiner Verzweiflung habe ich dann noch mal die Themes durchgeblättert und dabei Minimo entdeckt. Das muss ich die ganzen vorherigen Male übersehen haben, es existiert nämlich schon seit 2018. Zu seinen vielen Funktionen komme ich später.

Wie kommen die Inhalte aus Habari in Hugo?

Diese Frage hatte ich mir schon für Pelican gestellt und im Zuge dessen das Export-Plugin für Habari entdeckt & installiert. Damit bekomme ich zunächst eine XML-Datei im (annähernd, auch dazu später mehr) Wordpress-kompatiblen Format, die Pelican importieren kann. Hugo kann das ohne Hilfmittel nicht, dafür benutze ich ExitWP for Hugo.

Beim ersten Anlauf mit ExitWP for Hugo stellte ich fest, dass Habari alle Einträge mit einem falschen Datumsformat exportiert. Außerdem schreibt es statt des korrekten link-Tags guid in die Datei. Und die Tags wiederum sollten korrekt als post_tag statt nur als tag eingetragen werden. Deshalb habe ich die exportierte Datei zunächst durch diesen sed-Filter gejagt:

sed -e 's/\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\)T\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)[+-][0-9][0-9][0-9][0-9]/\1 \2/g' | sed -e 's/guid/link/g'
sed -e 's/domain="tag"/domain="post_tag"/g'

Auch dann tat ExitWP for Hugo noch nicht ganz das, was es sollte, deshalb gibt es auch dafür Github-Commits von mir.

Und dadurch, dass sich alles so lange hingezogen hat, war schließlich, als ich das passende Theme gefunden hatte, Python 2.7 auf meinem Gentoo-System aussortiert worden und ExitWP for Hugo wollte erst mal gar nicht laufen. An dieser Stelle kann ich wieder die Open Source-Gemeinde loben, es gibt nämlich einen Pull Request um ExitWP for Hugo an Python 3 anzupassen, dank dem es schließlich funktioniert hat.

Was jetzt auf diesem Wege im neuen statischen Hugo-Blog angekommen ist, sind

  • die Blogbeiträge
  • die statischen Seiten
  • die Tags

Die Kommentare schlummern zur Zeit noch im Habari-Export, denn ich muss zuvor das Kommentarsystem Isso einrichten. Das wiederum werde ich erst nach einem bevorstehenden Providerwechsel tun (wohin, wird noch nicht verraten), diesen werde ich allerdings in den nächsten Tagen gleich angehen.

Was das Hugo-Theme Minimo alles kann

Als ich Minimo das erste Mal in Aktion gesehen habe, war ich echt geflash – es hat nämlich eine Tag Cloud schon eingebaut. Du kannst sie am linken Rand der Seite bewundern. Die hatte ich bisher eher als “nice to have” eingestuft, Hauptsache überhaupt eine Liste von Tags, so wie sie im alten Habari-Blog war. Ich hatte mir schon eine Tag Cloud aus einem anderen Blog vorgemerkt; die brauche ich dank Minimo gar nicht.

Die integrierte Suchfunktion hatte ich erst nicht zum Laufen gekriegt. Mit folgender Datei search.md klappte es dann aber auf Anhieb:

---
type: page
title: Suchergebnisse
layout: search
outputs:
  - html
  - json
---

Es gilt mal wieder das Motto “Kaum macht man’s richtig, funktioniert’s.”

Ähnlich war es bis heute mit dem chronologischen Blog-Archiv. Dafür gibt es allerdings gar keine Dokumentation, so dass ich es mir selber zusammenreimen musste, analog zur Suchseite:

---
type: page
title: Archiv
layout: archive
outputs:
  - html
---

Beim ursprünglichen Adblock Plus-Entwickler Wladimir Palant hatte ich schon einen Blogbeitrag über lokale Suche für Hugo entdeckt, The easier way to use lunr search with Hugo. Auch diesen kann ich dank Minimo links liegen lassen, denn die Suche funktioniert out of the box. Was ich seinerzeit bei Wladimir Palant schon bemerkenswert fand: das Ganze findet per JavaScript im Browser clientseitig statt. Er schreibt einleitend:

I ruled out a third-party service (because privacy) and a server-supported one (because security). Instead, I went with lunr.js which works entirely on the client side.

Der RSS- bzw. Atom-Feed findet sich jetzt unter https://www.iromeister.de/index.xml, allerdings habe ich für die alte URL /atom/1 sowie neu auch für den Standard /feed/ jeweils einen Redirect eingerichtet.

Schneller und sicherer dank Static Site Generator

Wie erwartet lädt die Seite jetzt schneller als vorher mit Habari. Und jetzt kann ich auch zugeben, dass bis heute Vormittag mein Blog noch mit PHP 5.6 gelaufen ist, weil die letzte veröffentlichte Habari-Version 0.9.2 aus dem Jahr 2014 (!!) nicht mit PHP 7 funktioniert. Da hatte ich mich echt in eine technologische Sackgasse begeben & bin froh, diese endlich verlassen zu haben.

Ein weiterer netter Nebeneffekt ist, dass mein Blog nun keine Cookies mehr setzt. Das wird sich allerdings vermutlich wieder ändern, wenn Isso eingerichtet ist.

Auch mit Isso wird die Angriffsfläche auf dem Webserver jedenfalls deutlich kleiner als mit Habari, außerdem wird Isso aktiv gepflegt und daher auch mit Sicherheitsupdates versorgt.

Statisch bloggen mit Hugo – zurück zu den Wurzeln

Mein erstes richtiges Blog habe ich seinerzeit anlässlich meiner Gemeinschaftsreise bei twoday.net eingerichtet. Davor hatte ich schon mal eine Zeitlang ein kurzes knappes Internet-Tagebuch, das ich damals noch von Hand in HTML schrieb.

Im Jahr 2009 hatte ich kurzzeitig mit Drupal gebloggt, das sich aber bald als überdimensioniert für diesen Zweck erwies. Heute kann ich gar nicht mehr genau nachvollziehen, wann ich zu Habari gewechselt bin. Es hat jedenfalls lange gehalten, im Oktober 2015 hatte ich das bis heute Vormittag aktive Theme dafür eingerichtet.

Während ich Habari benutzte, habe ich meine Beiträge immer in HTML geschrieben. Jetzt werde ich mich an Markdown gewöhnen. Dafür liegt gerade das Markdown Cheat Sheet von Mac & i neben mir. Was darin fehlt, ist das Durchstreichen von Text, wofür um den Text herum je zwei Tilden benutzt werden.

Dabei schreibe ich im Editor meiner Wahl anstatt im Browser. Hugo hat übrigens eine sehr hilfreiche Funktion, hugo server – damit erzeugt Hugo erst die gesamte Site und liefert sie dann über einen integrierten Webserver auf Port 1313 aus. Solange dieser Server läuft, überwacht Hugo die gesamte Verzeichnisstruktur auf Änderungen und generiert nur die Teile der Seite neu, deren Grundlage verändert wurde.

Das ist ein ähnlicher Arbeitsablauf wie bisher, wo ich Entwürfe in Habari online gespeichert hatte. Der Vorteil ist aber, dass in dem Moment alles auf meiner eigenen Festplatte (bzw. SSD) gespeichert wird, wenn ich auf “Speichern” klicke, und nicht auf dem Weg durchs Internet noch Daten verloren gehen können.

Wenn dann ein Beitrag fertig ist, kann ich ihn einmalig hochladen und der Webserver kann ihn in beliebiger Ausfertigung an euch Leserinnen ausliefern.

Nachtrag: Nach einiger Bastelei kommt jetzt auch valides HTML hinten raus. Und nach gehörigem Ringen mit CSS-Selektoren sieht es damit weiterhin vernünftig aus.

Nachtrag vom 15.12.: Gerade habe ich festgestellt, dass ich in guter Gesellschaft bin – Kris Köhntopp hat sein Blog auch kürzlich auf Hugo umgestellt. Den Kris hatte ich schon im Jahr 2009 mit einem eigenen Beitrag hier verewigt. Und ganz aktuell hat er einen epischen Rant über Java anlässlich der log4j-Lücke geschrieben: Kommentar zu Log4j: Es funktioniert wie spezifiziert.

Nachtrag vom 17.01.2022: Beim letztjährigen rc3 des Chaos Computer Club hat jemand die grundsätzlichen Vorteile eines statischen Systems vorgestellt.

Nachtrag vom 08.02.2023: Eher zufällig habe ich heute die Seite mit den Privacy Settings von Hugo entdeckt. Die sollte in der Dokumentation prominenter sein.