×
Startseite RSS-Feed Info
i18n - Teil 2 von 3 aufeinander aufbauenden Anleitungen für das Erstellen einer Hugo multilingualen Website.

Hugo - Anleitung Teil 2 - i18n multilinguale Site erstellen

Hugo - Anleitung Teil 2 - i18n multilinguale Site erstellen

i18n - Teil 2 von 3 Anleitungen für das Erstellen einer Hugo multilingualen Website. Der zweite Teil geht in die Tiefe der Theme-Entwicklung und zeigt die Programmierung der multilingualen Website. Mit den folgenden Themen: Einträge im html und head Tag der baseof.html und Menüstruktur in der hugo.toml, inklusiv der Navigation Partials nav.html und sidepanel.html.

Beitrag aktualisiert am 06.06.2023

Ich habe diesen Beitrag etwas überarbeitet und an die Hugo-Änderungen der Version 0.112 angepasst.

baseof.html - der Rahmen für eine multilinguale Website

Die baseof.html muss man sich als Bilderrahmen um den Content vorstellen. Ein Basis Template das auf allen Webseiten benutzt wird. Dadurch erspart man sich das ewige wiederholen von Dingen, die bei jeder Webseite vorhanden sein müssen. Eine in HTML manuell erstellte Webseite muss bei jeder nachträglichen Änderung in allen bis dahin erstellten Webseiten geändert werden.

In der Hugo Dokumentation - Base Templates and Blocks - wird das Einbinden von Content durch die Hugo Anweisung, von zum Beispiel {{ block "main" . }} erklärt. Aber dazu später mehr.

Mein gekürzter Sourcecode in der themes/tekki/layouts/_default/baseof.html sieht wie folgt aus:

<!doctype html>
<html lang="{{- .Site.Language.Lang -}}">
  <head>
    <meta charset="utf-8">
  
    {{ if eq .Params.sitemap_exclude true }}
    <meta name="robots" content="noindex, nofollow, noarchive">
    {{ else }}
    <meta name="robots" content="index, follow, archive">
    {{ end }}

    {{ if .IsHome }}
      <!-- Homepage -->
      <title>{{ .Site.Params.description }} - {{ .Site.Params.mydomain }}</title>
      {{ if .Site.Params.description }}
      <meta name="description" content="{{ .Site.Params.description }}">
      {{end}}
    {{ else }}
      <!-- Page, Blog Page -->
      <title>{{ .Title }} - {{ .Site.Params.mydomain }}</title>
      {{if .Description }}
        <meta name="description" content="{{ .Description }}">
      {{ else }}
        <!-- Tags -->
        {{ if eq .Site.Language.Lang "de" }}
          {{ if eq .Title "Tags" }}
            <meta name="description" content="Übersicht der Tags von {{ .Site.Params.mydomain }}">
          {{ else }}
            <meta name="description" content="Das Tag #{{ .Title }} ist mit diversen Blogbeiträgen verknüpft.">
          {{ end }}
        {{ else }}
          {{ if eq .Title "Tags" }}
            <meta name="description" content="Overview of the tags from {{ .Site.Params.mydomain }}">
          {{ else }}
            <meta name="description" content="The tag #{{ .Title }} is linked to various blog posts.">
          {{ end }}
        {{ end }}
      {{ end }}
    {{ end }}
  
    {{ if .IsTranslated }}
    {{ range .Translations }}
    <link rel="alternate" hreflang="{{ .Language.Lang }}" href="{{ .Permalink }}">
    {{ end }}
    <link rel="alternate" hreflang="{{ .Language.Lang }}" href="{{ .Permalink }}">
    {{ end }}
  </head>

  <body>
    {{ partial "header.html" . }}
    {{ partial "nav.html" . }}
    {{ partial "sidepanel.html" . }}
    <div id="content">
      {{ block "main" . }}{{ end }}
    </div>
    {{ partial "footer.html" . }}
  </body>
</html>

