htmltest-Konfiguration für Hugo
Inhalt
Nun bin ich mit dem Umzug meiner Website zu Hugo fast fertig. Ich musste mehrere Anpassungen in der Frontmatter jedes Artikel vornehmen, damit sie in Hugo ähnliche Funktionen aufweisen wie zuvor mit Jekyll. Es ergaben sich einige Änderungen in der Ordnerstruktur teils durch die Migration, teils auch durch meine Erfahrungen als Autor, sodass auf dem Weg einige Links in praktisch jedem meiner Artikel zu überarbeiten waren. Inzwischen habe ich fast 340 davon, wenn man die Übersetzungen mitzählt.
Der schieren Masse der Links komme ich ohne weitere Hilfsmittel nicht bei. Also benötige ich Werkzeug.
htmltest#
Htmltest ist ein Hilfsprogramm, das HTML-Dateien nach Problemen durchsuchen kann. Unter anderem spürt es defekte Links auf. Ich installiere es per
# Red Hat-based Linux package manager install command
sudo dnf install htmltest
und wende es auf die von Hugo “gebauten” HTMl-Dateien im /public-Verzeichnis an:
htmltest public/
# [...]
✘✘✘ failed in 2.890119823s
2612 errors in 337 documents
Das sind aber ganz schön viele Fehler! Die Darreichungsform erscheint mir außerdem ziemlich unübersichtlich, siehe Bild.

Ausgabe in Datei umleiten#
Folglich tue ich mich erstmal ziemlich schwer mit diesem Werkzeug. Ich hatte angenommen, dass mir ein paar Links kaputtgegangen sind und nicht mit tausenden Fehlern gerechnet. Also fiel ich dem typischen not-invented-here Syndrom anheim und programmierte selbst ein Werkzeug in python, welches sich im Nachhinein als nicht gut genug entpuppte. Kurzgesagt:
Htmltest ist ein tolles und unglaublich schnelles Werkzeug. Wenn man dessen Ausgabe leserlich macht und richtig deutet, kann man damit ziemlich glücklich werden. Mit ein bisschen Herumprobieren gelange ich zu folgendem Befehl:
htmltest public/ 2>&1 | ansi2html > htmltest-output.html
Bedeutung: “Führe htmltest im
/public/-Ordner aus. Leite Fehler ausstderrin die Ausgabestdoutum. Reiche die Ausgabe an ansi2html1 weiter. Schreibe dessen Ausgabe in eine Datei namenshtmltest-output.html.

