Adventskalender 11. Dezember 2024 - Hugo
Verfasst: 11.12.2024 06:44:32
Hugo
Hinter diesem Türchen verbirgt sich Hugo: ein mächtiger und äusserst performanter Generator für statische Webseiten. Der Name dürfte einerseits an die Programmiersprache Go erinnern, in der er implementiert ist. (Go macht es einfach, Aufgaben zu parallelisieren, was wohl ein wichtiger Faktor für die ausserordentlich hohe Performance von Hugo sein dürfte.) Das “Hu” (wie “huge”) dürfte eine Anspielung darauf sein, das man mit Hugo riesige Seiten in nützlicher Frist generieren kann.
Themes: vorgefertigte und eigene
Zum Einstieg in Hugo wird oft empfohlen ein vorgefertigtes Theme zu wählen. Das ist für die meisten Seiten sicherlich ein guter Rat. So habe ich positive Erfahrungen mit dem äusserst mächtigen Relearn-Theme gemacht, das u.a. LaTeX-Formeln mit MathJax, Diagramme mit Mermaid und eine clientseitige JavaScript-Suche out of the box mitbringt. Ich brauche das für meine Unterrichtsmaterialien, siehe etwa die Webseite für mein Cloud-Modul.
Privat habe ich zwei Webseiten am Laufen: zum einen meine Hauptwebseite paedubucher.ch, die auf einem selber gebauten Hugo-Theme basiert. Neulich habe ich mir an einem Abend einen neuen Blog namens Read, Think, Write zusammengehackt. Hier kommt ebenfalls ein eigenes Theme zum Einsatz, aber ein äusserst minimalistisches. Die Webseite ist ein one pager im wahrsten Sinne des Wortes, dank HTML-Minifizierung aber trotzdem sehr schlank. (Die .woff-Schrift Bitter, die ich mit ausliefere, ist zugegebenermassen ein Luxus.) Wie man so etwas baut, möchte ich in diesem Türchen zeigen.
Liebes Tagebuch
Analog zu meinem Blog Read, Think, Write möchte ich zeigen, wie man mit Hugo eine kleine Tagebuch-Webseite erstellt. Von einer frischen Installation von Debian 12 “Bookworm” ausgehend soll zunächst einmal Hugo installiert werden:
Im Gegensatz zu den generierten Webseiten ist Hugo leider alles andere als schlank, was auf die statisch gebauten Binärdateien von Go zurückzuführen ist. Der Bloat bleibt aber lokal; der Webseitenbesucher bekommt Minimalismus ausgeliefert: ein akzeptabler Kompromiss!
Nun soll die Tagebuchseite initialisiert werden:
Dadurch wird folgender Verzeichnisbaum generiert:
Diese Verzeichniseinträge haben folgende Bedeutung:
Im Abschnitt minify wird angegeben, dass die HTML-Ausgabe verkleinert werden soll. Dadurch werden überflüssige Leerzeichen und sonstige Syntaxelemente aus dem HTML-Code entfernt, die für eine korrekte Darstellung im Browser unnötig sind. Das HTML bleibt aber standardkonform.
Metadaten sind im Abschnitt params definiert. Dies sind Angaben für die Meta-Tags author, description und keywords, die später im Template zum Einsatz kommen sollen.
Das Tagebuch wäre nun von technischer Seite her aufgesetzt. Nun soll das Layout erstellt werden.
Layout mit Go-Templates
Beim Layout handelt es sich um eine HTML-Datei, in welcher der dynamische Teil als Go-Template eingestreut wird. Die Datei wird unter layouts/index.html abgelegt:
Der Header enthält die üblichen Metadaten, welche über die .Site-Datenstruktur abgerufen werden können. Angaben wie Params.Meta.Keywords dürften anhand der Konfiguration in config.toml ziemlich einleuchtend sein.
Die CSS-Datei style.css wird zuerst “minifiziert” und dann per link-Tag eingebunden.
Der Seitentitel .Site.Title kommt sowohl für den title- als auch für den h1-Tag zum Einsatz.
Im Hauptbereich der Seite wird über die Inhaltsseiten (.Pages) iteriert. Die $page-Datenstruktur steht dann für eine einzelne Inhaltsseite, deren Inhalt als $page.Content ausgegeben werden kann. Das Markdown wurde in HTML gerendert. Die Datumsangabe wird typisch für Go formatiert: Man gibt einfach das gewünschte Format exemplarisch für den zweiten Januar 2006 an, das dann mit der Funktion time.Format anhand der Angabe $page.Params.Date dargestellt wird.
Zuunterst gibt es noch einen footer mit Copyright-Angaben. Auch hier kommt wieder eine Datumsformatierung anhand des gleichen Beispieldatums (Jahr 2006) zum Einsatz.
Eine minimalistische CSS-Datei soll unter assets/style.css zu liegen kommen:
Dadurch wird die Seite auf eine Breite von 30 “ems” begrenzt und im Blocksatz ausgerichtet.
Inhalt
Nun geht es ans Erstellen des ersten Eintrags. Hierbei ist uns Hugo behilflich:
Dadurch wird eine neue Datei unter content/hallo-welt.md erzeugt, bei welcher title (anhand des Dateinamens) und date (anhand des aktuellen Zeitstempels) bereits vorausgefüllt sind. Den Header draft: true kann man testhalber gleich auf false umstellen, damit man die Seite zu Sehen bekommt. Die Seite wird mit etwas Inhalt im Markdown-Format befüllt:
Und weil das so einfach ging, erstellen wir gleich noch den nächsten Eintrag:
Der Inhalt des zweiten Beitrags:
Mit zwei Einträgen lohnt es sich nun, das Tagebuch einmal zu rendern. Hierzu bietet Hugo einen integrierten Webserver, der sich folgendermassen starten lässt:
Die Webseite kann nun unter localhost:1313 aufgerufen werden. Auf die Anzeige verzichte ich an dieser Stelle, ihr sollt ja auch etwas zu tun haben.
Eine Seite, die unter der angegebenen Domain (siehe baseURL in config.toml) ausgeliefert werden kann, wird folgendermassen ins public-Verzeichnis generiert:
Die Generierung ist rasend schnell. Dies ist bei einer Seite mit so wenig Inhalt und einfachem Template nicht weiter verwunderlich, bei grösseren Seiten wartet man aber auch selten eine Sekunde lang auf die Ausgabe.
Nun?
Was meint ihr zu Hugo? Kommt das für euch in Frage? Ist die Template-Sprache einigermassen verständlich? Habt ihr Lust bekommen, einen kleinen Blog zu starten?
Nachtrag: Offenbar macht die Forensoftware völlig unnötig einen Link aus tagebuch.paedubucher.ch. Die Seite existiert nicht, und ich habe die URL mit tt-Tags umgeben. Warum die als Hyperlink angezeigt wird, ist mir schleierhaft.
Hinter diesem Türchen verbirgt sich Hugo: ein mächtiger und äusserst performanter Generator für statische Webseiten. Der Name dürfte einerseits an die Programmiersprache Go erinnern, in der er implementiert ist. (Go macht es einfach, Aufgaben zu parallelisieren, was wohl ein wichtiger Faktor für die ausserordentlich hohe Performance von Hugo sein dürfte.) Das “Hu” (wie “huge”) dürfte eine Anspielung darauf sein, das man mit Hugo riesige Seiten in nützlicher Frist generieren kann.
Themes: vorgefertigte und eigene
Zum Einstieg in Hugo wird oft empfohlen ein vorgefertigtes Theme zu wählen. Das ist für die meisten Seiten sicherlich ein guter Rat. So habe ich positive Erfahrungen mit dem äusserst mächtigen Relearn-Theme gemacht, das u.a. LaTeX-Formeln mit MathJax, Diagramme mit Mermaid und eine clientseitige JavaScript-Suche out of the box mitbringt. Ich brauche das für meine Unterrichtsmaterialien, siehe etwa die Webseite für mein Cloud-Modul.
Privat habe ich zwei Webseiten am Laufen: zum einen meine Hauptwebseite paedubucher.ch, die auf einem selber gebauten Hugo-Theme basiert. Neulich habe ich mir an einem Abend einen neuen Blog namens Read, Think, Write zusammengehackt. Hier kommt ebenfalls ein eigenes Theme zum Einsatz, aber ein äusserst minimalistisches. Die Webseite ist ein one pager im wahrsten Sinne des Wortes, dank HTML-Minifizierung aber trotzdem sehr schlank. (Die .woff-Schrift Bitter, die ich mit ausliefere, ist zugegebenermassen ein Luxus.) Wie man so etwas baut, möchte ich in diesem Türchen zeigen.
Liebes Tagebuch
Analog zu meinem Blog Read, Think, Write möchte ich zeigen, wie man mit Hugo eine kleine Tagebuch-Webseite erstellt. Von einer frischen Installation von Debian 12 “Bookworm” ausgehend soll zunächst einmal Hugo installiert werden:
Code: Alles auswählen
$ sudo apt install -y hugo
Nun soll die Tagebuchseite initialisiert werden:
Code: Alles auswählen
$ hugo new site tagebuch
Code: Alles auswählen
$ tree tagebuch
tagebuch/
├── archetypes
│ └── default.md
├── assets
├── config.toml
├── content
├── data
├── layouts
├── public
├── static
└── themes
- archetypes: Dieses Verzeichnis enthält Vorlagen für neue Seiten. Das Template default.md enthält einen YAML-Header für den Titel und das Tagesdatum. Das werden wir gleich in Aktion sehen.
- assets: Hier kommen Dateien hinein, die von Hugo verarbeitet (z.B. “minifiziert”) werden, wie z.B. CSS- oder JavaScript-Quellcodedateien.
- config.toml: Hierbei handelt es sich um die Konfigurationsdatei für die ganze Webseite, die auf der Hugo-Webseite sehr detailliert dokumentiert ist. Diese liegt standardmässig im TOML-Format vor. Wichtige Einstellungen sind die baseURL der Webseite, die ich auf https://tagebuch.paedubucher.ch ändere; der languageCode, den ich gut schweizerisch auf de-ch umstelle; und der Titel, den ich auf Mein Tagebuch ändere. Weitere Ergänzungen finden sich unten.
- content ist das Verzeichnis, welche die Seiteninhalte als Markdown-Dateien enthält. Dieses Verzeichnis werden wir gleich mit Inhalt befüllen.
- data enthält Dateien, die in den Hugo-Templates angesprochen werden können. Ich selber habe das noch nie verwendet, doch die Dokumentation gibt Auskunft darüber.
- layouts enthält eigene Templates um die Seite zu generieren. Es kommen die selbst für Go-Programmierer etwas gewöhnungsbedürftigen Go-Templates zum Einsatz.
- public ist das Verzeichnis, in welches das generierte HTML mit den Zusatzdateien (CSS, JavaScript) landet. Dieses Verzeichnis kann man von einem Webserver ausliefern lassen. Ich selber schliesse es aus meinem Git-Repository aus; es gibt aber Leute, die auch das generierte HTML in die Versionskontrolle aufnehmen.
- static ist für statische Dateien wie Bilder oder Schriftarten gedacht, die 1:1 (ohne weiteren Verarbeitungsschritt durch Hugo) ausgeliefert werden.
- themes kann mehrere Themes enthalten, die dann über die Konfiguration aktiviert werden. Wir werden in diesem Beispiel keine Themes verwenden.
Code: Alles auswählen
baseURL = 'https://tagebuch.paedubucher.ch'
languageCode = 'de-ch'
title = 'Mein Tagebuch'
[minify]
minifyOutput = true
[params]
author.name = "Patrick Bucher"
meta.description = "Mein Tagebuch"
meta.keywords = "Tagebuch, Blog, Persönliches"
Metadaten sind im Abschnitt params definiert. Dies sind Angaben für die Meta-Tags author, description und keywords, die später im Template zum Einsatz kommen sollen.
Das Tagebuch wäre nun von technischer Seite her aufgesetzt. Nun soll das Layout erstellt werden.
Layout mit Go-Templates
Beim Layout handelt es sich um eine HTML-Datei, in welcher der dynamische Teil als Go-Template eingestreut wird. Die Datei wird unter layouts/index.html abgelegt:
Code: Alles auswählen
<!doctype html>
<html lang="de-ch">
<head>
<meta charset="UTF-8" />
<meta name="author" content="{{ .Site.Params.Author.Name }}" />
<meta name="description" content="{{ .Site.Params.Meta.Description }}" />
<meta name="keywords" content="{{ .Site.Params.Meta.Keywords }}" />
{{ $css := resources.Get "style.css" | minify }}
<link rel="stylesheet" type="text/css" href="{{ $css.RelPermalink }}" />
<title>{{ .Site.Title }}</title>
</head>
<body>
<header>
<h1>{{ .Site.Title }}</h1>
</header>
<main>
{{ range $_, $page := .Pages }}
<article>
<h2>{{ $page.Params.Title }}</h2>
<p><em>{{ time.Format "02.01.2006" $page.Params.Date }}</em></p>
{{ $page.Content }}
<hr />
</article>
{{ end }}
</main>
<footer>
<p>© {{ .Site.Lastmod.Format "2006" }} by {{ .Site.Params.Author.Name }}.</p>
</footer>
</body>
</html>
Die CSS-Datei style.css wird zuerst “minifiziert” und dann per link-Tag eingebunden.
Der Seitentitel .Site.Title kommt sowohl für den title- als auch für den h1-Tag zum Einsatz.
Im Hauptbereich der Seite wird über die Inhaltsseiten (.Pages) iteriert. Die $page-Datenstruktur steht dann für eine einzelne Inhaltsseite, deren Inhalt als $page.Content ausgegeben werden kann. Das Markdown wurde in HTML gerendert. Die Datumsangabe wird typisch für Go formatiert: Man gibt einfach das gewünschte Format exemplarisch für den zweiten Januar 2006 an, das dann mit der Funktion time.Format anhand der Angabe $page.Params.Date dargestellt wird.
Zuunterst gibt es noch einen footer mit Copyright-Angaben. Auch hier kommt wieder eine Datumsformatierung anhand des gleichen Beispieldatums (Jahr 2006) zum Einsatz.
Eine minimalistische CSS-Datei soll unter assets/style.css zu liegen kommen:
Code: Alles auswählen
body {
margin: 0 auto;
max-width: 30em;
}
p {
text-align: justify;
}
Inhalt
Nun geht es ans Erstellen des ersten Eintrags. Hierbei ist uns Hugo behilflich:
Code: Alles auswählen
$ hugo new content/hallo-welt.md
Code: Alles auswählen
---
title: "Hallo Welt"
date: 2024-12-10T20:49:25+01:00
draft: false
---
Liebes Tagebuch. Es freut mich, mit dir bekannt zu werden. Ich möchte dich in Zukunft täglich pflegen und dich mit Inhalt füllen. Dank Hugo geht das sehr kombortabel und W3C-Standardkonform obendrein!
Code: Alles auswählen
$ hugo new content/dfde-adventskalender.md
Code: Alles auswählen
---
title: "DFDE-Adventskalender"
date: 2024-12-10T20:54:18+01:00
draft: false
---
Liebes Tagebuch. Ich sollte wirklich an meinem Zeitmanagement arbeiten. Es ist Dienstagabend kurz vor 21 Uhr, und ich bin nun seit ungefähr einer Stunde daran, meinen Türchen für morgen zu schreiben. Damit hätte ich schon [im Oktober](https://debianforum.de/forum/viewtopic.php?t=190688) anfangen sollen! Aber letztes Jahr ging ja auch alles gut.
Code: Alles auswählen
$ hugo server
Eine Seite, die unter der angegebenen Domain (siehe baseURL in config.toml) ausgeliefert werden kann, wird folgendermassen ins public-Verzeichnis generiert:
Code: Alles auswählen
$ hugo
Nun?
Was meint ihr zu Hugo? Kommt das für euch in Frage? Ist die Template-Sprache einigermassen verständlich? Habt ihr Lust bekommen, einen kleinen Blog zu starten?
Nachtrag: Offenbar macht die Forensoftware völlig unnötig einen Link aus tagebuch.paedubucher.ch. Die Seite existiert nicht, und ich habe die URL mit tt-Tags umgeben. Warum die als Hyperlink angezeigt wird, ist mir schleierhaft.