Den Sourceode habe ich wegen der Übersichtlichkeit und Erklärbarkeit auf die für i18n relevanten Einträge gekürzt. Für die Erklärungen habe ich die oben angezeigte baseof.html in entsprechende Code-Blöcke aufgeteilt:

html lang=“de” oder “en”

Mit der Language Angabe wird die Sprache für die komplette Seite bestimmt. Damit signalisiert man Screenreadern in welcher Sprache sie die Ausgabe umsetzen sollen. Google nutzt dieses Attribut nicht für die Suche, sondern ermittelt die Hauptsprache einer Seite auf Basis von deren Inhalten.

Mit Site.Language.Lang wird die Sprache der aktuellen Seite ausgegeben. Diese globale Variable erstellt Hugo durch die Analyse der [languages] Parameter in der hugo.toml. Diesen Parameter habe ich im Teil 1, im Abschnitt - i18n Einträge in der hugo.toml - beschrieben.

head - meta charset=“utf-8”

UTF-8 ist ein Zeichensatz der als Multibyte-Zeichenfolge auch Zeichen fernöstlicher Sprachen und Sprachen aus dem afrikanischen Raum darstellen kann. Die Standardzeichenkodierung in HTML-5 ist UTF-8. Ihr Sourcecode Editor muss das HTML-Dokument aber auch als UTF-8 speichern.

head - meta name=“robots” content=

    {{ if eq .Params.sitemap_exclude true }}
    <meta name="robots" content="noindex, nofollow, noarchive">
    {{ else }}
    <meta name="robots" content="index, follow, archive">
    {{ end }}

Wenn die aktuelle Webseite den Front Matter Parameter sitemap_exclude: true enthält, werden Suchroboter angewiesen die Webseite nicht zu indexieren, ihr nicht zu folgen und sie nicht zu archivieren. Wenn dies nicht der Fall ist sollen sie dies alles tun.

Den Front Matter Parameter sitemap_exclude: true habe ich im ersten Teil der HowTo-Serie beschrieben - Was und wofür sind _index.md Dateien? - Ungewollte Auswirkung auf die sitemap.xml

head - HTML-Tag title und Meta-Tag name=“description”

Im folgenden Abschnitt wird der Title und die Description für die aktuelle Webseite zusammengefügt. Es gibt die Bereiche Homepage, Webseite und Tags. Jeder Bereich muss individuell erstellt werden.

  
    {{ if .IsHome }}
      <!-- Homepage -->
      <title>{{ .Site.Params.description }} - {{ .Site.Params.mydomain }}</title>
      {{ if .Site.Params.description }}
      <meta name="description" content="{{ .Site.Params.description }}">
      {{end}}
    {{ else }}
      <!-- Page, Blog Page -->
      <title>{{ .Title }} - {{ .Site.Params.mydomain }}</title>
      {{if .Description }}
        <meta name="description" content="{{ .Description }}">
      {{ else }}
        <!-- Tags -->
        {{ if eq .Site.Language.Lang "de" }}
          {{ if eq .Title "Tags" }}
            <meta name="description" content="Übersicht der Tags von {{ .Site.Params.mydomain }}">
          {{ else }}
            <meta name="description" content="Das Tag #{{ .Title }} ist mit diversen Blogbeiträgen verknüpft.">
          {{ end }}
        {{ else }}
          {{ if eq .Title "Tags" }}
            <meta name="description" content="Overview of the tags from {{ .Site.Params.mydomain }}">
          {{ else }}
            <meta name="description" content="The tag #{{ .Title }} is linked to various blog posts.">
          {{ end }}
        {{ end }}
      {{ end }}
    {{ end }}

Die Startseite hat einen anderen Titel und Beschreibung, als eine normale Webseite. Sie erhält den Titel und die Beschreibung aus der hugo.toml. Bei der Webseite kommt der Titel und die Beschreibung aus den Front Matter Parametern der md Datei. Bei den Tags gibt es bei mir die Tag-Wolke und für ein einzelnes Tag eine Liste mit Beiträgen. Dazu weiter unten mehr.

