Ich habe diesen Blog von Wordpress zu Hugo migriert. In diesem Artikel will ich über die Beweggründe, die Vor- und Nachteile von Hugo (und statischen Websites allgemein) und Details zum Ablauf der Migration schreiben.

Hintergrund

Als ich mein Blog anfang 2017 aufsetzen wollte, stellte sich natürlich die Frage, welches Content Management System (kurz auch CMS) ich benutzen sollte. Mein Hauptkriterium an das CMS waren vor allem eine hohe Flexibilität, was sowohl die Erstellung der Inhalte als auch die individuelle optische Gestaltung der Seite betrifft.

Bei dynamisch mit PHP generierten Webseiten spielte nicht zuletzt auch die Sicherheit eine Rolle. Schließlich will man nicht eines Tages feststellen müssen, dass die eigene Webseite von Fremden übernommen worden ist und nun Werbung oder Malware unter der eigenen Domain verteilt wird oder Spam-Mails versendet werden. Das heißt also, dass das CMS auch eine entsprechende Softwarequalität haben und aktiv gepflegt werden sollte.

Wie immer sollte das Ganze natürlich auch freie Software sein und nichts kosten. 😄

Am Ende landete ich also beim Marktführer Wordpress. Geboten wurde mir alles Gewünschte:

  • Eine hübsche und bequeme Web-UI zum Erstellen von Posts und zum Verwalten der gesamten Seite
  • Die Möglichkeit eigene Themes zu erstellen und zu nutzen
  • Viele Funktionen, vor allem durch die riesige Menge an Plugins
  • Aktive Entwicklung und Pflege (Updates)
  • Große Community, die Lösungen zu Fragen oder Problemen geben kann
  • Gute Dokumentation. Sehr hilfreich bei der Erstellung eigener Themes
  • Open-Source und kostenfrei

Wordpress läuft auf einem klassischen Web-Stack mit PHP, MySQL und vorzugsweise Apache Webserver und kann damit quasi jedem beliebigen Webhoster betrieben werden.

Die Erstellung des Themes für meinen Blog war dank der wirklich guten Dokumentation, sowie der vielen Anleitungen und anderen Informationen im Internet reine Fleißarbeit. Es machte auch wirklich Spaß nach und nach die einzelnen Wordpress-Features im eigenen Theme nutzbar zu machen und auch optisch der eigenen Kreativität freien Lauf zu lassen 😌. Man könnte meinen, gar mehr Spaß als das eigentliche Schreiben von Blogartikeln.

Was an Wordpress nervte

Doch einige Punkte und Entwicklungen haben mich an Wordpress gestört, sodass ich immer wieder über Alternativen nachdenken musste.

Spam

Ein Wordpress-Blog im Internet anscheinend ein sehr beliebtes Angriffsziel für Bots. Die Konsequenz sind vor allem Spam-Kommentare und ständige Loginversuche.

Letztere sind für mich dank passender Vorsorge kein wirkliches Problem gewesen. Ich habe einfach ein starkes Passwort und dazu die beiden Plugins Limit Login Attempts Reloaded und Two Factor verwendet, um die Anzahl der Fehlversuche zu begrenzen (Rate-Limiting) bzw. ein TOTP als zweiten Faktor zum Passwort zu haben.

Bei Spam-Kommentaren sieht das Ganze jedoch anders aus. Ziel der Spam-Bots ist es eigentlich immer, auf gewisse Webseiten zu verlinken. Im besten Fall ist es nur Eigenwerbung, öfters dagegen allerdings scheinen es Phishing- und Betrugsversuche zu sein. Wordpress bietet als Gegenmaßnahme die Möglichkeit, Kommentare mit Wortlisten zu filtern. Wörter auf der Blacklist werden direkt als Spam markiert und nicht veröffentlicht, Wörter auf der Moderationsliste müssen manuell freigegeben werden.

Heiße Tipps für die Blacklist sind übrigens “casino”, “dating” und “bitcoin”. Für die Moderationsliste ist allein das Filtern nach Links mittels Keyword “http” in >95% der Fällen zielführend. 😉

