ortlepp.eu

Mehrsprachige Internetseiten mit JBake

Wie ich in meinem letzten Eintrag geschrieben habe, habe ich meine Internetseite und meinen Blog mit Jbake erstellt. Beides, die Internetseite selbst und der Blog sind auf Deutsch und Englisch verfügbar. In diesem Post werde ich darüber schreiben, wie das funktioniert und wie ich die Internetseite erstellt habe.

Die Voraussetzung für die gesamte Internetseite ist der Apache Webserver mit mod_negotiation, das Content Negotiation bereitstellt. Kurz zusammengefasst ermöglicht Content Negotiation, dass unterschiedliche Inhalte unter derselben URI bereitgestellt werden, die Auslieferung der Inhalte ist dann abhängig von den Fähigkeiten oder der Konfiguration des Clients.

Content Negotiation kann einfach durch die folgenden Zeilen in einer .haccess-Datei aktiviert werden:

<IfModule mod_negotiation.c>
  AddLanguage en .en
  AddLanguage de .de
  LanguagePriority en de
  DefaultLanguage en
  DirectoryIndex index index.html
</IfModule>

Diese Zeilen sind ziemlich selbsterklärend: Dateien mit der Endung .en enthalten englischsprachige Inhalte, Dateien mit der Endung .de deutschsprachige. Englisch hat eine höhere Priorität als Deutsch und der englischsprachige Inhalt wird standardmäßig ausgeliefert – z.B. wenn der Besucher als bevorzugte Sprache nur Französisch ausgewählt hat.

Als nächstes muss man JBake dazu bringen, englischsprachige Dateien mit der Endung .en zu erzeugen und deutschsprachige Dateien mit der Endung .de. Von Haus aus geht das leider nicht, aber es gibt einen Trick: Es werden zwei einzelne Blogs, eines für jede Sprache, angelegt. Mit Gradle werden dann die beiden Blogs "gebacken" und schließlich zu einem Blog zusammengeführt.

Für meinen Blog verwende ich die folgende Ordner- und Dateistruktur:

Projektverzeichnis
 - assets
    - favicon.ico
    - ...
 - templates
    - page.ftl
    - ...
 - websiteDE
    - content
       - index.adoc
       - ...
    - jbake.properties
 - websiteEN
    - assets
       - .jbakeignore
    - content
       - index.adoc
       - ...
    - jbake.properties
 - build.gradle
 - buildDE.gradle
 - buildEN.gradle

Es gibt dabei ein paar Besonderheiten: Zum Beispiel nutzen beide Blogs dieselben Templates. Wo es nötig ist, wird anhand der Sprache die Ausgabe angepasst, z.B. bei Datumsformaten. Außerdem sind die statischen Ressourcen ("assets") nur einmal vorhanden und werden auch nur einmal verarbeitet, für das zweite Blog gibt es nur eine Art "Fakeordner" ohne Inhalte. Detailliert ist das in meinem Beispielprojekt am Ende dieses Eintrags zu sehen.

Zuletzt fehlt noch ein wichtiges Detail: Die Sprache soll auch manuell gewechselt werden können. Dafür kann ein Cookie verwendet werden, in dem die bevorzugte Sprache gespeichert wird. Wird der Apache Webserver über die .htaccess-Datei entsprechend konfiguriert, überschreibt ein vorhandener Cookie die vom Benutzer im Browser eingestellten bevorzugten Sprachen:

SetEnvIf Cookie "language=(.+)" prefer-language=$1
Header append Vary cookie

Damit der Benutzer die Sprache ändern kann, kann man beispielsweise etwas JavaScript verwenden:

function setLanguageEnglish() {
 document.cookie = "language=en;path=/";
 location.reload();
}

So wird ein Cookie mit der bevorzugten Sprache gespeichert und die Seite neu geladen - dann in der ausgewählten Sprache.

Zum Schluss hier nun ein Beispielprojekt, das ähnlich wie meine Webseite und mein Blog aufgebaut ist: jbake-example.zip . Die Seite kann durch den Aufruf von gradle im Basisverzeichnis erstellt werden.