Das Benutzen und auseinanderhalten von globalen Variablen .Site.Params.description und Page / Front Matter Variablen .Description hat mich am Anfang mehrmals in eigene Fehler laufen lassen. Aber eigentlich, wenn man es dann verstanden hat, ist es einfach. Die Hugo Dokumentationen sind dazu sehr aussagekräftig:

Title und description der Startseite

    {{ if .IsHome }}
      <!-- Homepage -->
      <title>{{ .Site.Params.description }} - {{ .Site.Params.mydomain }}</title>
      {{ if .Site.Params.description }}
      <meta name="description" content="{{ .Site.Params.description }}">
      {{end}}
    {{ else }}

Wenn die aktuelle Webseite die Startseite ist, werden die Inhalte für description und title aus der hugo.toml übernommen. In .Site.Params.mydomain steht bei mir die Domain.

Title und description der Webseiten

    {{ else }}
      <!-- Page, Blog Page -->
      <title>{{ .Title }} - {{ .Site.Params.mydomain }}</title>
      {{if .Description }}
        <meta name="description" content="{{ .Description }}">
      {{ else }}

Wenn die aktuelle Webseite nicht die Startseite ist, ist dies eine normale Webseite und der Titel und Description wird aus den Front Matter Variablen der Seite entnommen. Den Titel erweitere ich noch mit mydomain aus der hugo.toml, also der globalen, länderspezifisch angepassten Variablen mit dem Domainnamen.

Title und description der Tags

      {{ else }}
        <!-- Tags -->
        {{ if eq .Site.Language.Lang "de" }}
          {{ if eq .Title "Tags" }}
            <meta name="description" content="Übersicht der Tags von {{ .Site.Params.mydomain }}">
          {{ else }}
            <meta name="description" content="Das Tag #{{ .Title }} ist mit diversen Blogbeiträgen verknüpft.">
          {{ end }}
        {{ else }}
          {{ if eq .Title "Tags" }}
            <meta name="description" content="Overview of the tags from {{ .Site.Params.mydomain }}">
          {{ else }}
            <meta name="description" content="The tag #{{ .Title }} is linked to various blog posts.">
          {{ end }}
        {{ end }}
      {{ end }}
    {{ end }}

Nun wird es etwas komplizierter. Wenn die aktuelle Webseite nicht die Startseite ist und der Front Matter Parameter .Description nicht vorhanden ist, werden aktuell Tags angezeigt.

Den Titel für die Tags habe ich schon bei den “normalen” Webseiten zusammengesetzt. Mit {{ if eq .Site.Language.Lang "de" }} unterscheide ich in welcher Sprache die Seite angezeigt wird. Der nun folgende Aufwand für meta name=description basiert auf unterschiedlichen Seiten. Mit {{ if eq .Title "Tags" }} wird meine Tag-Wolke abgefangen. Im else Zweig wird die Teaser-Liste mit dem jeweiligen Tag angezeigt.

SEO Tipp für das HTML-Tag title

Ein längerer und genau beschreibender Titel gefällt Suchmaschinen besser als 1 oder 2 Wörter. In den Suchergebnissen werden von dem Titel nur 55 bis 60 Zeichen angezeigt. Der Rest wird abgeschnitten. Also sollte das Wichtige in diesen ersten 55 Zeichen stehen.

Quelle: MDN - Page titles and SEO

SEO Tipp für das Meta-Tag name=description

Google zeigt in der Ergebnisliste unterhalb der Titel-Links die Beschreibung aus dem Meta-Tag description an. Das Tag Description ist also sehr wichtig. Wenn man die Zeichenlänge der Texte auf der Ergebnisseite überprüft zeigt sich, dass ca. 160 Zeichen angezeigt werden. Selber beschränke ich mich auf weniger als 140 Zeichen. Dadurch sollte gewährleistet sein, dass auch alles was ich möchte angezeigt wird.

