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.
- Hugo - Anleitung Teil 1 - i18n multilinguale Site erstellen
Im Teil 1 werden erste Konfigurationschritte in der hugo.toml, die Page Bundle Struktur der Webseiten und Front Matter Einträge in den Markdown Dateien beschrieben.
- Hugo - Anleitung Teil 3 - i18n multilinguale Site erstellen
Mit den folgenden Themen: Die T (Translate) Funktion von Hugo, das Umschalten der Sprache auf der Website inkl. Sourcecode und SCSS, Hugo Probleme mit multilingualen Tags, Tag Wolke als Themenübersicht, Tag Beitragsliste inkl. Sourcecode und SCSS, interne Verlinkung.
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
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 meta name=description
basiert auf unterschiedlichen Seiten. Mit 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.
head - HTML-Tag link rel=alternate
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.
SEO Tipp für link rel=“alternate”
Google erklärt den link rel= alternate
umfangreich in der Google Search Central Dokumentation:
body - Hugo’s block keyword
Im body
wird der Content der Webseite durch 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:
- In der - Hugo Dokumentation - Menus - wird die allgemeine Benutzung von Menüs erklärt.
- Die - Hugo Dokumentation - Menu Entry Properties - beschreibt die Menü Variablen und Funktionen.
- Der multilinguale Teil wird in der - Hugo Dokumentation - Multilingual Menus dokumentiert.
Nachfolgend meine multilingual relevanten Einträge in der hugo.toml
:
..
defaultContentLanguage = "de"
[languages]
[languages.de]
languageName = "Deutsch"
weight = 1
description = "Blog über Hugo, Webdesign, CSS/SCSS, 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
description = "Blog about Hugo, web design, CSS/SCSS, 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
Menüpunkte - languages.–.menu.main
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.
Menüpunkt - Variable url
Der Inhalt von url
bezieht sich relativ zur baseURL
in der hugo.toml
. Der Eintrag url = “/tags/"
Menüpunkt - Variable name
Die Variable name
wird als Menüpunkttext angezeigt. Durch die sprachliche Zuordnung wird in jeder Sprache der länderspezifische Text angezeigt.
Menüpunkt - Variable weight
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>☰</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 ☰
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 main
in der hugo.toml
.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">
<a href="javascript:void(0)" class="closebtn" onclick="closeNav()">×</a>
<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>
</div>
Der erste Link zeigt das Schließen-Symbol an. Wenn der Link angeklickt wird, wird die JavaScript Funktion closeNav
aufgerufen. Weiter unten dazu mehr. Der zweite Link ist für den Menüpunkt Startseite zuständig. In der hugo.toml
habe ich dafür keinen Menüpunkt eingetragen. Der Rest stimmt mit dem oben erklärten Partial nav.html
überein.
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.
Teil 3 dieser Reihe ist in Arbeit. Beim Schreiben fallen mir Dinge auf, die ich in den Teilen 1 und 2 im nachhinein anpassen muss. Deshalb sind die schon veröffentlichten Teile zurzeit noch nicht endgültig.
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
- Hugo Dokumentation - Base Templates and Blocks
- i18n Einträge in der hugo.toml
- Hugo Dokumentation - Site Variables
- Hugo Dokumentation - Page Variables
- MDN - Page titles and SEO
- Google Search Central Dokumentation - Google über lokalisierte Versionen deiner Seite informieren - HTML
- Hugo Dokumentation - Menus
- Hugo Dokumentation - Menu Entry Properties
- Hugo Dokumentation - Multilingual Menus
Das könnte Sie auch interessieren
- Hugo - Anleitung Teil 1 - i18n multilinguale Site erstellen
i18n - Teil 1 von 3 aufeinander aufbauenden Anleitungen für das Erstellen einer Hugo multilingualen Website.
- Hugo - Anleitung Teil 3 - i18n multilinguale Site erstellen
Mit den folgenden Themen: Die T (Translate) Funktion von Hugo, das Umschalten der Sprache auf der Website inkl. Sourcecode und SCSS, Hugo Probleme mit multilingualen Tags, Tag Wolke als Themenübersicht, Tag Beitragsliste inkl. Sourcecode und SCSS, interne Verlinkung.
- Hugo - Page Bundle Shortcodes für Bilder
In der Markdown Datei Bilder per Shortcodes aus dem Page Bundle einbinden.
- Hugo - i18n Multilingual - lastmod Datum länderspezifisch anpassen
i18n - Die länderspezifische Schreibweise des lastmod Datums entsprechend der Sprache anpassen.
Kommentare werden bei deutscher Spracheinstellung nicht in der englischen Variante der Webseite angezeigt und umgekehrt.