Die Kunst des Spam-Filterns ist die Balance zu finden, so viele Spam-Nachrichen wie möglich automatisch von der Veröffentlichung zu verhindern, aber gleichzeitig False-Positives zu vermeiden. Ich wollte unbedingt verhindern, dass keiner der freundlichen und hilfreichen Kommentare echter Leser verloren geht. Allerdings wollte ich auch aus Datenschutz- und Unabhängigkeitsgründen keine Dienste Dritter verwenden, die die Filterung für mich übernehmen.

Daher erhielt ich im Schnitt rund täglich eine Mail zur Kommentar-Moderation, rund 95% davon leider Spam. Nervig, aber auch gleichzeitig schwer zu vermeiden ohne die eigenen Prinzipien aufzugeben.

Der Kampf gegen Wordpress selbst

Der zweite Punkt, der mich an Wordpress störte, sind die “Verbesserungen” von Wordpress selbst und die nötigen Mittel, die das Verhalten abstellen.

Zu nennen ist vor allem der Gutenberg Editor, mit dem seit einiger Zeit standardmäßig Posts und Seiten erstellt werden. Im Prinzip nutzt der Editor “Blöcke” mit denen Inhalte eingefügt und positioniert werden können. Schön und gut, wenn man gerne mit der Maus sich seine Webseite zusammenklicken will und einem die damit zusätzlich geladenen CSS-Regeln egal sind. Ihr könnt den Gutenberg Editor direkt im Browser testen und selbst entscheiden, ob ihr so Inhalte erstellen wollt. Mein Fall ist es leider nicht, sodass ich (you guessed it) per Plugin den Classic Editor installierte. Auch der ist nicht perfekt, gibt aber mehr direkte Kontrolle über die HTML-Ausgabe zurück.

Plugins über Plugins

Weiter störte mich die Notwendigkeit von weiteren Plugins, um mir Wordpress zurechtzubiegen:

  • Clearfy: Abstellen von APIs, JQuery JavaScript, andere HTML Metadaten
  • Disable Emojis: Abstellen der Emoji-Font
  • WP-GeSHi-Highlight: Syntax Highlighting für Codeschnippsel
  • WP Super Cache: Caching von Seiten und Beiträgen als fertig gerenderte HTML-Dokumente
  • Yoast SEO: Suchmaschinenoptimierung durch Opengraph/Twitter Cards Metadaten

Was ist das Problem mit der Vielzahl an Plugins?

  1. Sie sind nötig, um meine Inhalte überhaupt schön darzustellen (z.B. Syntax Highlighting)
  2. Sie stellen Funktionen bereit, die Wordpress selbst bieten sollte (SEO Metadaten)
  3. Sie stellen Funktionen von Wordpress ab, was Wordpress selbst als Option bieten könnte
  4. Sie sind nötig, um Wordpress performant zu machen (Super Cache, Clearfy, Disable Emojis)
  5. Sie sind fremder Code und damit auch gewissermaßen auch sicherheitsbedenklich
  6. Sie müssen regelmäßig aktualisiert werden, um kompatibel und sicher zu bleiben (was zum Glück seit einigen Wordpress Releases endlich automatisch passieren kann!)
  7. Sie mutieren mit steigender Beliebtheit gerne zu einer Art Adware (Werbebanner für “Pro” Versionen im Admin-UI)

Auf der einen Seite ist es schön, dass Wordpress Plugins ermöglicht, die Funktionalitäten anpassen und zu erweitern. Andererseits sind sie aber ein notwendiges Übel, welches Sorgfalt und Pflege bedarf.

Statische Webseiten

Während Wordpress Webseiten dynamisch bei jedem Aufruf erzeugt, generieren Programme wie bspw. Hugo oder Jekyll statische Webseiten. Bei statischen Webseiten liegen die einzelnen Seiten also als fertig erzeugte HTML-Dokumente auf dem Webserver und müssen daher eben nicht beim Aufruf erst mit einer Scriptsprache wie PHP erzeugt werden.