Wenn eine Webseite auch in einer übersetzten Version vorhanden ist, sollte man einen alternativen Link für Suchmaschinen einbauen. Zusätzlich muss ein alternativer Link auf die Seite selbst vorhanden sein. Eine sogenannte Selbstreferenzierung.

    {{ if .IsTranslated }}
    {{ range .Translations }}
    <link rel="alternate" hreflang="{{ .Language.Lang }}" href="{{ .Permalink }}">
    {{ end }}
    <link rel="alternate" hreflang="{{ .Language.Lang }}" href="{{ .Permalink }}">
    {{ end }}

Wenn die aktuelle Webseite übersetzt wurde, werden im range die alternativen Links zu den anderen Webseiten erstellt. Da ich nur eine andere Sprache zur Verfügung stelle, wird der range nach einem Durchlauf verlassen. Die Ausgabe des zweiten alternativen Links referenziert die Sprache der aktuellen Webseite.

Dieser Quelltext ist die einfachste Variante. Bei paginierten Webseiten - also URLs mit der Erweiterung /page/X/ wie z.B. die zweite Seite der Startseite oder Tag-Listen ab Seite 2 - wird es komplizierter. In meinem Blogbeitrag - SEO - Selbstreferenzierender hreflang auf mehrsprachiger Website - habe ich dies beschrieben.

Google erklärt den link rel= alternate umfangreich in der Google Search Central Dokumentation:

Google Search Central Dokumentation - Google über lokalisierte Versionen deiner Seite informieren - HTML

body - Hugo’s block keyword

Im body wird der Content der Webseite durch {{ block "main" }} eingebunden. Es gibt auf dieser Ebene nichts multilingual-spezifisches. block wird in der - Hugo Dokumentation - Base Templates and Blocks - erklärt:

 <body>
    {{ partial "header.html" . }}
    {{ partial "nav.html" . }}
    {{ partial "sidepanel.html" . }}
    <div id="content">
      {{ block "main" . }}
      {{end}}
    </div>
    {{ partial "footer.html" . }}
  </body>
</html>

Im Partial nav.html wird das Menü erstellt. Das Menü wird ab einer bestimmten Displaybreite mit der CSS-Anweisung display: none unsichtbar gemacht. Ansonsten stapeln sich die Menüpunkte häßlich übereinander. Das Partial sidepanel.html übernimmt dann die Menüfunktion. Aber dazu weiter unten mehr.

hugo.toml - Multilinguale Menüstruktur

Da meine Menüstruktur sehr übersichtlich ist, habe ich sie direkt in die hugo.toml eingefügt. Die Menü-Dokumentation von Hugo besteht aus folgenden Dokumenten:

Nachfolgend meine multilingual relevanten Einträge in der hugo.toml:

..
defaultContentLanguage = "de"
[languages]
  [languages.de]
    languageName = "Deutsch"
    weight = 1
    title = "Hugo, Webdev, SEO, Tools"
    [languages.de.params]
      description = "Blog über Hugo, Webdev, SEO, Tools"
      mydomain = "tekki-tipps.de 🇩🇪"

    [[languages.de.menu.main]]
      url    = "/tags/"
      name   = "Tags"
      weight = 1
    [[languages.de.menu.main]]
      url    = "/datenschutz/"
      name   = "Datenschutz"
      weight = 10
    [[languages.de.menu.main]]
      url    = "/impressum/"
      name   = "Impressum"
      weight = 20
    [[languages.de.menu.main]]
      url    = "/kontakt/"
      name   = "Kontakt"
      weight = 30

  [languages.en]
    languageName = "English"
    weight = 2
    title = "Hugo, Webdev, SEO, Tools"
    [languages.en.params]
      description = "Blog about Hugo, Webdev, SEO, Tools"
      mydomain = "tekki-tipps.de/en/ 🇬🇧"

    [[languages.en.menu.main]]
      url    = "/tags/"
      name   = "Tags"
      weight = 1
    [[languages.en.menu.main]]
      url    = "/data-protection/"
      name   = "Data Protection"
      weight = 10
    [[languages.en.menu.main]]
      url    = "/legal-notice/"
      name   = "Legal notice"
      weight = 20
    [[languages.en.menu.main]]
      url    = "/contact/"
      name   = "Contact"
      weight = 30

