Multisprachige Webseite mit Jekyll

07.05.2024 10:08

Jekyll - eine performante Alternative

Wer heute eine Webseite baut, kann zwischen vielen unterschiedlichen Vorgehen und Frameworks wählen. Die meisten davon sind sehr mit JavaScript überladen, oft unnötigerweise. Sehr oft verursachen diese Frameworks auch eine relativ hohe CPU-Last auf dem Server, weil sie beispielsweise in PHP geschrieben sind und gleich darauf ausgelegt alles zu können - einen Editor für Posts mitzuliefern, mehrbenutzerfähig zu sein, erweiterbar durch Plugins, etc. Solche Frameworks gehen auch immer mit einer Datenbank einher.

Diese Features sind gut, aber nicht unbedingt immer 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 erstellen statischen Webseiten auch locker fertig!

Aber, was tun, wenn man einen mehrsprachigen Blog, oder eine mehrsprachige Webseite betreiben will? Zumindestens 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. So kann es passieren, dass man tagelang an einer Webseite arbeitet, scheinbar Fortschritte macht, aber dann vor eine Wand läuft die nur noch durch hässliche Hacks zu umgehen ist. Viel Erfolg beim nächsten Update, wenn alles wieder zusammenbricht…

Grundsätzliche Tipps

Will man eine Webseite mit Jekyll bauen, so sollte man vermeiden sich in die Neuerfindung des Fahrrads zu stürzen! Das gilt allgemein für jedes Softwareprojekt. Hier meine grundsätzlichen Tipps im Detail:

  1. Immer auf die offiziellen Ressourcen als erstes zurück greifen, nicht einfach drauflos suchen
  2. Auf GitHub gibt es viele Themes für Jekyll. Schaut euch vor allem die an, welche die meisten Sterne haben. Nehmt sie als Muster zur Erstellung eines eigenen Themes, oder verwendet diese direkt weiter
  3. Versucht so weit wie möglich nicht Funktionen von Jekyll zweck entfremdet zu benutzen. Collections sind z.B. nicht dazu da mehrsprachigen Inhalt anzuordnen

Was sind denn die offiziellen Ressourcen? Anlaufstelle Nr. 1 ist die Hauptseite des Projekts: Jekyll. Dort im Bereich Docs findet ihr schon eine sehr gute Anleitung und Erklärung für erste Schritte. Will man jedoch weiter gehen, und hat man etwas vor, was in dieser Anleitung nicht beschrieben ist, so ist ein Blick auf die Ressourcen angesagt. Vor allem empfehle ich die Liste der Jekyll Plugins.

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, stattdessen habe ich ja oben darauf verlinkt.

Multisprachiger Blog

Wie baut man also genau einen multisprachigen Blog mit Jekyll? Hier sind die Plugins, die man m.M.n. zumindestens nehmen sollte:

  • “jekyll-paginate-v2”
  • “jekyll-polyglot”
  • “jekyll-sitemap”
  • “jekyll-seo-tag”

Diese sind im Gemfile einzutragen, so sieht es bei mir aus:

  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 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: nehmt euch eines dieser Themes, oder nutzt es als Template ;-)

Datenstruktur

Die richtige Datenstruktur ist sehr wichtig, sonst kann einer der folgenden Fehler passieren:

  • die Webseite sieht funktionsfähig aus nach einem bundle exec jekyll serve, 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 multisprachig werden. Außerdem brauchen wir mehrere Kategorien, wie z.B. einen Blog und ein Portfolio, möglicherweise einen separaten News-feed für Updates welche die Seite selbst betreffen.

  • Jede Kategorie braucht ein eigenes Unterverzeichnis. Diese Ordner gehören ins Wurzelverzeichnis. Z.B.:
    my-website
      blog
      photos
      portfolio
    

    Gebt euren 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 heisst. So sieht es bei mir aus:
    my-website
      blog
          _posts
      photos
          _posts
      portfolio
          _posts
    
  • Da die Seite mehrsprachig werden soll, gehören da noch Unterverzeichnise 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 .md Dateien generiert. 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): Polyglot Konfiguration Permalink Konfiguration

  • Legen wir eine index.md Datei an (Standardsprache für die Webseite ist Deutsch). Einfach im Wurzelverzeichnis anlegen. Hier ist das Front Matter:
    title: "Mehrsprachige Webseite!"
    lang: de
    permalink: /
    page_id: index
    link_title: "Start"
    description: "Ein Blog in mehreren Sprachen"
    
  • Jetzt dasselbe für Englisch. Die Datei muss nun anders heissen, sonst wird ja die alte überschrieben. Z.B. index.en.md:
    title: "Multilang website!"
    lang: en
    permalink: /
    page_id: index
    link_title: "Home"
    description: "A blog with multiple languages"
    

    Usw., für jede Sprache die noch benötigt wird

  • Legen wir nun die .md Dateien für unsere Kategorien an, diese werden später die Posts für diese jeweilige Kategorie abbilden. Ich lege die Datei blog.md so an:
    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. lang zeigt weiterhin die Sprache des Inhalts an. Das wird vom Polyglot Plugin benutzt, um Links korrekt zu generieren (ca. nach dem Muster [lang]/[categories]/[permalink].html). Der Bereich pagination ist notwendig, damit man die Posts in dieser Kategorie nicht alle auf einer Seite anzeigt, sondern mit der Zeit auch ein Vor- und Zurückblättern ermöglicht. Hier ist es wichtig eine gesonderte indexpage zu definieren, sonst überschreiben sich die Kategorien gegenseitig, sobald Pagination greift. Category muss gesetzt sein, 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.

  • In diesem Schritt erweitern wir das Front Matter von blog.md, 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 weiss, ich habe weiter oben geschrieben, dass man Funktionen nicht zweck entfremden sollte. Ich fand aber keinen besseren Weg, als den “tag” im Post zu nutzen, und hier nach eben diesem “tag” zu filtern. Immerhin ist es nicht ganz falsch, die Sprache des Artikels kann auch durchaus als “tag” gesetzt werden. Jetzt werden unter blog.md nur die Posts angezeigt, welche:

  • auf Deutsch sind (wo “tag: de” gesezt ist)
  • welche zur Kategorie Blog gehören (wo “categories: blog” gesetzt ist)

  • Vermutlich habt ihr schon ein Theme ausgesucht, oder ihr macht ein eigenes. Unabhängig davon, müsst ihr in einer der Layout Dateien die Anzeige der Posts aktivieren. Angenommen ihr habt eine default.html als den Layout für alle Seiten. Dann muss dort an der Stelle, wo die Posts aufgelistet werden sollen, zumindestens folgendes hin:

Paginate-Beispiel

Wie man das paginate-v2 Plugin konfiguriert, ist am besten hier beschrieben.

  • Jetzt müssen noch die .md Datein für alle anderen Seiten angelegt werden, je eine pro Sprache, genau wie oben beschrieben.