Statische Webseiten haben daher große Vorteile:

  1. Die Performance ist durch den Wegfall der Seitenerzeugung sehr hoch
    • Sehr kurze Ladezeiten für Benutzer
    • Sehr geringe Serverlast, hohe Skalierbarkeit
  2. Es wird kein PHP Interpreter und keine Datenbank (z.B. MySQL) benötigt
  3. Kein dynamisch ausgeführter Code (Webserver ausgenommen)
    • Keine Sicherheitslücken
    • Keine regelmäßigen Updates notwendig

Der Nachteil statischer Seiten ist natürlich, dass die Inhalte der einzelnen Seiten eben nicht veränderlich (daher “statisch”) sind. Damit fallen generell erst einmal einige Features wie eine Kommentar- und Suchfunktion weg. Auch gibt es keine Oberfläche, mit der die Inhalte direkt im Browser auf dem Server erstellt werden können. Für alle dieser Punkte gibt es Lösungen oder Alternativen.

Hugo

Hugo ist ein sehr beliebter Generator für statische Webseiten. Es ist in der Programmiersprache Go geschrieben und daher für quasi alle Betriebssysteme/Architekturen verfügbar. Textinhalte werden in Markdown verfasst, sodass prinzipiell jeder beliebige Editor verwendet werden kann. Ich selbst bevorzuge (wie für so vieles) Visual Studio Code.

Die Funktionsweise von Hugo zu erklären würde diesen Artikel noch viel länger machen als er eh schon ist, daher verweise ich an dieser Stelle auf die verlinkte Homepage mit der Dokumentation 😄. Der Workflow zum Erstellen eines neuen Posts ist in Kurzform folgender:

  1. Im Projektordner den Befehl hugo new posts/my-new-post/index.md ausführen
  2. In der erzeugten Datei die Metadaten (bei mir im YAML-Format) anpassen
  3. Inhalt mit Markdown-Syntax erstellen, dabei Live-Vorschau mit hugo server im Browser anschauen
  4. Mit hugo die Webseite generieren
  5. Den erzeugten Ordner public auf den Webserver kopieren

Man kann an dieser Stelle bereits feststellen, dass Hugo nicht für jedermann geeignet ist, dadurch dass Terminalbefehle verwendet werden müssen. Auch generell wird im Vergleich mit Wordpress wesentlich mehr Grundverständnis in der Verwendung gefordert. Man sollte auch wissen wie bei Hugo Dateipfade zu URLs werden, wie die Syntax von Markdown, YAML und TOML ist und wie man die Rohform seiner Webseite verwaltet, bspw. über ein git-Repository. Für Web- oder Software-Entwickler ist das sicherlich kein Problem, kann jedoch für Hobbyisten eine recht große Einstiegshürde sein.

Für mich persönlich ist Hugo eine kleine Offenbarung, weil es die vielen genannten Schwächen von Wordpress nicht hat. Die großen Freiheiten bei der Generierung der Seiten, kombiniert mit der Performance, Sicherheit und Wartungsfreiheit einer statischen Webseite, sind genau die Punkte, die mich überzeugt haben.

Die Migration von Wordpress zu Hugo

Nun kam es also zum Umzug meines, zugegebenermaßen recht überschaubaren, Blogs. Die Migration bestand im Prinzip aus zwei nenneswerten Schritten. Zuerst habe ich mein Wordpress-Theme (handcrafted) in Form eines eigenen Hugo-Themes nachgebaut. Danach habe ich die Inhalte übernommen. Auf beide Punkte will ich gerne gesondert eingehen.

Theme Migration

Hugo Themes sind erstaunlich ähnlich zu erstellen wie Wordpress Themes, obwohl die Template-Sprachen komplett unterschiedlich sind. Wordpress Themes bestehen PHP-Scripten, Hugo Themes aus sogenannten GoLang Templates. Bei beiden wird letztenendes ein HTML-Gerüst definiert, welches mit Template-Funktionen mit den Inhalten gefüllt wird.

Beispiel: Post-Titel einfügen

  • Wordpress:
    <h1><?php the_title(); ?></h1>
    
  • Hugo:
    <h1>{{ .Title }}</h1>
    