Die Einträge in der hugo.toml wurden von mir nachträglich an die Hugo-Version 0.112 angepasst. Siehe dazu auch - Multilingual - Änderungen in Hugo ab Version 0.112 .

Die Menüinhalte für deutsch und englisch sind bis auf die Sprache identisch. Hugo ist sehr empfindlich was die Schreibweise der Menüpunkt in den verschiedenen Sprachen angeht. Die Syntax [[languages.de.menu.main]] und [[languages.en.menu.main]] muss eingehalten werden.

Der Inhalt von url bezieht sich relativ zur baseURL in der hugo.toml. Der Eintrag url = “/tags/" resultiert bei mir in der deutschen Variante in https://tekki-tipps.de/tags/ und in der englische in https://tekki-tipps.de/en/tags/.

Die Variable name wird als Menüpunkttext angezeigt. Durch die sprachliche Zuordnung wird in jeder Sprache der länderspezifische Text angezeigt.

Die Reihenfolge der Menüpunkte wird durch die Variable weight festgelegt und erfolgt aufsteigend.

i18n Menü - Partial nav.html

Die Navigatiosleiste verschwindet auf dieser Website, wenn man auf der Seite nach unten scrollt. Das Hamburger-Icon nutze ich für ein Sidepanel, in dem ebenfalls das Menü angezeigt wird. Sobald die Navigationsleiste nicht mehr angezeigt wird, rutscht der Hamburger-Button in die Headerleiste links neben mein Logo. Nachfolgend der Sourcecode für die Navigation themes/tekki/layouts/partial/nav.html:

<nav id="navigation-bar">
	<div class="container">
		<div class="navbutton">
			<button type="button" class="btn btn-link menu-hamburger openbtn" onclick="openNav()"><span>&#9776;</span> {{ T "Menu" }}</button>
		</div>
		<ul class="menulinks">
			{{ $currentPage := . }}
			{{ range .Site.Menus.main }}
				{{ $menu_item_url := .URL | relLangURL }}
				{{ $page_url := $currentPage.RelPermalink | relLangURL }}
				<li {{ if eq $menu_item_url $page_url }}class="active"{{ end }}>
					<a href="{{ $menu_item_url | absLangURL }}">{{ .Name }}</a>
				</li>
			{{ end }}
		</ul>
	</div>
</nav>

Hamburger-Button für das Sidepanel

Der Hamburger-Button, der richtige Name lautet im Unicode Trigram for Heaven , wird durch die dezimale HTML-Kodierung &#9776; angezeigt. Wenn der Button angeklickt wird, wird die JavaScript Funktion openNav() aufgerufen. Dazu weiter unten mehr. Mit der Hugo T-Funktion wird ein String, in dem Fall - Menü / Menu - in die aktuelle Sprache übersetzt. Mehr dazu im Teil 3 dieser HowTo-Reihe.

Zusammenstellen der Menü Listenstruktur

Mit {{ range .Site.Menus.main }} wird in der aktuellen Sprache, dass Menü main in der hugo.toml nach Menüeinträgen durchsucht. “.Site” wird von Hugo als [languages.de] oder [languages.en] interpretiert. Danach wird in der Variablen $menu_item_url die länderspezifische URL, für den in der Schleife durchsuchten Menüpunkt gespeichert. Der Variablen $page_url wird die länderspezifische URL der Webseite zugewiesen. Bei dem Zusammenfügen des HTML-Tags li wird untersucht, ob die aktuelle Webseite mit der URL des Menü-Listenpunktes übereinstimmt. Wenn ja, dann wird die CSS-Klasse active zugewiesen. Danach wird der Link aufgebaut und der Name des Menüpunktes eingefügt.