Das sieht doch so schon viel besser aus!
Fehlerkategorien#
Die mit htmltest gefundene Fehler lassen sich für meine Zwecke in ein paar wenige Kategorien sortieren:
- Hugo-intern bedingte Fehler wie durch
livereload.jsverursachtetarget does not exist-Meldungen. - Unvollständige Links, die zwar in der Praxis funktionieren, aber
href lacks trailing slash-Fehler erzeugen. Diese Art Fehler machen bei mir den Löwenanteil der berichteten Probleme aus. - Lookup-Fehler
GET <src> [...] failure in name resolution, bei fehlender Verbindung, unzureichenden Rechten, aktiver Bot-Abwehr oder wenn der Zielserver offline ist - Harte, durch defekte Links erzeugte
target does not exist-Fehler. Genau diese wollte ich eigentlich beheben.
Das Log bereinigen#
Wie bekomme ich nun nur noch Fehler der vierten Kategorie angezeigt? Durch ein paar Änderungen in den Werkeugen und die Beseitigung der Trailing-Slash-Fehler.
Fehler der Kategorie 1, die durch Hugos nützliche livereload-Funktion hervorgerufen werden, sehen so aus:
target does not exist --- en/tags/tools/index.html --> /livereload.js?mindelay=10&v=2&port=1313&path=livereload
LiveReload ist diejenige Funktion, die mir ständiges F5-Tippen im Browserfenster erspart, wenn Hugo eine meiner Änderungen nach dem Speichern der Markdown-Datei baut. Für den Test kann ich es jedoch kurz deaktivieren. Die folgende Lösung reduziert die Anzahl erzeugter Fehler um eins pro html-Seite.
hugo server --disableLiveReload
Lookup-Fehler der Kategorie 3 vermeide ich durch einen Fokus auf interne Links worüber ich die vollständige Kontrolle habe. Hierbei hilft mir der Parameter -s, --skip-external in htmltest:
htmltest -s public/ 2>&1 | ansi2html > htmltest-output.html
# [...]
✘✘✘ failed in 494.7678ms
446 errors in 337 documents
Tote externe Links kann ich zu einem späteren Zeitpunkt beheben; nun will ich erstmal die durch die Migration entstandenen Probleme lösen.
“Missing trailing slash”: Fehlerbehebung per Markup#
Mit den vielen href lacks trailing slash-Fehlern tue ich mich lange zeit schwer, müsste ich doch an fast jeden Markdown-Link in jedem Artikel ein / anfügen. Zum Glück finde ich eine Lösung in meinem Markup render-link.html:
{{- /* /layouts/_markup/render-link.html */ -}}
{{- $url := .Destination | safeURL -}}
{{- $is_external := or (strings.HasPrefix $url "http://") (strings.HasPrefix $url "https://") -}}
{{- $is_anchor := strings.HasPrefix $url "#" -}}
{{- $is_asset := strings.HasPrefix $url "/assets/" -}}
[...]
{{- /* Add / to internal paths that have no file extension */ -}}
{{- if and (not $is_external) (not $is_anchor) (not $is_asset) -}}
{{- $parsed := urls.Parse $url -}}
{{- if and $parsed (not (strings.HasSuffix $parsed.Path "/")) (eq (path.Ext $parsed.Path) "") -}}
{{- $url = printf "%s/" $url -}}
{{- end -}}
{{- end -}}
[...]
Bedeutung: Interne Links, die weder auf Überschriften
is_anchornoch Mediendateienis_assetverweisen, bekommen genau dann ein/angehangen, wenn sie eine korrekte Syntax aufweisenparsedund noch keinen Slash am Ende der URL vorweisen können.
Dies löst 95% der Fehlermeldungen durch weniger hässliches html. Die restlichen 5% hole ich mir durch Anhängen von ein paar Slashes in der Hugo-Konfiguration. Beispiele:
# hugo.yml
url: "/en/" # /en -> /en/
logoHomeLink: "/en/" # /en -> /en/
Fertig! Übrig bleiben nur noch harte, interne Fehler.
htmltest -s public/ 2>&1 | ansi2html > htmltest-output.html
# [...]
✘✘✘ failed in 359.28ms
102 errors in 84 documents
Manuelles Suchen und Beheben#
Was nun folgt ist reine Fleißarbeit. Ich öffne das Zieldokument (also jenes, auf welches per Link verwiesen wird) und schaue mir an, ob zum Beispiel Überschriftenlinks zwischen verschiedenen Sprachen uneinheitlich sind. Falls ja, füge ich individuelle Anchor-Links an die Überschrift an.
### Überschrift {#heading3}
Falls in der Zieldatei alles paletti ist, öffne ich zusätzlich alle Quelldateien, die den defekten Link verwenden. Dort korrigiere ich den Link manuell. In den meisten Fällen befindet sich die Zieldatei inzwischen in einem anderen Ordner, oder der Sprachpräfix ist falsch gesetzt.
Das Ergebnis#
Nach ein paar Stunden anstrengender und dröger Handrbeit werde ich belohnt:
htmltest public/ -s 2>&1
Skipping the checking of external links.
htmltest started at 10:51:23 on public
========================================================================
✔✔✔ passed in 238.970354ms
tested 338 documents
Bald kann ich mit meiner neuen alten Seite online gehen!
ansi2html bzw. colorized-logs ist ein Hilfsprogramm, welches Konsolenausgabe inkl. Formatierung und Textfarben in
htmlumwandelt. ↩︎