Hugos Templates besitzen immer ein Kontext-Objekt, den Punkt, auf dessen Attribute und Methoden zugegriffen werden kann. Ein Kontext ist auf oberster Ebene immer die aktuell generierte Seite (Typ “Page”) bzw. eine Liste aus Seiten (Typ “Pages”). Der Kontext kann aber auch selbst geändert werden, bspw. wenn man auf globale Attribute der Webseite zugreifen will. Bei der Erstellung von Templates muss man daher immer wissen, was gerade der Kontext ist. Auch hier möchte ich auf Hugos Dokumentation verweisen, weil das Thema komplex genug für ein eignes Buch ist 😄.

Bei der Migration des Themes habe ich Chance genutzt und das Design hier und da etwas aufgefrischt und modernisiert. Gefallen hat mir besonders, dass Hugo Template-Funktionen bietet, mit denen automatisch SEO Metadaten wie Opengraph, Twitter Cards und Sitemaps generiert werden können, sowie andere schöne Features wie CSS/JS Minimizer etc.

Content Migration

Das Übertragen der bestehenden Inhalte war reine Fleißarbeit. Am Ende des Tages habe ich im Wordpress Admin-UI jeden Post geöffnet, im Classic Editor den HTML Code kopiert und mit etwas Regex-Magie am Ende zu Markdown “konvertiert”.

Bei eingebetteten Bildern war das Ganze etwas umständlicher. Diese habe ich aus dem wp-content/uploads/<yahr>/<monat> Verzeichnis kopieren und das HTML img-Element zu Markdown-Syntax (![alt text](relative-link.jpg)) umwandeln müssen. Ich habe dabei die Original-Bilder aus dem Uploads-Ordner verwendet und mit GIMP + jpegoptim/optipng skaliert und optimiert.

Syntax-Highlighting für Codeschnippsel gibt’s bei Hugo dank Markdown for free 🎉. Hier musste nur der HTML-Code aus Wordpress zu äquivalentem Markdown umgeschrieben werden.

Meine letzte Sorge waren die Permalink-URLs. In Wordpress hatten Posts das Linkformat /the-post-slug, in meinem Hugo Setup kommt allerdings technisch bedingt noch der “Archetype” (quasi die Art der Seite, aktuell “page” oder “post”) dazu. Damit alte Bookmarks oder Links aber nicht ins Nirvana laufen, kann man in den Metadaten der Seiten (“Frontmatter”) in der Liste “aliases” den alten Link eintragen, sodass eine HTML-Dokument mit einer Weiterleitung von Hugo erzeugt wird.

Status Quo / Quo Vadis?

Wie ihr unschwer erkennen könnt hat die Migration geklappt. Die Seite ist in Rekordgeschwindigkeit geladen, alle Inhalte sind verfügbar und unter der originalen URL erreichbar und ein aufgefrischtes Aussehen gibt’s noch dazu.

Seit der Migration können lediglich die Kommentarfunktion und eine Suche vermisst werden. Ersteres finde ich schon bedauerlich, da ich einen Austausch mit und Feedback von Euch schon gut gefunden habe. Ich könnte in Zukunft auf Drittlösungen wie Disqus setzen, möchte ich allerdings ungern.

Die Suchfunktion werde ich wahrscheinlich auch nicht zurückbringen, da ich keinen echten Mehrwert darin sehe. Zum einen kann das die Suchmaschine eurer Wahl eh besser, zum anderen ist die Menge meiner Beiträge eh nicht sehr hoch. Allerdings versehe ich meine Posts mit Kategorien und Tags, was ggf. auch weiterhelfen kann.

Punkte, die ich mir in Zukunft ansehen werde, sind die Einführung mehrsprachiger Artikel (Englisch & Deutsch), Optimierung von Bildern (webp-Format, unterschiedliche Größen für Mobile) und wie ich das Deployment automatisieren kann.

Schreibt mir gerne eine Mail oder Telegram-Nachricht (siehe Impressum), falls ihr Feedback oder Fragen habt!