CSS/SCSS - Partial nav.html

Die SCSS Anweisungen werde ich nicht besonders erläutern. Das ist Webdesign und gehört zum Handwerkszeug dazu. Falls Sie SCSS nicht verstehen, gibt es im Internet Websites die eine Konvertierung von SCSS in CSS anbieten.

In der CSS-ID navigation-bar und weiteren CSS-Klassen, weise ich den Wert einer Variablen, zum Beispiel var(–wk-container-bg); zu. Der Grund für die Zuweisung per Variablen ist der Darkmode meines Themes. Standardmäßig startet das Theme im Lightmode. Durch ein Theme Switcher Symbol - ganz oben, das Zweite von rechts - kann in den Dunkelmodus umgeschaltet werden.

Weiter unten wird der Breite des Containers, die Variable $site-width zugewiesen. In SCSS sind solche Zuweisungen möglich und sorgen für Flexibilität. Das SCSS wird bei mir in folgender Datei gespeichert - themes/tekki/assets/scss/layouts/basic.scss:

#navigation-bar {
	display: flex;
	width: 100%;
	margin-top: 5.5rem;
	background-color: var(--wk-container-bg);
	border-top: 1px dotted var(--wk-accent-border-color);
	border-bottom: 1px dotted var(--wk-accent-border-color);

	.container {
		display: flex;
		width: $site-width;
		background-color: var(--wk-container-bg);
	
		.navbutton {
			display: flex;
			padding-right: 1.0rem;

			.btn {
				border-radius: 0;
				color: var(--wk-link-color);
			}
			.btn:focus {
				box-shadow: none;
			}
			.btn-link {
				text-decoration: none;
			}
			span {
				padding-bottom: 0.1rem;
				padding-right: 0.3rem;
			}
			.menu-hamburger {
				margin-left: -1.5rem;
				padding-right: 1.0rem;
				border-right: 1px dotted var(--wk-accent-border-color);
				background-image: none;
			}
		}
		.menulinks {
			display: flex;
			flex-direction: row;
			list-style: none;
			margin: 0;
			padding: 0;

			a {
				float: left;
				display: block;
				color: var(--wk-link-color);
				text-align: center;
				padding: 15px;
				text-decoration: none;
			}
			.active {
				border-top: 2px solid red;
			}
		}
	}
}
// Responsive
//
@media (max-width: 767.8px) {
	#navigation-bar {
		.container {
			.menulinks {
				display: none;
			}
		}
	}
}
@media (max-width: 575.8px) {
	#navigation-bar {
		.container {
			width: 100%;

			.navbutton {
				.menu-hamburger {
					margin-left: -1.0rem;
				}
			}
		}
	}
}

Wenn die Navigationsleiste noch sichtbar ist, es wurde also noch nicht nach unten gescrollt, werden bis zu einer maximalen View-Breite von 767.8px die Menüpunkte unsichtbar gemacht. Ansonsten würden sich die Menüpunkte stapeln und das sieht nicht gut aus. Das Menü ist über das Sidepanel auch im Responsive Mode immer erreichbar.

Wie Sie die Responsive Anzeige überprüfen können, habe ich in einem anderen Beitrag beschrieben - Überprüfen des responsive Viewport .

i18n Menü - Partial sidepanel.html

Sourcecode: themes/tekki/layouts/partial/sidepanel.html:

<div id="tt-sidepanel" class="sidepanel">
	<div class="closebtn" onclick="closeNav()">×</div>
	<a href='{{ "/" | relLangURL }}'>{{ T "Startseite" }}</a>
	<ul class="menulinks">
		{{ $currentPage := . }}
		{{ range .Site.Menus.main }}
			{{ $menu_item_url := .URL | relLangURL }}
			{{ $page_url:= $currentPage.RelPermalink | relLangURL }}
			<li {{ if eq $menu_item_url $page_url }}class="active"{{ end }}>
				<a href="{{ $menu_item_url | absLangURL }}">{{ .Name }}</a>
			</li>
		{{ end }}
	</ul>
	<a href='{{ "/rss-info/" | relLangURL }}'>{{ T "rssInfo" }}</a>
</div>

Das zweite div zeigt das Schließen-Symbol an. Wenn das x angeklickt wird, wird die JavaScript-Funktion closeNav aufgerufen. Mehr dazu weiter unten. Der erste Link ist für den Menüpunkt Startseite zuständig. In der hugo.toml habe ich dafür keinen Menüpunkt eingetragen. Alle Einträge zwischen dem ul entsprechen dem oben erklärten Partial nav.html. Am Ende wird ein Link hinzugefügt, der auch nicht im Partial nav.html enthalten ist. Sonst wird das horizontale Menü zu groß.

CSS/SCSS - Partial sidepanel.html

Sourcecode: themes/tekki/assets/scss/layouts/basic.scss:

.sidepanel {
  width: 0;
  position: fixed;
  z-index: 100;
  top: 0;
  left: 0;
  background-color: var(--wk-container-bg-4);
  overflow-x: hidden; /* Disable horizontal scroll */
  padding: 3.0rem 0 2.0rem;
  transition: 0.5s;

	a {
		display: block;
		padding: 0.5rem 0.5rem 0.5rem 1.0rem;
		text-decoration: none;
		font-size: 25px;
		color: var(--wk-accent-color-5);
		transition: 0.3s;
	}
	a:hover {
		color: #f1f1f1;
	}
	.closebtn {
		position: absolute;
		top: 0;
		right: 0.5rem;
		font-size: 36px;
		background-image: none;
	}
	.menulinks {
		list-style: none;
		margin: 0;
		padding: 0;
	}
}

JavaScript - Partial sidepanel.html

Sourcecode: themes/tekki/assets/wkjs/wk-1.0.js:

/* Set the width of the sidebar to 250px (show it) */
function openNav() {
  document.getElementById("tt-sidepanel").style.width = "250px";
}

/* Set the width of the sidebar to 0 (hide it) */
function closeNav() {
  document.getElementById("tt-sidepanel").style.width = "0";
}

Fazit

Wenn Sie ein fertiges Theme für Ihr Hugo Projekt einsetzen, werden Sie wahrscheinlich diese hier beschriebenen, tiefen Eingriffe nicht benutzen können. Trotzdem können einige Hinweise nützlich sein.

Wie ich im Teil 1 schon gesagt habe - dies ist mein Weg um eine multilinguale Website aufzubauen. Ich wollte vom Theme her nicht wieder abhängig sein. Es ist selbstverständlich, dass wenn Theme Autoren ein Theme nicht mehr weiterentwickeln wollen, sie die Freiheit haben den Service einzustellen. Da ich dies selber erlebt habe, programmiere ich meine Themes lieber selber.

Ich habe den Aufwand für so eine Reihe komplett unterschätzt. Ich versuche die einzelnen Hugo Schritte genau zu erklären, so dass hoffentlich auch ein i18n-Anfänger meinen Sourcecode versteht. Dadurch fallen mir gleichzeitig unschöne Dinge in meinem eigenen Sourcecode auf. Die ich dann korrigiere und so lange rumprobiere bis ich mit dem dann öffentlichen Ergebnis zufrieden bin.

Jedenfalls so lange bis ich mir den eigenen Sourcecode Wochen später noch einmal anschaue …

Linkliste zu diesem Beitrag

Das könnte Sie auch interessieren

Update:  |
17 Minuten Lesezeit
0
Dieser Beitrag wurde mit der Hugo-Version 0.115.2 erstellt.

Kommentare werden bei deutscher Spracheinstellung nicht in der englischen Variante der Webseite angezeigt und umgekehrt.

© 2023 - Frank Kunert  -  Ich über mich