<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hugo on Schallberts Blog</title><link>https://blog.schallbert.de/tags/hugo/</link><description>Recent content in Hugo on Schallberts Blog</description><generator>Hugo</generator><language>de</language><lastBuildDate>Wed, 30 Sep 2026</lastBuildDate><atom:link href="https://blog.schallbert.de/tags/hugo/index.xml" rel="self" type="application/rss+xml"/><item><title>Hugo vs. Jekyll: Benchmark</title><link>https://blog.schallbert.de/hugo-versus-jekyll-benchmark/</link><pubDate>Wed, 30 Sep 2026</pubDate><author>Schallbert</author><guid>https://blog.schallbert.de/hugo-versus-jekyll-benchmark/</guid><description type="html">&#10; &lt;img src="https://blog.schallbert.de/assets/images/posts/2026-09-30-hugo-jekyll-benchmark.avif"&#10; class="post-cover"&#10; alt="Image: The result of a page load time and page bandwidth test in the browser. There is a cake diagram, showing the majority of data transfer accounting for images, followed by css with a fifth. HTML content is the smallest part with a tenth or less."&#10; title="Hugo vs. Jekyll: Benchmark" /&gt;&#10;&lt;h2 id="ladezeiten"&gt;Ladezeiten&lt;/h2&gt;&#10;&lt;p&gt;Schauen wir uns mal an, wie meine Seite mit Jekyll gegenüber Hugo lädt. Hierfür öffne ich die &lt;em&gt;Entwickleroptionen (F12)&lt;/em&gt; in &lt;a href="https://www.firefox.com/de/?redirect_source=mozilla-org" target="_blank" rel="noopener noreferrer" class="external-link"&gt;meinem Browser&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt;, wähle das &lt;em&gt;Network&lt;/em&gt;-Tab an und klicke dort auf &lt;em&gt;All&lt;/em&gt;. Anschließend lade ich die Seite neu.&lt;/p&gt;&#10;&lt;p&gt;Dabei entsteht die folgende Auflistung:&lt;/p&gt;&#10;&lt;figure class="media-frame media-frame--center"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/migrating-hugo-to-jekyll/blog_schallbert-transfersize-loadtime-hugo.avif" alt="Image: A snapshot of my browser window with the blog&amp;#39;s landing page opened. Developer options are activated, and the lower part of the image shows a table with the individual page content files, their size, and contribution to the load time. For hugo, it transfers a total of 189kB in 175ms."&gt;&lt;figcaption class="media-caption"&gt;&#10; &lt;span class="caption-text"&gt;Im Bild unten: Ladezeit meiner Landing Page mit Hugo&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;p&gt;Zu erwähnen ist, dass ich hier eigentlich gar nicht Jekyll mit Hugo vergleiche, sondern lediglich deren Ausgabe und daher die gewählten Themes maßgeblich für Größe und Ladezeit verantwortlich sind. Also vergleiche ich praktisch das &lt;em&gt;minimalmistakes theme in Jekyll&lt;/em&gt; mit dem &lt;em&gt;terminal theme in Hugo&lt;/em&gt;. Hugo ist in diesem Falle etwa &lt;code&gt;10%&lt;/code&gt; schneller als Jekyll.&lt;/p&gt;&#10;&lt;figure class="media-frame media-frame--center"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/migrating-hugo-to-jekyll/blog_schallbert-transfersize-loadtime-jekyll.avif" alt="Image: A snapshot of my browser window with the blog&amp;#39;s landing page opened. Developer options are activated, and the lower part of the image shows a table with the individual page content files, their size, and contribution to the load time. For jekyll, it transfers a total of 328kB in 306ms."&gt;&lt;figcaption class="media-caption"&gt;&#10; &lt;span class="caption-text"&gt;Im Bild unten: Ladezeit meiner Landing Page mit Jekyll&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;h2 id="größe"&gt;Größe&lt;/h2&gt;&#10;&lt;figure class="media-frame media-frame--right"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/migrating-hugo-to-jekyll/blog_schallbert-landing-performance-analysis-terminaltheme.avif" alt="Image: A cake diagram as the output of firefox&amp;#39;s performance analysis tool in developer options. Analyzing the hugo&amp;#39;s terminal theme on a typical blog post of mine, images make up for three quarters of total transferred size. The last quarter is largely taken by css, and just 12kB html at a total size of 165kB."&gt;&lt;/figure&gt;&#10;&lt;p&gt;Ein anderes Diagramm erhalte ich, wenn ich ganz unten links auf die Stoppuhr klicke und damit eine &lt;a href="https://firefox-source-docs.mozilla.org/devtools-user/network_monitor/performance_analysis/" target="_blank" rel="noopener noreferrer" class="external-link"&gt;performance analysis&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; ausführe. Die Kuchendiagramme zeigen für meine Implementierung in Jekyll den größten Anteil in Bildern, gefolgt von CSS und JS. In Hugo geht JS gegen null, und auch der Anteil von CSS ist geschrumpft.&lt;/p&gt;&#10;&lt;p&gt;Die folgende Tabelle zeigt ein paar meiner Seiten im direkten Vergleich. Allerdings ist die Übersicht mit Vorsicht zu genießen: Die Werte ändern sich schon mal, wenn ich neu lade (auch mit ausgeschaltetem Cache). Gerade bei eingebundenen Inhalten Dritter wie meinen Videos kommen hier teils stark unterschiedliche Werte heraus. Insgesamt habe ich mit Hugo und Terminal deutliche Optimierungen vorliegen.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Item&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;minimal-mistakes&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;terminal-schallbert&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Jekyll&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Hugo&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;transferred&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;[kB]&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Diff [%]&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;time&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;[ms]&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Diff [%]&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Landing&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;163.47&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;98.68&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;-39&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;30&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;30&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;0&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Post&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;2861&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;1767&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;-38&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;340&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;270&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;-20&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;List page&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;1507&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;140&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;-90&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;30&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;30&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;0&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Manuell implementiert in Hugo hatte ich das bedingte Laden von Katex nur auf Seiten, wo mathematische Ausdrücke auftauchen (das spart oftmals &lt;code&gt;90kB min.css&lt;/code&gt;).&lt;/li&gt;&#10;&lt;li&gt;Mit Hugo habe ich kleinere CSS-Dateien. Es wird nur geladen, was ich auch wirklich verwende. Es gibt kaum noch Code, der nicht angefahren wird.&lt;/li&gt;&#10;&lt;li&gt;Automatisch in Hugo sind Medien-Vorschaudateien von den hochauflösenden Dateien abgeleitet und per Bildprozessor auf die Darstellungsverhältnisse im gebauten Zustand platzoptimiert. Diese Optimierung spart bei vielen, klein dargestellten Bildern eine Menge Bandbreite.&lt;/li&gt;&#10;&lt;li&gt;Das &lt;em&gt;Terminal&lt;/em&gt;-Theme zeigt anders als &lt;em&gt;minimalmistakes&lt;/em&gt; keine Kärtchen für &amp;ldquo;weitere Posts&amp;rdquo; an. Dies spart die Übertragung von vier Vorschaubildern.&lt;/li&gt;&#10;&lt;li&gt;In Hugo habe ich fast gar keine Javascript-Inhalte mehr - eines der Ziele, das ich mir gesteckt hatte.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="auslieferungcontinuous-deployment"&gt;Auslieferung/Continuous Deployment&lt;/h2&gt;&#10;&lt;p&gt;Für Jekyll gestaltete sich Bauen und Ausliefern in Gitea etwas hakelig: erst mit einem &lt;a href="https://blog.schallbert.de/gitea-action-runner-jekyll-dockerimage/"&gt;Jekyll-Dockerimage&lt;/a&gt; war ich in der Lage, &lt;a href="https://blog.schallbert.de/gitea-action-runner-native-jekyll/"&gt;ruby richtig aufzusetzen&lt;/a&gt;. Damit und weil ich meinen Actions nicht erlaube zu cachen dauert das Bauen ziemlich lang: Erst den aktuellen Docker-Container ziehen, ruby und jekyll updaten, gems installieren, die Quelldateien auschecken, anschließend bauen und ausliefern - hier vergehen selbst unter optimalen Bedingungen mehr als &lt;code&gt;90 Sekunden&lt;/code&gt;, bis ein neuer Artikel live ist.&lt;/p&gt;&#10;&lt;figure class="media-frame media-frame--center"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/posts/2026-09-30-CD-build-with-jekyll.avif" alt="Image: Gitea dashboard in the Actions tab. We see three successful workflow runs with a hugo full build &amp;amp; deploy of my site, taking 122sec, 138sec, and 160sec."&gt;&lt;/figure&gt;&#10;&lt;p&gt;Für Hugo geht der ganze Prozess dank schnellerer Bauzeiten und vorgefertigter Container (siehe dazu mein Artikel zum Thema &lt;a href="https://blog.schallbert.de/build-deploy-hugo-with-actions-docker-caddy/"&gt;Continuous Deployment Pipeline mit Hugo in Docker&lt;/a&gt;) viel schneller vonstatten.&lt;/p&gt;&#10;&lt;figure class="media-frame media-frame--center"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/posts/2026-09-30-CD-build-with-hugo.avif" alt="Image: Gitea dashboard in the Actions tab. We see three successful workflow runs with a hugo full build &amp;amp; deploy of my site, taking 12sec, 9sec, and 21sec."&gt;&lt;/figure&gt;&#10;&lt;p&gt;Selbst im ungünstigsten Fall (siehe Build unten), z.B. nach einem Neustart des Runners nach Update und einer Änderung im Docker-Repository für meinen Hugo Container, bleibe ich weit unter &lt;code&gt;30 Sekunden&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="komplexität"&gt;Komplexität&lt;/h2&gt;&#10;&lt;p&gt;Ganz klar: Hugo ist hier im Vergleich zu Jekyll unschlagbar.&lt;/p&gt;&#10;&lt;p&gt;Da Themes in Hugo steckbare Module sind, benötigen sie keinen Abhängigkeitsbaum in Form von Gems wie bei Jekyll zum Nachladen und installieren. Entsprechend kann hier viel weniger kaputt gehen. Für mich lokal verringert sich die Bauzeit für einen &amp;ldquo;full build&amp;rdquo; (zweisprachig) um &lt;strong&gt;75%&lt;/strong&gt; und auch das automatische Bauen bei Veränderung meiner Markdown-Dateien ist sowohl &lt;strong&gt;5x&lt;/strong&gt; schneller als auch aussagekräftiger: Wenn ich in Jekyll nämlich &amp;ldquo;incremental build&amp;rdquo; einschalte, dann gibt es keine aktualisieren Paginator-Seiten mehr - sprich Listenansichten und Übersichtsseiten werden nicht mit gebaut.&lt;/p&gt;&#10;&lt;p&gt;Auf der anderen Seite kann ich in Jekyll sehr flexibel und feingranular selbst eingreifen, eigene Gems entwerfen und recht einfach besondere Gimmicks für meine Seite herstellen wie ein mitscrollendes Inhaltsverzeichnis. Jenes vermisse ich in Hugo etwas.&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;Fazit: Für die tagtägliche Benutzbarkeit gefällt mir Hugo ganz klar besser als Jekyll. - &lt;em&gt;schallbert, Sep-2026&lt;/em&gt;&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;</description></item><item><title>Continuous Deployment für Hugo</title><link>https://blog.schallbert.de/build-deploy-hugo-with-actions-docker-caddy/</link><pubDate>Tue, 15 Sep 2026</pubDate><author>Schallbert</author><guid>https://blog.schallbert.de/build-deploy-hugo-with-actions-docker-caddy/</guid><description type="html">&#10; &lt;img src="https://blog.schallbert.de/assets/images/posts/2026-09-15-dind-action-setup-cover.avif"&#10; class="post-cover"&#10; alt="Image: A hand-drawn Docker container layout image. It shows the runner container on a VM with a debian OS, which starts an action container, which in turn runs the hugo deployment container."&#10; title="Continuous Deployment für Hugo" /&gt;&#10;&lt;p&gt;Gerade habe ich meine Website &lt;a href="https://blog.schallbert.de/projects/migrating-jekyll-to-hugo/"&gt;von Hugo auf Jekyll umgezogen&lt;/a&gt;. Nun will ich sie automatisiert bauen und Änderungen ausrollen, sobald ich einen Artikel fertiggestellt und ihn per &lt;code&gt;git push&lt;/code&gt; und anschließendem Merge in &lt;code&gt;main&lt;/code&gt; auf meine &lt;a href="https://blog.schallbert.de/projects/move-blog-to-own-server/"&gt;Gitea-Instanz&lt;/a&gt; geschoben habe.&lt;/p&gt;&#10;&lt;h2 id="die-befehlskette"&gt;Die Befehlskette&lt;/h2&gt;&#10;&lt;p&gt;Ich habe einen &lt;a href="https://en.wikipedia.org/wiki/Virtual_private_server" target="_blank" rel="noopener noreferrer" class="external-link"&gt;VPS&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; gemietet, auf dem ich alle Anwendungen in Docker laufen lasse. Die Aufgabe ist nun, einen &lt;a href="https://docs.github.com/en/actions/concepts/workflows-and-actions/workflows" target="_blank" rel="noopener noreferrer" class="external-link"&gt;workflow&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; in Gitea zu bauen (&amp;ldquo;Actions&amp;rdquo;), welcher das Update im Repository auscheckt, es &lt;a href="https://hub.docker.com/r/hugomods/hugo" target="_blank" rel="noopener noreferrer" class="external-link"&gt;hugo&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; zur Verfügung stellt, dort die HTML-Seiten erzeugen lässt, und sie anschließend so auf der Festplatte ablegt, dass mein Webserver die Dateien einlesen und ausliefern kann.&lt;/p&gt;&#10;&lt;h3 id="erfahrungswerte"&gt;Erfahrungswerte&lt;/h3&gt;&#10;&lt;p&gt;Das alles hatte ich für meine &lt;a href="https://blog.schallbert.de/gitea-action-runner-jekyll-dockerimage/"&gt;Website in Jekyll bauen und ausrollen&lt;/a&gt; können, daher kann ich auf ein paar Erfahrungswerte zurückgreifen.&lt;/p&gt;&#10;&lt;p&gt;Üblicherweise nutzt man dafür standardisierte Aktionen. Ich vereinfache mal stark und liste nur die Hauptdarsteller auf, ohne in fiese Details wie Rechtevergabe (darf Hugo in diesen Ordner schreiben? Hat der hugo-user genügend Rechte?) tiefer einzugehen:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://github.com/actions/checkout" target="_blank" rel="noopener noreferrer" class="external-link"&gt;checkout&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; stellt einen gewünschten Stand des Quellrepository bereit&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://github.com/peaceiris/actions-hugo" target="_blank" rel="noopener noreferrer" class="external-link"&gt;actions-hugo&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; installiert hugo in der virtuellen Maschine der Action, sodass die Website gebaut werden kann&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://github.com/actions/upload-artifact" target="_blank" rel="noopener noreferrer" class="external-link"&gt;upload-artifact&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; lädt die von hugo erstellte Seite auf den Webserver hoch&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Da ich jedoch auf ein- und derselben Maschine in Docker unterwegs bin, kann ich mir das aufwendige Einwählen auf dem Webserver &amp;ldquo;von außen&amp;rdquo; sparen. Daher gehe ich einen anderen Weg.&lt;/p&gt;&#10;&lt;h2 id="docker-shared-volumes"&gt;Docker shared Volumes&lt;/h2&gt;&#10;&lt;p&gt;Ich kann meiner &lt;em&gt;Caddy&lt;/em&gt;-Anwendung direkt die gebauten Dateien zur Verfügung stellen, wenn ich das von ihr gelesene Volume bis in die Action weiterreiche.&lt;/p&gt;&#10;&lt;h3 id="aufgepasst-action-volume--hugo-volume"&gt;Aufgepasst: Action volume != Hugo volume&lt;/h3&gt;&#10;&lt;p&gt;Doch das funktioniert mit &lt;em&gt;actions-hugo&lt;/em&gt; nicht: Sie ist selbst kein Docker container, kann also keine Volumes einbinden. Sie baut zwar die Webseite fertig; sobald die Aktion jedoch durchgelaufen ist, reißt sie die Artefakte mit ins Nirvana.&lt;/p&gt;&#10;&lt;p&gt;Ich benötige also eine hugo-Runtime, die selbst in einem Docker-Container läuft - ganz nach dem &lt;a href="https://blog.schallbert.de/gitea-act-runner-dind/"&gt;DinD-Ansatz&lt;/a&gt;. Diesem kann ich dann das von Caddy verwendete Volume mit Schreibzugriff durchreichen.&lt;/p&gt;&#10;&lt;h2 id="der-workflow"&gt;Der Workflow&lt;/h2&gt;&#10;&lt;p&gt;Doch welchen Docker-Container soll ich nehmen?&lt;/p&gt;&#10;&lt;p&gt;Man stelle sich nun mehrere Stunden der Recherche und viele Fehlversuche beim Einrichten des Workflows auf meinem Server vor.&#10;&lt;figure class="media-frame media-frame--center"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/posts/2026-09-15-hugo-unsuccessful-workflow-run-history.avif" alt="Image: Giteas workflow run overview. We see many actions at the bottom with a red &amp;#39;build failed&amp;#39;-flag. Only the top two workflow runs were successful."&gt;&lt;/figure&gt;&lt;/p&gt;&#10;&lt;p&gt;Folgendes ergab sich aus meinen Untersuchungen:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;checkout@v4&lt;/code&gt; benötigt &lt;a href="https://nodejs.org/en" target="_blank" rel="noopener noreferrer" class="external-link"&gt;node.js&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt;, und zwar mindestens Version &lt;em&gt;node:18&lt;/em&gt;. Der Docker-Container (und das darunterliegende Betriebssystem des Runners!) müssen es installiert haben bzw. unterstützen.&lt;/li&gt;&#10;&lt;li&gt;Die Action benötigt &lt;code&gt;git&lt;/code&gt;. Auch dies muss der Docker-container idealerweise bereits mitbringen.&lt;/li&gt;&#10;&lt;li&gt;Hugo braucht &lt;code&gt;go&lt;/code&gt;. Klingt soweit logisch.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="runner-betriebssystem-anpassen"&gt;Runner-Betriebssystem anpassen&lt;/h3&gt;&#10;&lt;p&gt;Mein Runner aus dem Jahr 2023 ist inzwischen in die Tage gekommen. Er basiert auf &lt;code&gt;node:16-bullseye&lt;/code&gt;, eine Debian-basierte VM. Ich probiere etwas mit &lt;a href="https://hub.docker.com/_/node?tag=lts-alpine3.24" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Alpine&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; herum, doch diese Installation ist zu minimal für meine Zwecke und lässt mich mit vielen manuellen Anpassungen zurück. Schließlich muss der Runner noch andere Workflows ausführen als diesen hier. Ich entscheide mich letztendlich, bei Debian zu bleiben und nur die Node-Version hochzuziehen. Die Umsetzung in der Runner-Konfiguration sieht dann wie folgt aus:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# /gitea/runner/config.yml&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# The labels of a runner are used to determine which jobs the runner can run, and how to run them.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Like: [&amp;#34;macos-arm64:host&amp;#34;, &amp;#34;ubuntu-latest:docker://node:16-bullseye&amp;#34;, &amp;#34;ubuntu-22.04:docker://node:16-bullseye&amp;#34;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# If it&amp;#39;s empty when registering, it will ask for inputting labels.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# If it&amp;#39;s empty when execute `deamon`, will use labels in `.runner` file.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;labels&lt;/span&gt;: [&lt;span style="color:#ae81ff"&gt;ubuntu-latest:docker://node:20-bullseye]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Anschließend muss der Runner-Container neu gestartet werden. Idealerweise bootet man Gitea gleich mit durch, dann funktioniert das Registrieren des Runners auch zuverlässig.&lt;/p&gt;&#10;&lt;h3 id="das-workflow-script-schreiben"&gt;Das Workflow-Script schreiben&lt;/h3&gt;&#10;&lt;p&gt;Um die oben beschriebenen Abhängigkeiten abzudecken entscheide ich mich für einen &amp;ldquo;batteries included&amp;rdquo;-Ansatz. So kann ich die Bausteine einfach ohne manuelle Anpassungen zusammenstecken und vertraue auf langfristige Wartung und Pflege der Container, da sie wirklich sehr häufig verwendet werden (Größenordnung mehrere Millionen Pulls). &lt;a href="https://docker.hugomods.com/docs/tags/" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Diese Webseite&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; half mir sehr bei der Auswahl.&lt;/p&gt;&#10;&lt;aside class="update-box update-box--note" role="note"&gt;&#10; &lt;span class="update-box__icon" aria-hidden="true"&gt;&#10; ℹ️&#10; &lt;/span&gt;&#10;&#10; &lt;div class="update-box__body"&gt;&#10; &lt;div class="update-box__heading"&gt;&#10; &lt;strong class="update-box__title"&gt;&#10; &#10; Update: Runner mit Alpine3.24 ist doch möglich.&#10; &#10; &lt;/strong&gt;&#10;&#10; &lt;time datetime="2026-09-22T00:00:00Z"&gt;&#10; 22. Sept. 2026&#10; &lt;/time&gt;&#10; &#10; &lt;/div&gt;&#10;&#10; &#10; &lt;div class="update-box__content"&gt;&#10; Führe ich die Action in einem Container aus wie unten beschrieben, so benötigt der Runner selbst gar kein NodeJS mehr, da der Checkout jetzt im Hugo Container selbst abläuft. Daher kann das OS des Runner wieder abgespeckt und &lt;code&gt;labels: [ubuntu-latest:docker://node:20-alpine3.24]&lt;/code&gt; verwendet werden, sofern keine andere Action einen direkten Checkout durchführen muss.&#10; &lt;/div&gt;&#10; &#10; &lt;/div&gt;&#10;&lt;/aside&gt;&#10;&lt;p&gt;Schließlich erstelle ich meinen Workflow basierend auf dem Container von &lt;a href="https://hub.docker.com/r/hugomods/hugo" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Hugomods&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# /.gitea/workflows/build-deploy-with-hugo.yml&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Deploy Hugo site&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;run-name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;${{ gitea.actor }} builds Hugo site&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;on&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;push&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;branches&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;main&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;jobs&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Build job&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;build&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;runs-on&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ubuntu-latest&lt;/span&gt; &lt;span style="color:#75715e"&gt;# this is the &amp;#34;label&amp;#34; the runner will use and map to docker target OS&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;container&lt;/span&gt;: &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;hugomods/hugo:latest&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;volumes&lt;/span&gt;: &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;/tmp/blog-artifacts:/tmp/blog-artifacts&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;steps&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: --- &lt;span style="color:#ae81ff"&gt;CHECKOUT ---&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;actions/checkout@v4&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;with&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;submodules&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;recursive &lt;/span&gt; &lt;span style="color:#75715e"&gt;# Fetches Hugo themes&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;fetch-depth&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: --- &lt;span style="color:#ae81ff"&gt;BUILD WITH HUGO ---&lt;/span&gt; &lt;span style="color:#75715e"&gt;# chown -R hugo /tmp/blog-artifacts&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: |&lt;span style="color:#e6db74"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; hugo \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --minify \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --cleanDestinationDir \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --destination /tmp/blog-artifacts&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="zielordner-bereinigen"&gt;Zielordner bereinigen&lt;/h3&gt;&#10;&lt;p&gt;Ich habe mich im obigen Beispiel für ein &amp;ldquo;direktes Deployment&amp;rdquo; entschieden, ohne Netz und doppelten Boden, und ohne, dass ich die Artefakte herumkopiere oder gar den Server neu starte. Begründung: Der Hugo-Bauprozess benötigt für Meine Seite weniger als &lt;code&gt;2000ms&lt;/code&gt;. Nur in diesem Fenster kann Caddy theoretisch eine &amp;ldquo;korrupte&amp;rdquo; Datenbank sehen und ausliefern, also nur während die Platte vom Hugo-Build-Workflow noch beschrieben wird.&lt;/p&gt;&#10;&lt;p&gt;Um Inkonsistenzen trotzdem weitgehend zu vermeiden, gebe ich Hugo die Option &lt;code&gt;--cleanDestinationDir&lt;/code&gt; mit. Damit ist das Zielverzeichnis stets sauber und Caddy wird im Zweifel keine defekte Seite anzeigen, sondern höchstens eine &lt;code&gt;404-Fehlermeldung&lt;/code&gt; erzeugen.&lt;/p&gt;&#10;&lt;h3 id="submodules"&gt;Submodules&lt;/h3&gt;&#10;&lt;p&gt;Wie in &lt;a href="https://blog.schallbert.de/projects/migrating-jekyll-to-hugo/#opportunities"&gt;meiner Projektdokumentation&lt;/a&gt; geschrieben, kann man in Hugo zum Laden von Themes sogenannte &lt;em&gt;submodules&lt;/em&gt; verwenden. Diese werden in das Projekt eingeklickt und können, wenn korrekt verlinkt, dann auch im Workflow verwendet werden:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;with&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;submodules&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;recursive &lt;/span&gt; &lt;span style="color:#75715e"&gt;# Fetches Hugo themes&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;fetch-depth&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ist alles richtig eingestellt, sollte es nicht zu folgender Fehlermeldung kommen:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# workflow action&amp;#39;s error message due to incoherent submodules&amp;#39; commit references&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# actions/checkout@v4:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Fetching submodules&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/usr/bin/git submodule sync&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/usr/bin/git -c protocol.version&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; submodule update --init --force&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Submodule &lt;span style="color:#e6db74"&gt;&amp;#39;themes/terminal&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;https://github.com/panr/hugo-theme-terminal.git&lt;span style="color:#f92672"&gt;)&lt;/span&gt; registered &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; path &lt;span style="color:#e6db74"&gt;&amp;#39;themes/terminal&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Cloning into &lt;span style="color:#e6db74"&gt;&amp;#39;/workspace/schallbert/blog-hugo/themes/terminal&amp;#39;&lt;/span&gt;...&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;fatal: remote error: upload-pack: not our ref 719505fc89332baa69bffb90cee708ff124dd143&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Fetched in submodule path &lt;span style="color:#e6db74"&gt;&amp;#39;themes/terminal&amp;#39;&lt;/span&gt;, but it did not contain 719505fc89332baa69bffb90cee708ff124dd143. Direct fetching of that commit failed.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Error: The process &lt;span style="color:#e6db74"&gt;&amp;#39;/usr/bin/git&amp;#39;&lt;/span&gt; failed with exit code &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Error: Process completed with exit code 1.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Voraussetzung ist, dass man die Submodule auch lokal richtig geladen hat:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;schallbert@machine:~ git submodule add -f https://github.com/&amp;lt;my/hugo-theme&amp;gt;.git themes/my-hugo-theme&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;schallbert@machine:~ git submodule update --init --recursive&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Die Statusabfrage darf keinen leeren String zurückgeben, sondern muss einen Commit hash beinhalten. Beispiel:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;schallbert@machine:~ git submodule status &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;44d9a1890d228745ffc300b37a7d73e940ef9fa9 themes/terminal &lt;span style="color:#f92672"&gt;(&lt;/span&gt;v4.2.5&lt;span style="color:#f92672"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Weiteres Zeugnis ist die &lt;code&gt;.gitmodules&lt;/code&gt;-Datei, welche eine Referenz auf das Theme beinhalten muss:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;schallbert@machine:➜/blog git:&lt;span style="color:#f92672"&gt;(&lt;/span&gt;main&lt;span style="color:#f92672"&gt;)&lt;/span&gt; ✗ nano .gitmodules&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;submodule &lt;span style="color:#e6db74"&gt;&amp;#34;themes/terminal&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; path &lt;span style="color:#f92672"&gt;=&lt;/span&gt; themes/terminal&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; url &lt;span style="color:#f92672"&gt;=&lt;/span&gt; https://github.com/panr/hugo-theme-terminal.git&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Funktioniert das nicht, so sind die Submodule nochmal komplett zu entfernen und antschließend wie oben beschrieben neu zu initialisieren:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git submodule deinit -f themes/&amp;lt;my-theme&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git rm -r --cached themes/&amp;lt;my-theme&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rm -rf .git/modules/themes/&amp;lt;my-theme&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="typische-probleme-hugo-versionen-und-deprecations"&gt;Typische Probleme: Hugo-Versionen und Deprecations&lt;/h2&gt;&#10;&lt;p&gt;Nun verlief die &lt;code&gt;checkout&lt;/code&gt;-Aktion erfolgreich. Doch der Build mit Hugo schlägt fehl:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;error&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;calling&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;partial&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;/workspace/schallbert/blog-hugo/layouts/_partials/head.html:37:40&amp;#34;&lt;/span&gt;: &lt;span style="color:#a6e22e"&gt;execute&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;of&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;template&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;failed&lt;/span&gt;: &lt;span style="color:#a6e22e"&gt;template&lt;/span&gt;: &lt;span style="color:#a6e22e"&gt;_partials&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;head&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;html&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;37&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;40&lt;/span&gt;: &lt;span style="color:#a6e22e"&gt;executing&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;_partials/head.html&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;at&lt;/span&gt; &amp;lt;&lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Page&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Language&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Locale&lt;/span&gt;&amp;gt;: &lt;span style="color:#a6e22e"&gt;can&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;t&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;evaluate&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;field&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Locale&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;in&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;langs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Language&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;Error&lt;/span&gt;: &lt;span style="color:#a6e22e"&gt;Process&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;completed&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;with&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;exit&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;code&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Lokal auf meiner Maschine baut Hugo erfolgreich, gibt aber ein paar Warnungen heraus:&lt;/p&gt;&#10;&lt;h3 id="änderungen-der-language-identifier-und--auswertung-ab-v0158"&gt;Änderungen der Language-identifier und -Auswertung ab v0.158&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;schallbert@machine:➜/blog git:&lt;span style="color:#f92672"&gt;(&lt;/span&gt;main&lt;span style="color:#f92672"&gt;)&lt;/span&gt; ✗ hugo build --logLevel info &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;WARN deprecated: site.Language.Locale was deprecated in Hugo v0.158.0 and will be removed in a future release. Use .Page.Language.Locale instead.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;WARN deprecated: .Language.Lang was deprecated in Hugo v0.158.0 and will be removed in a future release.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Man könnte denken, dass sich diese Fehler leicht beheben ließen. Leider können sie sich prima verstecken:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;in Submodules, die man als third-party-content lädt (z.B. in Themes). Eine projektweite Suche in der IDE hat Submodules üblicherweise ausgeblendet und liefert keine Treffer.&lt;/li&gt;&#10;&lt;li&gt;als Variablen im eigenen Code, die nur indirekt auf die alten Parameter zugreifen: Ich benutze bis dato &lt;code&gt;.Page.Site.Home.AllTranslations&lt;/code&gt;, um herauszufinden, ob ich mich auf einer gegebenen Seite in der &amp;ldquo;Hauptsprache&amp;rdquo; aufhalte. Allein schon das Scoping ist widersinnig und wird meiner Meinung nach zu Recht entfernt. Das, was ich tun will, kann nun viel einfacher erreicht werden mit &lt;code&gt;.Page.Language.IsDefault&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="submodules-auf-stand-bringen"&gt;Submodules auf Stand bringen&lt;/h3&gt;&#10;&lt;p&gt;Bei den Submodulen sehe ich zwei Lösungsansätze:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Die Maintainer anschreiben (bzw. ein Issue aufmachen), dass ihr Code gerade veraltet und sie darum bitten, ihre Themes auf Stand zu bringen.&lt;/li&gt;&#10;&lt;li&gt;Die betroffenen Dateien aus dem Submodule herauskopieren und in die eigene Ordnerstruktur integrieren. So würde das in meinem Falle betroffene &lt;code&gt;language-menu.html&lt;/code&gt; unter &lt;code&gt;/layouts/partials/language-menu.html&lt;/code&gt; eine neue Heimat finden. Dort behebe ich dann die Probleme selbst.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h3 id="eigene-lösungen-programmieren"&gt;Eigene Lösungen programmieren&lt;/h3&gt;&#10;&lt;p&gt;Macht die Fehlermeldung keine Lösung offensichtlich, so kann man sich gut an der Hugo Community orientieren. Für die &lt;a href="https://discourse.gohugo.io/t/deprecations-in-v0-158-0/56869" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Deprecatoins in v0.158&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; gibt es beispielsweise eine ausführliche Dokumentation.&lt;/p&gt;&#10;&lt;h3 id="versionen-abgleichen"&gt;Versionen abgleichen&lt;/h3&gt;&#10;&lt;figure class="media-frame media-frame--center"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/posts/2026-09-15-hugo-build-v0154-fail.avif" alt="Image: Gitea&amp;#39;s workflow run log in detail view. The build fails with an error about a field that cannot be evaluated."&gt;&lt;/figure&gt;&#10;&lt;p&gt;Hmm. Wie das Bild zeigt, verwendet mein Container das Paket &lt;code&gt;hugo extended&lt;/code&gt; von hugomods, welches die Version &lt;code&gt;v0.154.5&lt;/code&gt; bereitstellt; ich hatte einen stabilen release für die Action ausgewählt. Vergleichen wir mal mit meiner lokalen Version, die inzwischen ohne auch nur eine Warnung brav baut:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;➜ blog git:&lt;span style="color:#f92672"&gt;(&lt;/span&gt;main&lt;span style="color:#f92672"&gt;)&lt;/span&gt; ✗ hugo version&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hugo v0.162.1+extended linux/amd64 &#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Der Klassiker: Es gibt eine Änderung ab &lt;code&gt;v0.158&lt;/code&gt;, die die interne API verändert. Ältere Versionen kennen die neuen Felder nicht und meckern. Neuere Versionen hingegen kreiden die Verwendung der alten Felder an.&lt;/p&gt;&#10;&lt;p&gt;Ich glaube, diese Probleme lassen sich nur dann zuverlässig vermeiden, wenn die Pipeline für lokal und remote identisch ist. Sprich: Auf dem Lokalen Rechner eine virtuelle Maschine mit dem CI-Betriebssystem booten und alles in Docker wegkapseln. Macht bestimmt Sinn, wenn man in einer größeren Organisation arbeitet und mehrere User vor diesem Problem stehen.&lt;/p&gt;&#10;&lt;p&gt;Stattdessen wechsle ich zur Behebung im Remote Container auf die Version &lt;code&gt;image: hugomods/hugo:latest&lt;/code&gt; und behebe damit den Fehler. Jedoch habe ich noch immer unterschiedliche Versionen lokal und in der CD-Pipeline. Für mein Betriebssystem gibt es die neueste schlicht noch nicht und auch der Docker Release hängt zeitlich etwas hinter den Releases des Originals.&lt;/p&gt;&#10;&lt;figure class="media-frame media-frame--center"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/posts/2026-09-30-CD-build-with-hugo.avif" alt="Image: Gitea dashboard in the Actions tab. We see three successful workflow runs with a hugo full build &amp;amp; deploy of my site, taking 12sec, 9sec, and 21sec."&gt;&lt;/figure&gt;&#10;&lt;p&gt;Die Bau- und Releasezeiten sind fantastisch, oder? Eine Änderung an der Website in &lt;code&gt;12 Sekunden&lt;/code&gt; online zu haben, inkl. Container hochziehen etc. - das gab es bei mir jedenfalls noch nie. Um die &lt;code&gt;20 Sekunden&lt;/code&gt; benötigt der Durchlauf, wenn er die Container refs erst neu holen und herunterladen muss, z.B. bei Updates der Registry von &lt;code&gt;latest&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;Einen detaillierten &lt;a href="https://blog.schallbert.de/hugo-versus-jekyll-benchmark/"&gt;Benchmarkd zwischen Hugo und Jekyll&lt;/a&gt; bietet der verlinkte Artikel.&lt;/p&gt;&#10;</description></item><item><title>Schallberts Blog mit Hugo</title><link>https://blog.schallbert.de/announcements/2026-09-06-blog-anniversary-hugo/</link><pubDate>Sun, 06 Sep 2026</pubDate><author>Schallbert</author><guid>https://blog.schallbert.de/announcements/2026-09-06-blog-anniversary-hugo/</guid><description type="html">&#10; &lt;img src="https://blog.schallbert.de/assets/images/migrating-hugo-to-jekyll/hugo-website-landing-cover.avif"&#10; class="post-cover"&#10; alt="Image: Crop my landing page with Hugo: We see the logo of the blog, half a speaker and half cog-wheel as menu bar, simple three-word navigation, and the cover images representing the blog&amp;#39;s focus points on Hardware, Electronics, and Software."&#10; title="Schallberts Blog mit Hugo" /&gt;&#10;&lt;h2 id="was-ist-geschehen"&gt;Was ist geschehen?&lt;/h2&gt;&#10;&lt;p&gt;Zum fünften Geburtstag 🥳 stelle ich &lt;strong&gt;schallbert&amp;rsquo;s Blog&lt;/strong&gt; auf eine neue technische Basis!&lt;/p&gt;&#10;&lt;figure class="media-frame media-frame--center"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/migrating-hugo-to-jekyll/hugo-jekyll-build-compare-banner.avif" alt="Image: side-by-side comparison of my website, once built with jekyll, and now built with hugo."&gt;&lt;/figure&gt;&#10;&lt;p&gt;Ich habe diesen Blog von &lt;a href="https://blog.schallbert.de/projects/thissite/"&gt;jekyll&lt;/a&gt; nun auf den Webseitengenerator &lt;a href="https://gohugo.io/" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Hugo&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; umgezogen. Das war viel Aufwand: Über etwa vier Monate hinweg habe ich einen Großteil meiner Freizeit hineingesteckt. Dabei ging der Löwenanteil in das Erstellen und Polieren der Formatierung, Anpassung meiner Inhalte an die neue Umgebung, Reparatur defekter Links und die Dokumentation meines Umbaus.&lt;/p&gt;&#10;&lt;h2 id="warum-habe-ich-das-gemacht"&gt;Warum habe ich das gemacht?&lt;/h2&gt;&#10;&lt;p&gt;Mit Jekyll stand ich immer mehr auf Kriegsfuß: Viele Abhängigkeiten mit immer häufigeren Defekten, die zunehmend lange Bauzeit und die komplexe Umgebung zum Ausrollen auf meinem Server waren die Hauptgründe.&lt;/p&gt;&#10;&lt;p&gt;Meine Seite baut nun etwa &lt;em&gt;fünf mal so schnell&lt;/em&gt; wie vorher.&lt;/p&gt;&#10;&lt;p&gt;Sie lädt &lt;em&gt;weniger Formatierung&lt;/em&gt; nach (CSS, JS) und die Bilder sind noch einmal &lt;em&gt;platzsparender&lt;/em&gt;.&lt;/p&gt;&#10;&lt;p&gt;Außerdem habe ich weder Ruby noch zig Gems auf Stand zu halten.&lt;/p&gt;&#10;&lt;p&gt;Bei den Themes habe ich in Hugo Wert darauf gelegt, es nach benötigter Funktion auszuwählen und nicht nur nach gefälligem Aussehen. Somit ist es jetzt viel &lt;em&gt;simpler und performanter&lt;/em&gt;.&lt;/p&gt;&#10;&lt;h2 id="was-haben-die-leserinnen-davon"&gt;Was haben die LeserInnen davon?&lt;/h2&gt;&#10;&lt;figure class="media-frame media-frame--right"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/announcements/2026-09-06-rss.webp" alt="Image: the RSS logo showing an orange frame with white lines and a dot, simplified like waves transmitted by a broadcast antenna."&gt;&lt;figcaption class="media-caption"&gt;&#10; &lt;span class="caption-text"&gt;RSS logo&lt;/span&gt;&lt;a&#10; href="https://rss.com/blog/free-rss-icon/#rss-logo"&#10; class="attr-link"&#10; aria-label="Attribution 1"&#10; &gt;&#10; &lt;sup class="attr-id"&gt;[1]&lt;/sup&gt;&#10; &lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;p&gt;Der Blog bietet nun einen &lt;a href="https://blog.schallbert.de/index.xml/"&gt;RSS-Feed&lt;/a&gt;. Außerdem sind nun auch meine Projekte in die &lt;a href="https://blog.schallbert.de/tags/"&gt;Schlagwort-Ansicht&lt;/a&gt; mit eingebunden. Zu guter Letzt sind durch die Migration zahlreiche Artikel entstanden. Diese sollen einen solchen Umzug für andere leichter machen als ich es hatte, und die Strukturen in Hugo verdeutlichen.&lt;/p&gt;&#10;&lt;h2 id="artikel-zum-thema"&gt;Artikel zum Thema&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://blog.schallbert.de/projects/migrating-jekyll-to-hugo/"&gt;Projekt: Migration von Jekyll zu Hugo&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://blog.schallbert.de/hugo-create-language-specific-permalinks/"&gt;Permalinks sprachunabhängig korrekt darstellen&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://blog.schallbert.de/hugo-link-checker/"&gt;Website-Links in Hugo mit &lt;em&gt;linkcheck&lt;/em&gt; überprüfen&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://blog.schallbert.de/migrate-jekyll-to-hugo-image-alignment/"&gt;Bildformatierung und -Platzierung in Hugo&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://blog.schallbert.de/build-deploy-hugo-with-actions-docker-caddy/"&gt;Continuous Deployment: Pipeline für Hugo bauen&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="was-fehlt-noch"&gt;Was fehlt noch?&lt;/h2&gt;&#10;&lt;p&gt;Ich bin mit dem Umbau noch nicht ganz fertig:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Die Website auch für die mobile Darstellung optimieren ✓&lt;/li&gt;&#10;&lt;li&gt;Es soll möglich sein, Bilder zentriert und in nativer Auflösung anzuzeigen ✓&lt;/li&gt;&#10;&lt;li&gt;Der Feed soll Coverbilder meiner Artikel korrekt anzeigen ✓&lt;/li&gt;&#10;&lt;li&gt;Ich möchte in CSS einen noch einheitlicheren Look haben (Farben, Bildränder etc.)&lt;/li&gt;&#10;&lt;li&gt;Übersichtsseiten könnten die ganze Bildschirmseite einnehmen und dann größere Bilder anzeigen&lt;/li&gt;&#10;&lt;li&gt;Es fehlen einige englische Übersetzungen ✓&lt;/li&gt;&#10;&lt;li&gt;Schlagworte könnten spezifischer und trennschärfer implementiert werden&lt;/li&gt;&#10;&lt;li&gt;Schön wäre ein mitscrollendes Inhaltsverzeichnis auf der linken Seite&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Auf diesen Seiten wird es in den kommende Wochen in vielen Details noch einmal Verbesserungen geben.&#10;Ich freue mich darauf!&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;schallbert&lt;/strong&gt;&lt;/p&gt;&#10;</description></item><item><title>Umzug von Jekyll zu Hugo</title><link>https://blog.schallbert.de/projects/migrating-jekyll-to-hugo/</link><pubDate>Sun, 06 Sep 2026</pubDate><author>Schallbert</author><guid>https://blog.schallbert.de/projects/migrating-jekyll-to-hugo/</guid><description type="html">&#10; &lt;img src="https://blog.schallbert.de/assets/images/migrating-hugo-to-jekyll/hugo-jekyll-build-compare-cover.avif"&#10; class="post-cover"&#10; alt="Image: Hugo console build output. It shows a full build time below 8sec. (~70% reduction over build time with Jekyll)"&#10; title="Umzug von Jekyll zu Hugo" /&gt;&#10;&lt;h2 id="projekt-steckbrief"&gt;Projekt-Steckbrief&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Schwierigkeitsgrad: Mittel 3/5&lt;/li&gt;&#10;&lt;li&gt;Kosten: 0€&lt;/li&gt;&#10;&lt;li&gt;Zeit ~20h&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;In diesem Projekt beschreibe ich meinen Umzug von Jekyll mit der Optik von &lt;a href="https://github.com/mmistakes/minimal-mistakes" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Minimal Mistakes&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; zu Hugo in einem stark modifizierten &lt;a href="https://github.com/panr/hugo-theme-terminal" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Terminal-Theme&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="warum-überhaupt-wechseln"&gt;Warum überhaupt wechseln?&lt;/h2&gt;&#10;&lt;p&gt;Schon seit langem war ich nicht mehr vollständig zufrieden mit dem Bauen meiner Website per Jekyll. Der Auslöser für den Umstieg war, dass ich eines Tages plötzlich wegen eines Kompatibilitätsproblemes nicht mehr lokal bauen konnte. Ein &lt;code&gt;bundle update --conservative&lt;/code&gt; oder &lt;code&gt;bundle install&lt;/code&gt; wie üblich half nicht. Auch das manuelle Nachinstallieren der verursachenden Pakete per &lt;code&gt;gem install commonmarker-0.23.12&lt;/code&gt; oder &lt;code&gt;gem install posix-spawn -v 0.3.15 -- --with-cflags=\&amp;quot;-Wno-incompatible-function-pointer-types\&amp;quot;&lt;/code&gt; brachten keine Abhilfe.&lt;/p&gt;&#10;&lt;figure class="media-frame media-frame--center"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/migrating-hugo-to-jekyll/jekyll-update-bundle-installer-error.avif" alt="Image: Bundler dependency tree showing the error: Failed to build gem native extension. Multiple errors like this occurred lately when I tried building my site."&gt;&lt;/figure&gt;&#10;&lt;p&gt;Ein Update von &lt;em&gt;Ruby&lt;/em&gt; und &lt;em&gt;Jekyll&lt;/em&gt; selbst brachte ebenfalls keinen Erfolg. Und überhaupt: Die Bauzeit mit Jekyll ist inzwischen ziemlich lang geworden. Ich bin durch meinen &lt;a href="https://blog.schallbert.de/projects/move-blog-to-own-server/"&gt;Umzug der Seite von Github Pages auf einen eigenen Server&lt;/a&gt; nicht mehr an Jekyll gebunden, was einen Wechsel attraktiver macht.&lt;/p&gt;&#10;&lt;h3 id="weitere-schwierigkeiten-mit-jekyll"&gt;Weitere Schwierigkeiten mit Jekyll&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;CI/CD: Meine Deploy-Pipeline war vor Monaten mit ähnlichen Fehlern ausgefallen, sodass ich auf eine ältere Jekyll-Version zurückgreifen musste. Damit vergrößert sich technische Schuld und Angriffsfläche meiner Actions. Ich müsste auf die Suche nach einer gut gewarteten Containerlösung eines anderen Anbieters wechseln. Suche und Einrichtung würden zusätzliche Zeit erfordern.&lt;/li&gt;&#10;&lt;li&gt;RSS-Feed: Ich möchte zu meiner Website gern einen RSS-Feed bereitstellen. Meine Experimente mit Jekyll zeigten jedoch, dass nur &amp;ldquo;Posts&amp;rdquo; und keine &amp;ldquo;Announcements&amp;rdquo; inkludiert werden. Das wollte ich beheben.&lt;/li&gt;&#10;&lt;li&gt;Bildformate: Cover-Bilder (Thumbnails) für Posts werden im RSS-Feed durch Jekyll eigentlich mit gebaut. Durch meinen Umstieg von &lt;code&gt;.jpg&lt;/code&gt; auf das platzsparendere &lt;code&gt;.avif&lt;/code&gt; funktionierte das nun leider nicht mehr. Eine Lösung habe ich trotz mehrerer Anläufe nicht durch den Pull Request Review bekommen.&lt;/li&gt;&#10;&lt;li&gt;Icons: Das von mir verwendete Theme nutzt &lt;em&gt;Font Awesome&lt;/em&gt; zur Darstellung von Icons und ist insgesamt für eine statische Website recht groß. Ich wollte aber nichts aus dem Netz nachladen und habe die Bibliothek daher lokal gespeichert. Daher war mein Plan, nur die wirklich benötigten Icons heraussuchen und den Rest zu löschen. Mit dem Umstieg auf Hugo ist dies nicht mehr notwendig.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="opportunities"&gt;Die Chancen&lt;/h3&gt;&#10;&lt;p&gt;Von Hugo verspreche ich mir schnellere Bauzeiten, eine vereinfachte CI/CD ohne Nachinstallieren von Bundler, Ruby etc. und die Behebung der oben beschriebenen Schwierigkeiten. Das Abhängigkeits- und Paketmanagement von Hugo unterscheidet sich grundlegend von Jekyll: Zusätzliche Inhalte werden per &lt;a href="https://git-scm.com/book/en/v2/Git-Tools-Submodules" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Git Submodules&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; eingebunden und das Abhängigkeismanagement nutzt statt der &lt;a href="https://bundler.io/man/gemfile.5.html" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Gemfile&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; schlicht &lt;a href="https://instagit.com/gohugoio/hugo/hugo-dependency-management-go-modules/" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Go modules&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="das-migrationswerkzeug"&gt;Das Migrationswerkzeug&lt;/h2&gt;&#10;&lt;p&gt;Die Ordnerstrukturen der Inhalte unterscheidet sich deutlich zwischen &lt;em&gt;Jekyll&lt;/em&gt; und &lt;em&gt;Hugo&lt;/em&gt;. Ich nutze daher ein in Hugo enthaltenes &lt;a href="https://gohugo.io/commands/hugo_import_jekyll/" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Importwerkzeug&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt;, welches mir zumindest die Artikel unter &lt;code&gt;/posts&lt;/code&gt; korrekt importiert.&lt;/p&gt;&#10;&lt;p&gt;Alle spezifischen Inhalte wie Übersichtsseiten &lt;code&gt;/tags, /pages/error, /pages/legal&lt;/code&gt; und Seiten, wo Projekte und Ankündigungen abgelegt sind &lt;code&gt;/_announcements, /_projects&lt;/code&gt;, werden allerdings nicht mit umgezogen und müssen manuell kopiert und modifiziert werden.&lt;/p&gt;&#10;&lt;h3 id="anpassen-der-front-matter"&gt;Anpassen der Front Matter&lt;/h3&gt;&#10;&lt;p&gt;Viele von mir gemachten Anpassungen in Jekyll funktionieren in Hugo entweder nicht richtig oder führen zum Abbruch des Bauvorganges - die &lt;strong&gt;Front Matter&lt;/strong&gt; einer jeden Markdown-Datei muss also angepasst und teils bereinigt werden.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Alt: So kann die Front matter einer Übersichtsseite in Jekyll aussehen&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;lang&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;de&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;title&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Beitragsarchiv&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;subtitle&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Diese Sammlung enthält alle meine Beiträge&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;layout&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;collection&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;collection&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;posts&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;permalink&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;/posts-archive/&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;entries_layout&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;grid&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;classes&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;wide&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;author_profile&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In meinem Falle liegen einige Theme-abhänigen Parameter im Frontmatter vor wie &lt;code&gt;layout, classes, author_profile&lt;/code&gt;. Der &lt;code&gt;lang&lt;/code&gt;-Parameter aus meiner Internationalisierungserweiterung in Jekyll ist nicht einmal korrekte Hugo-Syntax: es erwartet die angezeigte Sprache entweder als Feld unter &lt;code&gt;params: lang&lt;/code&gt; oder Ordnerweit. Auch andere, an den eigenen Geschmack angepasste Parameter können definiert und unter &lt;code&gt;params&lt;/code&gt; mitgegeben werden.&lt;/p&gt;&#10;&lt;p&gt;Permalinks finden gar keinen Eingang mehr in die Front matter, stattdessen findet die Konfiguration &lt;a href="https://gohugo.io/configuration/permalinks/" target="_blank" rel="noopener noreferrer" class="external-link"&gt;zentral statt&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;Eine &lt;a href="https://gohugo.io/content-management/front-matter/" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Hugo-kompatible front matter&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; kann so aussehen:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;title&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Beitragsarchiv&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;description&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Diese Sammlung enthält alle meine Beiträge&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;layout&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;collection&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="konfiguration-des-theme"&gt;Konfiguration des Theme&lt;/h2&gt;&#10;&lt;p&gt;Eine Basis-Konfiguration meines Themes kann ich mit folgendem Kommando installieren:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;➜ blog git:&lt;span style="color:#f92672"&gt;(&lt;/span&gt;main&lt;span style="color:#f92672"&gt;)&lt;/span&gt; ✗ git submodule add https://github.com/panr/hugo-theme-terminal ./themes/terminal &#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Zum Aktivieren muss ich es in der Hauptkonfiguration bekannt machen:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# /hugo.toml&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Add it only if you keep the theme in the `themes` directory.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Remove it if you use the theme as a remote Hugo Module.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;theme&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;terminal&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Und schon baut Hugo für mich im Terminal-Theme und Originalfarben.&lt;/p&gt;&#10;&lt;figure class="media-frame media-frame--center"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/migrating-hugo-to-jekyll/hugo-initial-build-with-terminal.avif" alt="Image: One of my blog posts in original Terminal theme: Left-adjusted, filling half the screen and in dark grey, orange as contrast color, and white text."&gt;&lt;/figure&gt;&#10;&lt;p&gt;Dies ist nun nicht vertikal zentriert und für meinen Geschmack zu schmal ausgelegt, der Text recht klein und &amp;ldquo;meine&amp;rdquo; Blog-Farben sollen ebenfalls anders sein .&lt;/p&gt;&#10;&lt;p&gt;Daher erstelle ich eine &lt;code&gt;.css&lt;/code&gt;-Datei, die einige Eigenschaften des Basis-Themes überschreibt. Sie muss im Ordner &lt;code&gt;/static&lt;/code&gt; liegen und den Namen des Themes tragen.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/* /static/terminal.css */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;:&lt;span style="color:#a6e22e"&gt;root&lt;/span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --background: &lt;span style="color:#ae81ff"&gt;#252a34&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --background-highlight: &lt;span style="color:#ae81ff"&gt;#475064&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --foreground: &lt;span style="color:#ae81ff"&gt;#d2eaef&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --foreground-dimmed: &lt;span style="color:#ae81ff"&gt;#8b9ea2&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --accent: &lt;span style="color:#ae81ff"&gt;#25a679&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --accent-highlight: &lt;span style="color:#ae81ff"&gt;#79ae9c&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --radius: &lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --font-size: &lt;span style="color:#ae81ff"&gt;1.35&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;rem&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --line-height: &lt;span style="color:#ae81ff"&gt;1.8&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;em&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/* Use system fonts, reduce transferred kB */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;body&lt;/span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;font-family&lt;/span&gt;: system-ui, &lt;span style="color:#f92672"&gt;-&lt;/span&gt;apple-system, &lt;span style="color:#e6db74"&gt;&amp;#34;Segoe UI&amp;#34;&lt;/span&gt;, Roboto, Arial, &lt;span style="color:#66d9ef"&gt;sans-serif&lt;/span&gt; &lt;span style="color:#75715e"&gt;!important&lt;/span&gt;; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/* make content wider */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;body&lt;/span&gt; .&lt;span style="color:#a6e22e"&gt;container&lt;/span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;max-width&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;70&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;rem&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;width&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;90&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;%&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Und schon sieht es fast wie früher aus.&lt;/p&gt;&#10;&lt;figure class="media-frame media-frame--center"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/migrating-hugo-to-jekyll/hugo-custom-build-with-terminal.avif" alt="Image: One of my blog posts in the modified Terminal theme: centered, filling three quarters of the screen and in dark grey, teal as contrast color, and blueish-white text with a sans-serif system font."&gt;&lt;/figure&gt;&#10;&lt;h2 id="organisation-der-ordnerstruktur"&gt;Organisation der Ordnerstruktur&lt;/h2&gt;&#10;&lt;p&gt;Anders als bei der von mir verwendeten &lt;em&gt;Jekyll&lt;/em&gt;-Version verfügt &lt;em&gt;hugo&lt;/em&gt; über eingebaute Internationalisierung (&lt;code&gt;i18n&lt;/code&gt;). Dafür muss ich meine Ordnerstruktur umbauen und explizit in &lt;code&gt;/de&lt;/code&gt; und &lt;code&gt;/en&lt;/code&gt;-Ordnerinhalte sortieren. Inhalte werden nun statt auf der höheren Ordner-Ebene direkt unter &lt;code&gt;/_pages, /_announcements, /_posts&lt;/code&gt; im Ordner &lt;code&gt;content&lt;/code&gt; gehalten, was die Sache übersichtlicher macht.&lt;/p&gt;&#10;&lt;h3 id="vorher"&gt;Vorher&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── _announcements&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── assets&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── css&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── fontawesome&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── katex&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── main.scss &lt;span style="color:#75715e"&gt;# &amp;lt;-- theme import, customization&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ └── webfonts&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── js&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── lunr&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── _main.js&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── main.min.js&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── plugins&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ └── vendor&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── video&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── banner.js&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── CNAME&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── _config.yml&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── _data&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── de&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── l10n.yml&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── en&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── l10n.yml&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── en&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── index.html&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── Gemfile&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── Gemfile.lock&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── _includes &lt;span style="color:#75715e"&gt;# &amp;lt;-- Layouts (HTML), partials, 3rd-party&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── index.html &lt;span style="color:#75715e"&gt;# &amp;lt;-- Landing page&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── _layouts &lt;span style="color:#75715e"&gt;# &amp;lt;-- Page layouts&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── _pages&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── 404.md &lt;span style="color:#75715e"&gt;# &amp;lt;-- German version&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── &lt;span style="color:#f92672"&gt;[&lt;/span&gt;...&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── en&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── 404.md &lt;span style="color:#75715e"&gt;# &amp;lt;-- English version&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── &lt;span style="color:#f92672"&gt;[&lt;/span&gt;...&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── _posts/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── en &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── _projects/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── _sass&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── minimal-mistakes &lt;span style="color:#75715e"&gt;# &amp;lt;-- Styles (SCSS) for layouts and partials&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── minimal-mistakes.scss&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── _video.scss&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── _site/ &lt;span style="color:#75715e"&gt;# &amp;lt;-- Build artifacts&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── staticman.yml&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="nachher"&gt;Nachher&lt;/h3&gt;&#10;&lt;p&gt;Einen guten Überblick über die Ordnerstruktur bietet &lt;a href="https://gohugo.io/templates/new-templatesystem-overview/" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Hugos Dokumentation&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt;. Am wichtigsten für die tägliche Arbeit mit Artikeln und Aussehen der Website sind die Stammordner &lt;code&gt;content&lt;/code&gt;, &lt;code&gt;layouts&lt;/code&gt; und &lt;code&gt;static&lt;/code&gt;.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── archetypes&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── assets&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── content&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── de&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── about.md&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── announcements/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── posts/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ └── projects/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── en&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── about.md&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── &lt;span style="color:#f92672"&gt;[&lt;/span&gt;...&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── data&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── hugo.yml&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── layouts&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── _default&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── baseof.html &lt;span style="color:#75715e"&gt;# &amp;lt;-- defines header, add-ons, content, footer structure&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── index.html &lt;span style="color:#75715e"&gt;# &amp;lt;-- landing page&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── list.html &lt;span style="color:#75715e"&gt;# &amp;lt;-- grid view&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ └── single.html &lt;span style="color:#75715e"&gt;# &amp;lt;-- post view&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── _markup&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ └── render-link.html &lt;span style="color:#75715e"&gt;# &amp;lt;-- link highlighting and function (referrer, tabs)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── _partials&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── cover.html &lt;span style="color:#75715e"&gt;# &amp;lt;-- cover (thumbnail) image rendering&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ └── math.html &lt;span style="color:#75715e"&gt;# &amp;lt;-- math rendering (katex)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── _shortcodes&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── audio.html&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── image.html&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── &lt;span style="color:#f92672"&gt;[&lt;/span&gt;...&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── resources&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── _gen&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── assets/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── static&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── assets&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── audio/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── css/ &lt;span style="color:#75715e"&gt;# &amp;lt;-- contains overrides for custom layouts &lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── docs/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── images/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── js/ &lt;span style="color:#75715e"&gt;# &amp;lt;-- math (katex) JS lives here&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ └── video/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── terminal.css &lt;span style="color:#75715e"&gt;# &amp;lt;-- Central theme override (colors, formatting, styling)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;└── themes&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └── terminal &lt;span style="color:#75715e"&gt;# &amp;lt;-- GIT submodule: Vanilla &amp;#34;Terminal&amp;#34; theme&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Bei beiden Lösungen werden Layouts in &lt;code&gt;html&lt;/code&gt; und Stil/Format ind &lt;code&gt;CSS&lt;/code&gt; definiert. Da ich bei Jekyll mehr Plugins verwenden musste, wird das Setup größer.&lt;/p&gt;&#10;&lt;h2 id="manuelle-anpassungen-shortcodes"&gt;Manuelle Anpassungen: Shortcodes&lt;/h2&gt;&#10;&lt;p&gt;Mit &lt;em&gt;Shortcodes&lt;/em&gt; kann man in Hugo nicht-Text-Inhalte (Medien, Links, Formatierung, Stil) definieren, die dann nach definierter Vorschrift gerendert werden. Dafür legt man eine &lt;code&gt;html&lt;/code&gt;-Datei an, welche den Dekorator definiert und entsprechende &lt;code&gt;css-Klassen&lt;/code&gt; einbindet. Außerdem fügt man die gewünschte Formatierung in der überschreibenden Theme-&lt;code&gt;css&lt;/code&gt;-Datei ein.&lt;/p&gt;&#10;&lt;p&gt;Da ich hier absolut kein Profi bin, probiere ich anschließend so lange herum, bis mir das Layouting gefällt und ich keine Artefakte/Überlagerungen mehr sehe.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── layouts&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── _shortcodes&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── my-shortcode.html &lt;span style="color:#75715e"&gt;# &amp;lt;-- Custom shortcode file&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── static&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── terminal.css &lt;span style="color:#75715e"&gt;# &amp;lt;-- Central theme override (colors, formatting, styling)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="syntax-hugo-und-jekyll"&gt;Syntax: Hugo und Jekyll&lt;/h3&gt;&#10;&lt;p&gt;Shortcodes werden bei Hugo in der Markdown-Datei mit folgender Syntax angezeigt:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{&amp;lt; &lt;span style="color:#a6e22e"&gt;shortcode&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;html&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;filename&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;options&lt;/span&gt; &amp;gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{&amp;lt; &lt;span style="color:#a6e22e"&gt;image&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;/path/to/image.avif&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;alt&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;Image: alt text&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;position&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;right&amp;#34;&lt;/span&gt; &amp;gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Im Vergleich dazu sehen Shortcode-ähnliche Dekoratoren in Jekyll für &lt;a href="https://jekyllrb.com/docs/liquid/" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Liquid, die in Jekyll benutzte Beschreibungssprache&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; so aus:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-md" data-lang="md"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;### Liquid in interpreter code&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{% Liquid bracket syntax %}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;### Liquid &amp;#34;shortcode&amp;#34; pendant&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{% include gallery id=&amp;#34;gallery&amp;#34; caption=&amp;#34;Eindrücke von &lt;span style="font-weight:bold"&gt;**MobFobAmp**&lt;/span&gt;. Zum Vergrößern anklicken.&amp;#34; %}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;### Liquid decorator for layouting&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{:.list-inline}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="image"&gt;image&lt;/h3&gt;&#10;&lt;p&gt;Anwendungsbeispiel zur Bildanzeige. In der nächsten Zeile folgt ein zentriertes Bild.&#10;&lt;figure class="media-frame media-frame--center"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/favicon/logo_icon.avif" alt="Image: My blog logo, half a speaker chassis, half cog wheels, centered."&gt;&lt;/figure&gt;&lt;/p&gt;&#10;&lt;figure class="media-frame media-frame--left"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/favicon/logo_icon.avif" alt="Image: My blog logo, half a speaker chassis, half cog wheels, left-adjusted with text flow."&gt;&lt;/figure&gt;&#10;&lt;p&gt;Der klassische Bild-Dekorator für Markdown &lt;code&gt;[Alt Text](/path/to/image)&lt;/code&gt; wird in Hugo standardmäßig als mittig zentriertes Bild ohne Textfluss gerendert. Für ein schönes Layouting benötige ich jedoch ein paar Varianten, welche etwas zusätzlichen Code in cascading style sheets und html erfordern.&lt;/p&gt;&#10;&lt;figure class="media-frame media-frame--right"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/favicon/logo_icon.avif" alt="Image: My blog logo, half a speaker chassis, half cog wheels, right-adjusted with text flow."&gt;&lt;/figure&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Bild zentriert, ohne Textfluss&lt;/li&gt;&#10;&lt;li&gt;Bild links , Textfluss rechts&lt;/li&gt;&#10;&lt;li&gt;Bild rechts, Textfluss links&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Zuerst besorgt sich Hugo Dateipfad und Bildtext. Anschließend liest es die gewünschte Formatierung aus der Markdown-Datei, welche mit der &lt;code&gt;position&lt;/code&gt;-Variable angelegt wird. Anschließend wendet sie die &lt;code&gt;image-wrapper&lt;/code&gt; Klasse aus der &lt;code&gt;.css&lt;/code&gt;-Datei darauf an. Die Ausrichtung der Bilder gilt für bessere Lesbarkeit nur für die Desktop-Variante der Webseite (&lt;code&gt;&amp;gt;684px&lt;/code&gt;).&lt;/p&gt;&#10;&lt;p&gt;Die Anpassungen des Themes gehen zur richtigen Darstellung von Bildern recht weit. Außerdem habe ich noch eine Galerie entwickelt, falls ein Post über sehr viele Bilder verfügt. Daher habe ich für die Bildformatierung und -Ausrichtung &lt;a href="https://blog.schallbert.de/migrate-jekyll-to-hugo-image-alignment/"&gt;einen eigenen Artikel&lt;/a&gt; geschrieben.&lt;/p&gt;&#10;&lt;h3 id="audio"&gt;audio&lt;/h3&gt;&#10;&lt;p&gt;Zur Darstellung des Audio-Players verwende ich die im Browser implementierten Standards.&lt;/p&gt;&#10;&lt;figure class="media-frame media-frame--center media-frame--audio"&gt;&#10; &lt;figure class="media-frame"&gt;&#10; &lt;audio controls&gt;&#10; &lt;source src="https://blog.schallbert.de/assets/audio/aa_alpha_fingered_flageolet.mp3" type="audio/mp3"&gt;&#10; Your browser does not support the audio element.&#10; &lt;/audio&gt;&lt;figcaption class="media-caption"&gt;&#10; &lt;span class="caption-text"&gt;Beispielplayer: Melodie auf dem E-Bass&lt;/span&gt;&#10; &lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#75715e"&gt;/* /layouts/_shortcodes/audio.html */&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; .&lt;span style="color:#a6e22e"&gt;Get&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;src&amp;#34;&lt;/span&gt; }}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;caption&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; .&lt;span style="color:#a6e22e"&gt;Get&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;caption&amp;#34;&lt;/span&gt; | &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt; }}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;media-wrapper&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;media-container&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;audio&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;controls&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;source&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;{{ $src }}&amp;#34;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;type&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;audio/mp3&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Your&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;browser&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;does&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;not&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;support&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;the&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;audio&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;audio&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{ &lt;span style="color:#a6e22e"&gt;with&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;caption&lt;/span&gt; }}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;media-title&amp;#34;&lt;/span&gt;&amp;gt;{{ . }}&amp;lt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{ &lt;span style="color:#a6e22e"&gt;end&lt;/span&gt; }}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In &lt;code&gt;css&lt;/code&gt; verwende ich einen Wrapper und Media-Container, um Titel im Rahmen des Players anzeigen zu können und die Formatierung zu erleichtern. Auch hier habe ich angepasstes Verhalten für ein &amp;ldquo;responsive layout&amp;rdquo; bei Mobilgeräten oder Änderungen der Größe des Browser-Fensters.&lt;/p&gt;&#10;&lt;h3 id="video"&gt;video&lt;/h3&gt;&#10;&lt;p&gt;Das CSS ist identisch mit &lt;code&gt;audio&lt;/code&gt;. Es gibt nur im &lt;code&gt;html&lt;/code&gt; geringfügige Unterschiede. Der von mir verwendete Container unterstützt unter &lt;code&gt;src=&lt;/code&gt; als Quellen sowohl &amp;ldquo;embed-Links&amp;rdquo; von Webseiten wie &lt;em&gt;peertube&lt;/em&gt; als auch lokale Quelldateien.&lt;/p&gt;&#10;&lt;figure class="media-frame media-frame--center media-frame--video"&gt;&#10; &lt;div class="media-video"&gt;&lt;video controls&gt;&#10; &lt;source src="https://blog.schallbert.de/assets/video/posts/2022-03-01_trolley.mp4" type="video/mp4"&gt;&#10; Your browser does not support the video tag.&#10; &lt;/video&gt;&lt;/div&gt;&#10; &lt;figcaption class="media-caption"&gt;&#10; &lt;span class="caption-text"&gt;Video-Beispiel (lokal): Linearführungen mit Kugelumlauf&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#75715e"&gt;/* /layouts/_shortcodes/video.html */&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; .&lt;span style="color:#a6e22e"&gt;Get&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;src&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;title&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; .&lt;span style="color:#a6e22e"&gt;Get&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;title&amp;#34;&lt;/span&gt; | &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;caption&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; .&lt;span style="color:#a6e22e"&gt;Get&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;caption&amp;#34;&lt;/span&gt; | &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;media-wrapper&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;media-container&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;hasPrefix&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;iframe&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;{{ $src }}&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;frameborder&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;0&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;allowfullscreen&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;iframe&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;video&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;controls&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;source&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;{{ $src }}&amp;#34;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;type&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;video/mp4&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Your&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;browser&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;does&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;not&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;support&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;the&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;video&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;tag&lt;/span&gt;.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;video&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;end&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;or&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;title&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;caption&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;media-title&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;title&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}{{ &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;title&lt;/span&gt; }}{{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}{{ &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;caption&lt;/span&gt; }}{{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;end&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;end&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="updates"&gt;Updates&lt;/h3&gt;&#10;&lt;p&gt;Auch bei mir &amp;ldquo;altern&amp;rdquo; Inhalte. Manchmal wechsle ich Technologien oder Anbieter, und manchmal bewegen sich auch Dritte von Lösungen weg, deren Implementierung ich hier im Blog beschrieben habe. Daher habe ich &lt;code&gt;update-shortcodes&lt;/code&gt; eingeführt.&lt;/p&gt;&#10;&lt;aside class="update-box update-box--warn" role="note"&gt;&#10; &lt;span class="update-box__icon" aria-hidden="true"&gt;&#10; ⚠️&#10; &lt;/span&gt;&#10;&#10; &lt;div class="update-box__body"&gt;&#10; &lt;div class="update-box__heading"&gt;&#10; &lt;strong class="update-box__title"&gt;&#10; &#10; Software altert&#10; &#10; &lt;/strong&gt;&#10;&#10; &lt;time datetime="2026-09-15T00:00:00Z"&gt;&#10; 15. Sept. 2026&#10; &lt;/time&gt;&#10; &#10; &lt;/div&gt;&#10;&#10; &#10; &lt;div class="update-box__content"&gt;&#10; Klingt komisch. Was an Software soll denn altern? Vielleicht lässt es sich besser formulieren, indem man sagt, dass sich die Zeit und damit die Welt über Software hinwegbewegt und man sie daher stetig anpassen muss. Erscheint ein solches Kästchen im Blog, gibt es neue Informationen zum Thema, die ergänzend oder ersetzend wirken können.&#10; &lt;/div&gt;&#10; &#10; &lt;/div&gt;&#10;&lt;/aside&gt;&#10;&lt;h2 id="verlinkungen"&gt;Verlinkungen&lt;/h2&gt;&#10;&lt;p&gt;Folgendes Verhalten wünsche ich mir für Links auf meinem Blog:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;interne Links sollen im selben Tab geöffnet werden und die Nutzer weiterleiten.&lt;/li&gt;&#10;&lt;li&gt;interne Links sollen zu Seiten in derselben Sprache verweisen und nicht auf die Standard-Sprache oder zurück zur Hauptseite führen.&lt;/li&gt;&#10;&lt;li&gt;externe Links sollen mit einem Symbol gekennzeichnet werden: &lt;code&gt;↗&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;externe Links sollen in einem frischen Tab geöffnet werden: &lt;code&gt;target=&amp;quot;_blank&amp;quot;&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;exterme Links sollen weder auf die ursprünglichen Inhalte zugreifen noch den Quellverweis sehen können &lt;code&gt;rel=&amp;quot;noopener noreferrer&amp;quot;&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Dafür erstelle ich unter &lt;code&gt;/layouts/_markup&lt;/code&gt; die Datei &lt;code&gt;render-link.html&lt;/code&gt;.&#10;Den Code hierfür und seine Hintergründe stelle ich in einem separaten Post vor: &lt;a href="https://blog.schallbert.de/hugo-create-language-specific-permalinks/"&gt;Hugo Multi-language: Interne Permalinks&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;Der Override für CSS sieht wie folgt aus.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/* /static/terminal.css */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;external-link&lt;/span&gt; .&lt;span style="color:#a6e22e"&gt;external-link-icon&lt;/span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;display&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;inline-block&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;font-size&lt;/span&gt;: &lt;span style="color:#a6e22e"&gt;var&lt;/span&gt;(&lt;span style="color:#f92672"&gt;--&lt;/span&gt;font&lt;span style="color:#f92672"&gt;-&lt;/span&gt;size);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;vertical-align&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;middle&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;transform&lt;/span&gt;: translateY(&lt;span style="color:#ae81ff"&gt;-0.1&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;em&lt;/span&gt;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="manuelle-anpassungen-partials"&gt;Manuelle Anpassungen: Partials&lt;/h2&gt;&#10;&lt;p&gt;Partials kann man sich vorstellen wie die Layout-Bausteine für eine Hugo-Website. Sie werden unter &lt;code&gt;/layouts/_partials&lt;/code&gt; abgelegt und überschreiben die Standards des verwendeten Themes. Dabei wird die Ursprungsdatei gar nicht mehr geladen, was ein Herüberkopieren der Originaldatei in den Ordner mit anschließender manueller Anpassung empfehlenswert macht.&lt;/p&gt;&#10;&lt;h3 id="index"&gt;index&lt;/h3&gt;&#10;&lt;p&gt;Die Startseite für den Blog ist komplett selbt geschrieben und liegt nicht in Markdown, sondern in &lt;code&gt;html&lt;/code&gt; vor. Sie zeigt ihre Inhalte anders an als alle anderen Blog-Seiten und daher lohnte es sich für mich nicht, Templates zu programmieren. In der entsprechenden &lt;code&gt;/layouts/_partials/index.html&lt;/code&gt; lade ich dafür notwendige &lt;code&gt;scss&lt;/code&gt; und &lt;code&gt;css&lt;/code&gt;-Dateien und gebe die Struktur der Seite vor. Die folgende Tabelle gibt einen Überblick über meine Änderungen.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;File&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Purpose&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Customization&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;cover&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;thumbnail / cover image for overview pages, lists, and grids&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Add custom cover image decorator, alt text&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;head&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Defines Favicon, search console, page parameters, feeds etc.&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Custom favicon path&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;header&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Page header containing menu, logo, navigation etc.&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Add logo and subtitle to menu, lang selector&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;logo&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Custom page logo, title, subtitle&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Full&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;math&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Displays math content with Latex/Katex&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;None, implement math support&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h3 id="math"&gt;math&lt;/h3&gt;&#10;&lt;p&gt;Mein Blog soll mathematische Notation unterstützen. Dafür benutze ich &lt;a href="https://katex.org/" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Katex&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go-html-template" data-lang="go-html-template"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{- /* /layouts/_partials/math.html */ -}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;stylesheet&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/assets/css/katex.min.css&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;defer&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/assets/js/katex.min.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;defer&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/assets/js/contrib/auto-render.min.js&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;onload&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;renderMathInElement(document.body);&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; document.&lt;span style="color:#a6e22e"&gt;addEventListener&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;DOMContentLoaded&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;renderMathInElement&lt;/span&gt;(document.&lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;, {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;delimiters&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&lt;span style="color:#a6e22e"&gt;left&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;\\[&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;right&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;\\]&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;display&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;}, &lt;span style="color:#75715e"&gt;// block&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&lt;span style="color:#a6e22e"&gt;left&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$$&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;right&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$$&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;display&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;}, &lt;span style="color:#75715e"&gt;// block&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&lt;span style="color:#a6e22e"&gt;left&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;\\(&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;right&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;\\)&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;display&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;}, &lt;span style="color:#75715e"&gt;// inline&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;throwOnError&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="cover-image"&gt;cover image&lt;/h3&gt;&#10;&lt;p&gt;Unter der Bezeichnung &lt;code&gt;cover&lt;/code&gt; verstehe ich ein Titelbild eines Blog-Posts. Es wird in Übersichtsseiten, Artikel- und Tag-Listen etc. angezeigt und soll die Inhalte des Blog-posts unterstützend beschreiben. Auch mein &lt;code&gt;RSS&lt;/code&gt;-Feed soll diese Bilder für die Übersicht verschiedener Artikel auf Endgeräten meiner Leserschaft verwenden.&lt;/p&gt;&#10;&lt;p&gt;Es ist besonders stark komprimiert und benötigt wenig Übertragungsbandbreite. Daher ist seine Auflösung gering (&lt;code&gt;440x220&lt;/code&gt; oder &lt;code&gt;640x352&lt;/code&gt;). Für einen einheitlichen Look sind sie zudem stets monochrom.&lt;/p&gt;&#10;&lt;p&gt;Die Markdown-Syntax zum Einbinden des Covers sehe ich wie folgt vor:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;cover_alt&lt;/span&gt;: &lt;span style="color:#f92672"&gt;&amp;#39;Image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Hugo console build output. It shows a full build time below 2sec. (~90% reduction over build time with Jekyll)&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;cover&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;/assets/images/migrating-hugo-to-jekyll/hugo-jekyll-build-compare-cover.avif&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Anschließend erstelle ich unter &lt;code&gt;layouts/_partials&lt;/code&gt; die Datei &lt;code&gt;cover.html&lt;/code&gt; und schreibe folgenden Code hinein:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go-html-template" data-lang="go-html-template"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{- /* /layouts/_partials/cover.html */ -}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{- /* Handles cover-image generation */ -}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$cover&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$autoCover&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;default&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$.Site.Params.autoCover&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;index&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Params&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;cover&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Resources.GetMatch&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Params.Cover&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$cover&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.Resources.GetMatch&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Params.Cover&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.RelPermalink&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$cover&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;absURL&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Params.Cover&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$.Site.Params.AutoCover&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Params.Cover&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Resources.GetMatch&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;cover.*&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$cover&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.Resources.GetMatch&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;cover.*&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.RelPermalink&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$cover&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;!-- Cover image found --&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;img&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$cover&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;post-cover&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;alt&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Params.cover_alt&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;plainify&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.Description&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;plainify&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;title&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Params.CoverCredit&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;plainify&lt;/span&gt;&lt;span style="color:#f92672"&gt;|&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.Title&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;plainify&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; /&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Der Code sucht und extrahiert den Pfad zum Coverbild. Sollte ein valider Pfad gefunden werden, wird es als &lt;code&gt;post-cover&lt;/code&gt; mit entsprechendem CSS angezeigt.&lt;/p&gt;&#10;&lt;p&gt;Dem XML-Template füge ich als erstes Element innerhalb des &lt;code&gt;&amp;lt;description&amp;gt;&lt;/code&gt;-Tags das Coverbild hinzu. Erst danach kommt der eigentliche Artikel. Die meisten Feed Reader nehmen dieses Bild dann als Cover für ihre Übersichten.&lt;/p&gt;&#10;&lt;h2 id="manuelle-anpassungen-layouts"&gt;Manuelle Anpassungen: Layouts&lt;/h2&gt;&#10;&lt;p&gt;Damit sich meine Seite in Hugo weiterhin ganz ähnlich anfüllt wie zuvor in Jekyll muss ich in den Layouts ein paar Änderungen vornehmen. Im Folgenden habe ich sie beschrieben.&lt;/p&gt;&#10;&lt;h3 id="baseofhtml"&gt;baseof.html&lt;/h3&gt;&#10;&lt;p&gt;Hier werden die Basis-Inhalte definiert. Definitionen für Kopf- und Fußzeile werden importiert und Stylesheets eingebunden. Die allermeisten oben beschriebenen Änderungen werden an dieser Stelle importiert.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go-html-template" data-lang="go-html-template"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{- /* /layouts/baseof.html */ -}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;html&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;lang&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$.Site.Language&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;head&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Param&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;math&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;partialCached&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;math.html&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;block&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;title&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;title&lt;/span&gt;&amp;gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.IsHome&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$.Site.Title&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Title&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt; :: &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$.Site.Title&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;title&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;partial&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;head.html&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;stylesheet&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/assets/css/gallery.css&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;relURL&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&amp;gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;stylesheet&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/assets/css/media.css&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;relURL&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;head&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$container&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cond&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;$.Site.Params.FullWidthTheme&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;default&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;container full&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;cond&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;$.Site.Params.CenterTheme&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;default&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;container center&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;container&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$container&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cond&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;$.Site.Params.oneHeadingSize&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;default&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34; headings--one-size&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;partial&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;header.html&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;block&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;main&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;block&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;footer&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;partial&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;footer.html&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;html&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="listhtml"&gt;list.html&lt;/h3&gt;&#10;&lt;p&gt;Für Übersichtsseiten wie &lt;code&gt;Artikel&lt;/code&gt;, &lt;code&gt;Tags&lt;/code&gt;, &lt;code&gt;Projekte&lt;/code&gt; benötige ich eine Listenansicht. Dabei möchte ich je vier Artikel in einer Zeile anzeigen. Jeder Artikel bekommt ein eigenes &amp;ldquo;Kärtchen&amp;rdquo; mit Titelbild (cover), Titel, Kurzbeschreibung und - falls Verfügbar - weiteren Details wie Lesezeit. Hugos &lt;code&gt;paginator&lt;/code&gt; crawlt den entsprechenden Ordner und stellt die Inhalte zusammen, wärend mein Stylesheet &lt;code&gt;list.css&lt;/code&gt; Formatierung und Anzeige übernimmt.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go-html-template" data-lang="go-html-template"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{- /* /layouts/_default/list.html */ -}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;define&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;main&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;stylesheet&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/assets/css/list.css&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;relURL&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;with&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Content&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;index-content&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;posts posts-grid&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;range&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Paginator.Pages&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;article&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;post on-list&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;a&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Permalink&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;post-card&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;aria-label&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Title&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;partial&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;cover.html&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;post-card-body&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;h4&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;post-title&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Title&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;markdownify&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;h4&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;post-excerpt&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Description&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Description&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;p&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;and&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.Param&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;readingTime&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;eq&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.Param&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;readingTime&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;post-reading-time&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.ReadingTime&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$.Site.Params.minuteReadingTime&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;default&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;min read&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;a&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;article&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;partial&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;pagination.html&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="singlehtml"&gt;single.html&lt;/h3&gt;&#10;&lt;p&gt;Meine &lt;code&gt;single,html&lt;/code&gt; ist fast identisch mit der Standardimplementierung von &lt;a href="https://github.com/panr/hugo-theme-terminal/blob/master/layouts/_default/single.html" target="_blank" rel="noopener noreferrer" class="external-link"&gt;terminal&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt;. Ich habe lediglich die Möglichkeit hinzugefügt, ein zum Titel gehöriges &amp;ldquo;banner-image&amp;rdquo; zu haben, und importiere die &lt;code&gt;_partial/cover.html&lt;/code&gt;-Vorschrift zum Laden eines Coverbildes.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go-html-template" data-lang="go-html-template"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;article&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;post&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;with&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Params.banner&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;img&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;post-banner&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;alt&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$.Params.banner_alt&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;plainify&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;default&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39; &amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; /&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Bei all den Änderungen könnte man überlegen, ein eigenes Theme zu forken&amp;hellip; 🤔&lt;/p&gt;&#10;&lt;h2 id="qualitätskontrolle"&gt;Qualitätskontrolle&lt;/h2&gt;&#10;&lt;p&gt;Neu ist für meine Website auch, dass ich auf tote Links prüfe. Die Seite ist erwachsen geworden und verfügt über so viele interne und externe Verlinkungen, dass dies manuell nicht mehr sinnvoll durchzuführen ist. Mit welchem Tool ich vorgehe und wie ich dabei Hugo-Eigenheiten berücksichtige, dokumentiert der Artikel zum Thema &lt;a href="https://blog.schallbert.de/hugo-link-checker/"&gt;&lt;code&gt;htmltest&lt;/code&gt;-Konfiguration für Hugo&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="veröffentlichung"&gt;Veröffentlichung&lt;/h2&gt;&#10;&lt;p&gt;Auch für Hugo benötige ich eine automatisierte Pipeline. Sobald ich eine Änderung nach &lt;code&gt;main&lt;/code&gt; schiebe, soll die Webseite automatisch neu gebaut und ausgeliefert werden. Wie das genau funktioniert beschreibe ich im Artikel &lt;a href="https://blog.schallbert.de/build-deploy-hugo-with-actions-docker-caddy/"&gt;Hugo-Website mit Github Actions in Docker bauen und ausliefern&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="leistung"&gt;Leistung&lt;/h2&gt;&#10;&lt;p&gt;Was der ganze Aufwand jetzt gebracht hat? Für &lt;em&gt;user&lt;/em&gt; ist Aussehen und Navigation sehr ähnlich zur Website in Jekyll. Die Verbesserungen machen sich allerdings durch schnellere Ladezeiten, geringere zu übertragende Datenmengen und bessere Übersichtlichkeit aus. Einendetaillierten Vergleich zwischen nehme ich im Artikel &lt;a href="https://blog.schallbert.de/hugo-versus-jekyll-benchmark/"&gt;&lt;em&gt;Jekyll&lt;/em&gt; vs. &lt;em&gt;Hugo&lt;/em&gt; Benchmarking&lt;/a&gt; vor.&lt;/p&gt;&#10;</description></item><item><title>Hugo: Bilder im Textfluss ausrichten</title><link>https://blog.schallbert.de/migrate-jekyll-to-hugo-image-alignment/</link><pubDate>Sat, 29 Aug 2026</pubDate><author>Schallbert</author><guid>https://blog.schallbert.de/migrate-jekyll-to-hugo-image-alignment/</guid><description type="html">&#10; &lt;img src="https://blog.schallbert.de/assets/images/posts/2026-08-29-image-positioning-cover.avif"&#10; class="post-cover"&#10; alt="Image: A screenshot of my blog, showing three images, one each aligned left, center, right. The centered image has no text flow."&#10; title="Hugo: Bilder im Textfluss ausrichten" /&gt;&#10;&lt;h2 id="warum-das-ganze"&gt;Warum das Ganze?&lt;/h2&gt;&#10;&lt;p&gt;Mein Theme kann aus dem klassischen Markdown &lt;code&gt;![Image Alt Text](/path/to/image/)&lt;/code&gt; keine Bildformatierung und -Positionierung ableiten. Das benötige ich aber, um Bilder links, mittig, und rechts zu platzieren - mit und ohne Textfluss. Also muss ich selbst ran und mir etwas programmieren.&lt;/p&gt;&#10;&lt;h2 id="einstieg-in-shortcodes-layouts-css"&gt;Einstieg in shortcodes, layouts, css&lt;/h2&gt;&#10;&lt;p&gt;Einen Überblick verschaffe ich mir auf &lt;a href="https://cshire.xyz/centering-images-in-hugo/" target="_blank" rel="noopener noreferrer" class="external-link"&gt;cshire&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; und stelle schnell fest, dass mein erster Versuch per &lt;code&gt;/layouts/render-image.html&lt;/code&gt; nicht funktioniert.&lt;/p&gt;&#10;&lt;h3 id="debugging"&gt;Debugging&lt;/h3&gt;&#10;&lt;p&gt;Auf diese Weise stelle ich fest, ob &lt;code&gt;render-image.html&lt;/code&gt; überhaupt gelesen und angewendet wird - und zwar unabhängig von CSS:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;style&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;border: 3px dashed red; padding: 10px; margin: 10px; font-weight: bold;&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; RENDER-IMAGE.HTML IS BEING READ!&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Das funktioniert. Also muss Hugo irgendwas in der Markdown-Verarbeitung entgehen.&lt;/p&gt;&#10;&lt;h3 id="ursachenbehebung"&gt;Ursachenbehebung&lt;/h3&gt;&#10;&lt;p&gt;Ich sehe nun, dass Hugo zwar das Layout rendert, meine Bilder aber nicht richtig auswertet. Warum? Weil zur Auswertung der Bilder ein Auslöser, genannt &lt;code&gt;shortcode&lt;/code&gt;, fehlt. Shortcodes in Hugo werden mit &lt;code&gt;{{ &amp;lt;shortcode-name&amp;gt; parameter1=&amp;quot;String&amp;quot; parametern=&amp;quot;string&amp;quot; }}&lt;/code&gt; im Markdown angelegt, mittels der entsprechenden Vorschrift &lt;code&gt;/layouts/shortcodes/&amp;lt;shortcode-name&amp;gt;.html&lt;/code&gt; ausgewertet und anschließend durch &lt;code&gt;CSS&lt;/code&gt; interpretiert dargestellt.&lt;/p&gt;&#10;&lt;h2 id="shortcode-imagehtml"&gt;Shortcode: image.html&lt;/h2&gt;&#10;&lt;p&gt;Ich habe mir also ein Shortcode-Template gebastelt, sodass ich dem Bild ein paar weitere Parameter zusätzlich zu Quelldatei &lt;code&gt;src&lt;/code&gt; und Alternativtext &lt;code&gt;alt&lt;/code&gt; mitgeben kann: &lt;code&gt;position, caption, attrid, attrlink&lt;/code&gt;. Position und Titel des Bildes sind selbsterklärend. Eine Attributionsmöglichkeit wollte ich für nicht selbsterstellte Bilder haben. Bei diesen greife ich entweder auf offene Inhalte unter Rechtsverhältnissen wie den &lt;a href="https://en.wikipedia.org/wiki/Creative_Commons" target="_blank" rel="noopener noreferrer" class="external-link"&gt;creative commons&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; zu oder besorge mir vorab das schriftliche Einverständnis der Urheberrechtsinhaberschaft.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#75715e"&gt;/* layouts/_shortcodes/image.html */&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; .&lt;span style="color:#a6e22e"&gt;Get&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;src&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;alt&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; .&lt;span style="color:#a6e22e"&gt;Get&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;alt&amp;#34;&lt;/span&gt; | &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;position&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; .&lt;span style="color:#a6e22e"&gt;Get&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;position&amp;#34;&lt;/span&gt; | &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;center&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;caption&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; .&lt;span style="color:#a6e22e"&gt;Get&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;caption&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;attrid&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; .&lt;span style="color:#a6e22e"&gt;Get&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;attrid&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;attrlink&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; .&lt;span style="color:#a6e22e"&gt;Get&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;attrlink&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#a6e22e"&gt;figure&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;media-frame media-frame--{{ $position }}&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;img&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;{{ $src }}&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;alt&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;{{ $alt }}&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;caption&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;figcaption&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;media-caption&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;span&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;caption-text&amp;#34;&lt;/span&gt;&amp;gt;{{ &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;caption&lt;/span&gt; }}&amp;lt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;span&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;and&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;attrid&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;attrlink&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;{{ $attrlink }}&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;attr-link&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;aria&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;label&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;Attribution {{ $attrid }}&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;sup&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;attr-id&amp;#34;&lt;/span&gt;&amp;gt;[{{ &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;attrid&lt;/span&gt; }}]&amp;lt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;sup&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;end&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;figcaption&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;end&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;figure&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Diese Vorlage liest die mitgegebenen Parameter aus dem Shortcode aus und packt das Bild &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; in einen Rahmen &lt;code&gt;&amp;lt;figure class=&amp;quot;media-frame&amp;quot;&amp;gt;&lt;/code&gt;. Dieser trägt die Positionsinformation. Sofern ein Bildtitel und/oder eine Attribution vorliegt, wird dies in der &lt;code&gt;figcaption class=&amp;quot;media-caption&amp;quot;&lt;/code&gt; abgebildet.&lt;/p&gt;&#10;&lt;h3 id="verwendung-des-shortcodes"&gt;Verwendung des Shortcodes&lt;/h3&gt;&#10;&lt;p&gt;In Markdown würde ein Bild mit &amp;ldquo;Vollausstattung&amp;rdquo; nun so aussehen:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{&amp;lt; &lt;span style="color:#a6e22e"&gt;image&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;/path/to/image.jpg&amp;#34;&lt;/span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;alt&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;Example placeholder image for shortcode demonstration purposes&amp;#34;&lt;/span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;caption&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;Shortcode demo image&amp;#34;&lt;/span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;attrid&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;1&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;attrlink&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;https://example.com/&amp;#34;&lt;/span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;position&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;right&amp;#34;&lt;/span&gt; &amp;gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="migration"&gt;Migration&lt;/h3&gt;&#10;&lt;p&gt;Nur wie komme ich jetzt von den bisher von mir in Jekyll verwendeten &lt;code&gt;![alt](/path/to/image) {: .align-center}&lt;/code&gt; in das oben angegebene Format?&lt;/p&gt;&#10;&lt;p&gt;Mit einem Skript! Dafür erstelle ich mir ein &lt;code&gt;python&lt;/code&gt;-Programm, welches durch jeden meiner Artikel kämmt und dort nach Bildern in der oben angegebenen Formatierung sucht. Bei einem Treffer extrahiert es &lt;code&gt;src, alt, position&lt;/code&gt; und ersetzt den kompletten Ausdruck zu einem Hugo-Shortcode-Äquivalent.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; os&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; re&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; pathlib &lt;span style="color:#f92672"&gt;import&lt;/span&gt; Path&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# spaces/tabs only, no newlines&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SPACES &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;r&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;[ \t]*&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;IMG_WITH_OPTIONAL_ALIGN &lt;span style="color:#f92672"&gt;=&lt;/span&gt; re&lt;span style="color:#f92672"&gt;.&lt;/span&gt;compile(&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;r&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;!\[([^\]]*?)\]\(([^)]*?)\)&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# alt, src&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; SPACES &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#75715e"&gt;# optional spaces/tabs before decorator&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;r&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;(?:\{:&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; SPACES &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#75715e"&gt;# literal &amp;#34;{:&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;r&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;[^}\n]*?\.align-(center|left|right)\b[^}\n]*?&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# decorator body (no newlines)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;r&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;\})?&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# optional &amp;#34;}&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;convert_image_alignments&lt;/span&gt;(directory):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;repl&lt;/span&gt;(m):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; alt &lt;span style="color:#f92672"&gt;=&lt;/span&gt; m&lt;span style="color:#f92672"&gt;.&lt;/span&gt;group(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;replace(&lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#34;&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#39;&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; src &lt;span style="color:#f92672"&gt;=&lt;/span&gt; m&lt;span style="color:#f92672"&gt;.&lt;/span&gt;group(&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; position &lt;span style="color:#f92672"&gt;=&lt;/span&gt; m&lt;span style="color:#f92672"&gt;.&lt;/span&gt;group(&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;) &lt;span style="color:#f92672"&gt;or&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# return built Hugo shortcode. Escape Python f-string curly brace { with {{.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#e6db74"&gt;f&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;{{{{&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;lt; image src=&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;src&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34; alt=&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;alt&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34; position=&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;position&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34; &amp;gt;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;}}}}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; root, _, files &lt;span style="color:#f92672"&gt;in&lt;/span&gt; os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;walk(directory):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; file &lt;span style="color:#f92672"&gt;in&lt;/span&gt; files:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; file&lt;span style="color:#f92672"&gt;.&lt;/span&gt;endswith(&lt;span style="color:#e6db74"&gt;&amp;#39;.md&amp;#39;&lt;/span&gt;):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;continue&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; filepath &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Path(root) &lt;span style="color:#f92672"&gt;/&lt;/span&gt; file&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; content &lt;span style="color:#f92672"&gt;=&lt;/span&gt; filepath&lt;span style="color:#f92672"&gt;.&lt;/span&gt;read_text(encoding&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; new_content &lt;span style="color:#f92672"&gt;=&lt;/span&gt; IMG_WITH_OPTIONAL_ALIGN&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sub(repl, content)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; new_content &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; content:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; filepath&lt;span style="color:#f92672"&gt;.&lt;/span&gt;write_text(new_content, encoding&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;f&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Updated: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;filepath&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; __name__ &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; project_root &lt;span style="color:#f92672"&gt;=&lt;/span&gt; input(&lt;span style="color:#e6db74"&gt;&amp;#34;Enter the path to your project root: &amp;#34;&lt;/span&gt;)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;strip()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;path&lt;span style="color:#f92672"&gt;.&lt;/span&gt;isdir(project_root):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; convert_image_alignments(project_root)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#34;Conversion complete!&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#34;Invalid directory path.&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Bei den Regexes habe ich mir von &lt;a href="https://mistral.ai/news/mistral-small-4/" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Mistral&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; helfen lassen, ansonsten ist das Skript aber einfach gehalten.&lt;/p&gt;&#10;&lt;p&gt;Bilder mit Titel und/oder Attribution waren in Jekyll als &lt;code&gt;figure&lt;/code&gt; deklariert. Auch für diese schreibe ich ein ganz ähnliches Skript und lasse es bei der Migration durchlaufen.&lt;/p&gt;&#10;&lt;h2 id="css"&gt;CSS&lt;/h2&gt;&#10;&lt;p&gt;Kommen wir zur Darstellung der Bilder. Ich erstelle eine seitenfüllende &lt;code&gt;CSS&lt;/code&gt;-Datei &lt;code&gt;/assets/css/media.css&lt;/code&gt;, welche außerdem Größe und Formatierung anderer eingebetteter Medien wie Audio- und Videodateien einheitlich sowohl für die mobile- als auch die Desktopansicht regeln soll. Dafür greift sie auf die in der Vorlage definierten &lt;code&gt;class=&lt;/code&gt;-Attribute zu.&lt;/p&gt;&#10;&lt;p&gt;Ich nehme zur Erläuterung mal einen Ausschnitt aus der Datei heraus: Hier lege ich das Verhalten des &lt;code&gt;media-frame&lt;/code&gt;-Objektes fest. Jedes Asset (Bild, Video, Audio) wird in einem Rahmen eingebettet, welcher der Darstellung die nötige Luft verschafft. Mit dem Attribut &lt;code&gt;position=&lt;/code&gt; wird definiert, wo und wie dargestellt werden soll.&lt;/p&gt;&#10;&lt;p&gt;Dabei sind die Inhalte standardmäßig zentriert und werden solange sie nicht größer sind als die maximale Textbreite in ihrer nativen Auflösung dargestellt.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;media-frame&lt;/span&gt; &lt;span style="color:#f92672"&gt;img&lt;/span&gt;&lt;span style="color:#f92672"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;media-frame&lt;/span&gt; &lt;span style="color:#f92672"&gt;audio&lt;/span&gt;&lt;span style="color:#f92672"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;media-frame&lt;/span&gt; &lt;span style="color:#f92672"&gt;video&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;display&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;block&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;width&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;auto&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;max-width&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;%&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;height&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;auto&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;padding&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;border&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;border-radius&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;media-frame--center&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin-left&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;auto&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin-right&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;auto&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/* Left/Right align only for Non-mobile use */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#66d9ef"&gt;media&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#f92672"&gt;min-width&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#f92672"&gt;768px&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;media-frame--left&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;left&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;max-width&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;60&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;%&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin-top&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.35&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;em&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin-right&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;rem&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin-bottom&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.75&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;rem&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;media-frame--right&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;right&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;max-width&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;60&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;%&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin-top&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.35&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;em&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin-left&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;rem&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin-bottom&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.75&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;rem&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Auf einer Seite ausgerichtete Bilder werden in der Breite begrenzt, denn es soll noch Textfluss drum herum stattfinden. Außerdem werden minimale Abstände zu anderen Objekten definiert, damit sich bei aufeinanderfolgenden Medien nicht Rahmen an Rahmen reibt. In der mobilen Ansicht ist der Platz so beengt, dass Bilder stets zentriert dargestellt werden.&lt;/p&gt;&#10;&lt;h2 id="galerie"&gt;Galerie&lt;/h2&gt;&#10;&lt;p&gt;Für den Fall, dass ich viele Bilder an einer zentralen Stelle anzeigen will, erstelle ich mir zusätzlich einen &lt;code&gt;gallery&lt;/code&gt;-Shortcode und zugehöriges CSS. Die Galerie zeigt Bilder in einem Raster an. Bewegt man die Maus über eines der Bilder, so erscheint es heller als die anderen. Klickt man auf ein Bild, so erscheint es in groß am unteren Rand der Galerie, wobei der oben bereits beschriebene &lt;code&gt;media&lt;/code&gt;-Shortcode wiederverwendet wird.&lt;/p&gt;&#10;&lt;p&gt;Die darzustellenden Bilder werden in der front matter des Markdown-Dokumentes als Liste per &lt;code&gt;src&lt;/code&gt; und &lt;code&gt;alt&lt;/code&gt; angelegt.&#10;Hier ein Ausschnitt aus der Vorlage zur Auswertung des Shortcodes.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#a6e22e"&gt;section&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;hugo-gallery&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;hugo-gallery__frame&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;hugo-gallery__grid&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;role&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;list&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;range&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;img&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;items&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;img&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;alt&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;img&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;alt&lt;/span&gt; | &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Gallery image %d&amp;#34;&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)) &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;thumbURL&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;p&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;TrimPrefix&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/assets/&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;with&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;resources&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Get&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;p&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;thumb&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; .&lt;span style="color:#a6e22e"&gt;Fit&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;400x220&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;thumbURL&lt;/span&gt; = &lt;span style="color:#960050;background-color:#1e0010"&gt;$&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;thumb&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;RelPermalink&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;end&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;hugo-gallery__thumb&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;#gallery-full-{{ $i }}&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;aria&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;label&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;{{ $alt }}&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;img&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;{{ $thumbURL }}&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;alt&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;{{ $alt }}&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;hugo-gallery__thumb-img&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;loading&lt;/span&gt;=&lt;span style="color:#e6db74"&gt;&amp;#34;lazy&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;end&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;}}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ich iteriere durch alle in der Frontmatter definierten Bilder, begrenze ihre Größe auf handliche &lt;code&gt;400x220px&lt;/code&gt; und ordne sie in einem Raster &lt;code&gt;class=hugo-gallery__grid&lt;/code&gt; an.&lt;/p&gt;&#10;&lt;h2 id="tests"&gt;Tests&lt;/h2&gt;&#10;&lt;p&gt;Das Erstellen der Vorlagen ging verhältnismäßig schnell. Mit &lt;code&gt;CSS&lt;/code&gt; stehe ich aber auf Kriegsfuß. Ständig funkt mir irgendein Override aus einer anderen Datei dazwischen oder ich komme mir selbst mit den Styles im Basis-CSS in die Quere. Daher benötige ich einen Ort zum Testen von Formatierung und Anordnung.&lt;/p&gt;&#10;&lt;p&gt;Daher habe ich eine Bild-testseite erstellt. Neugierig?&#10;&lt;a href="https://blog.schallbert.de/hugo-testing-image-alignment/"&gt;Prüfen der Darstellung von Medien in Hugo&lt;/a&gt;&lt;/p&gt;&#10;</description></item><item><title>htmltest-Konfiguration für Hugo</title><link>https://blog.schallbert.de/hugo-link-checker/</link><pubDate>Mon, 10 Aug 2026</pubDate><author>Schallbert</author><guid>https://blog.schallbert.de/hugo-link-checker/</guid><description type="html">&#10; &lt;img src="https://blog.schallbert.de/assets/images/posts/2026-08-10-htmltest-success-output-cover.avif"&#10; class="post-cover"&#10; alt="Image: An SSH public key randomart image as visual fingerprint for humans to quickly see if public keys match"&#10; title="htmltest-Konfiguration für Hugo" /&gt;&#10;&lt;p&gt;Nun bin ich mit dem &lt;a href="https://blog.schallbert.de/projects/migrating-jekyll-to-hugo/"&gt;Umzug meiner Website zu Hugo&lt;/a&gt; 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.&lt;/p&gt;&#10;&lt;p&gt;Der schieren Masse der Links komme ich ohne weitere Hilfsmittel nicht bei. Also benötige ich Werkzeug.&lt;/p&gt;&#10;&lt;h2 id="htmltest"&gt;htmltest&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="https://github.com/wjdp/htmltest" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Htmltest&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; ist ein Hilfsprogramm, das HTML-Dateien nach Problemen durchsuchen kann. Unter anderem spürt es defekte Links auf. Ich installiere es per&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Red Hat-based Linux package manager install command&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install htmltest&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;und wende es auf die von Hugo &amp;ldquo;gebauten&amp;rdquo; HTMl-Dateien im &lt;code&gt;/public&lt;/code&gt;-Verzeichnis an:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;htmltest public/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# [...]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;✘✘✘ failed in 2.890119823s&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;2612&lt;/span&gt; errors in &lt;span style="color:#ae81ff"&gt;337&lt;/span&gt; documents&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Das sind aber ganz schön viele Fehler! Die Darreichungsform erscheint mir außerdem ziemlich unübersichtlich, siehe Bild.&lt;/p&gt;&#10;&lt;figure class="media-frame media-frame--center"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/posts/2026-08-10-htmltest-error-note.avif" alt="Image: Output of a htmltest report in the console. It is completely filled with text. There are different error messages like &amp;#39;name resolution error&amp;#39;, &amp;#39;missing trailing slash&amp;#39; and so on. It is nowhere easy to read but mentions the source path of the issue."&gt;&lt;/figure&gt;&#10;&lt;h3 id="ausgabe-in-datei-umleiten"&gt;Ausgabe in Datei umleiten&lt;/h3&gt;&#10;&lt;p&gt;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 &lt;a href="https://en.wikipedia.org/wiki/Not_invented_here" target="_blank" rel="noopener noreferrer" class="external-link"&gt;not-invented-here&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; Syndrom anheim und programmierte selbst ein Werkzeug in &lt;em&gt;python&lt;/em&gt;, welches sich im Nachhinein als nicht gut genug entpuppte. Kurzgesagt:&lt;/p&gt;&#10;&lt;p&gt;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:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;htmltest public/ 2&amp;gt;&amp;amp;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; | ansi2html &amp;gt; htmltest-output.html&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;&#10;&lt;p&gt;Bedeutung: &amp;ldquo;Führe &lt;em&gt;htmltest&lt;/em&gt; im &lt;code&gt;/public/&lt;/code&gt;-Ordner aus. Leite Fehler aus &lt;code&gt;stderr&lt;/code&gt; in die Ausgabe &lt;code&gt;stdout&lt;/code&gt; um. Reiche die Ausgabe an &lt;em&gt;ansi2html&lt;/em&gt;&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; weiter. Schreibe dessen Ausgabe in eine Datei namens &lt;code&gt;htmltest-output.html&lt;/code&gt;.&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;figure class="media-frame media-frame--center"&gt;&#10; &lt;img src="https://blog.schallbert.de/assets/images/posts/2026-08-10-htmltest-ansi2html-output.avif" alt="Image: Output of a htmltest report in html after piping through ansi2html, opened with a browser. The lines are formatted properly and have colour coding. Looks neat."&gt;&lt;/figure&gt;&#10;&lt;p&gt;Das sieht doch so schon viel besser aus!&lt;/p&gt;&#10;&lt;h3 id="fehlerkategorien"&gt;Fehlerkategorien&lt;/h3&gt;&#10;&lt;p&gt;Die mit &lt;em&gt;htmltest&lt;/em&gt; gefundene Fehler lassen sich für meine Zwecke in ein paar wenige Kategorien sortieren:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Hugo-intern bedingte Fehler wie durch &lt;code&gt;livereload.js&lt;/code&gt; verursachte &lt;code&gt;target does not exist&lt;/code&gt;-Meldungen.&lt;/li&gt;&#10;&lt;li&gt;Unvollständige Links, die zwar in der Praxis funktionieren, aber &lt;code&gt;href lacks trailing slash&lt;/code&gt;-Fehler erzeugen. Diese Art Fehler machen bei mir den Löwenanteil der berichteten Probleme aus.&lt;/li&gt;&#10;&lt;li&gt;Lookup-Fehler &lt;code&gt;GET &amp;lt;src&amp;gt; [...] failure in name resolution&lt;/code&gt;, bei fehlender Verbindung, unzureichenden Rechten, aktiver Bot-Abwehr oder wenn der Zielserver offline ist&lt;/li&gt;&#10;&lt;li&gt;Harte, durch defekte Links erzeugte &lt;code&gt;target does not exist&lt;/code&gt;-Fehler. Genau diese wollte ich eigentlich beheben.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h3 id="das-log-bereinigen"&gt;Das Log bereinigen&lt;/h3&gt;&#10;&lt;p&gt;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.&lt;/p&gt;&#10;&lt;p&gt;Fehler der Kategorie 1, die durch Hugos nützliche &lt;code&gt;livereload&lt;/code&gt;-Funktion hervorgerufen werden, sehen so aus:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code class="language-log" data-lang="log"&gt; target does not exist --- en/tags/tools/index.html --&amp;gt; /livereload.js?mindelay=10&amp;amp;v=2&amp;amp;port=1313&amp;amp;path=livereload&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;LiveReload ist diejenige Funktion, die mir ständiges &lt;code&gt;F5&lt;/code&gt;-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.&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;hugo server --disableLiveReload&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;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 &lt;code&gt;-s, --skip-external&lt;/code&gt; in &lt;em&gt;htmltest&lt;/em&gt;:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;htmltest -s public/ 2&amp;gt;&amp;amp;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; | ansi2html &amp;gt; htmltest-output.html&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# [...]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;✘✘✘ failed in 494.7678ms&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;446&lt;/span&gt; errors in &lt;span style="color:#ae81ff"&gt;337&lt;/span&gt; documents&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Tote externe Links kann ich zu einem späteren Zeitpunkt beheben; nun will ich erstmal die durch die Migration entstandenen Probleme lösen.&lt;/p&gt;&#10;&lt;h2 id="missing-trailing-slash-fehlerbehebung-per-markup"&gt;&amp;ldquo;Missing trailing slash&amp;rdquo;: Fehlerbehebung per Markup&lt;/h2&gt;&#10;&lt;p&gt;Mit den vielen &lt;code&gt;href lacks trailing slash&lt;/code&gt;-Fehlern tue ich mich lange zeit schwer, müsste ich doch an fast jeden Markdown-Link in jedem Artikel ein &lt;code&gt;/&lt;/code&gt; anfügen. Zum Glück finde ich eine Lösung in meinem Markup &lt;code&gt;render-link.html&lt;/code&gt;:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go-html-template" data-lang="go-html-template"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{- /* /layouts/_markup/render-link.html */ -}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Destination&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;safeURL&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_external&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;or&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.HasPrefix&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.HasPrefix&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;https://&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_anchor&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.HasPrefix&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;#&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_asset&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.HasPrefix&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/assets/&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[...]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{- /* Add / to internal paths that have no file extension */ -}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;and&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_external&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_anchor&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_asset&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$parsed&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;urls&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.Parse&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;and&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$parsed&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.HasSuffix&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$parsed&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.Path&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;))&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;eq&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.Ext&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$parsed&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.Path&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;printf&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;%s/&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[...]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;&#10;&lt;p&gt;Bedeutung: Interne Links, die weder auf Überschriften &lt;code&gt;is_anchor&lt;/code&gt; noch Mediendateien &lt;code&gt;is_asset&lt;/code&gt; verweisen, bekommen genau dann ein &lt;code&gt;/&lt;/code&gt; angehangen, wenn sie eine korrekte Syntax aufweisen &lt;code&gt;parsed&lt;/code&gt; und noch keinen Slash am Ende der URL vorweisen können.&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;Dies löst 95% der Fehlermeldungen durch weniger hässliches &lt;code&gt;html&lt;/code&gt;. Die restlichen 5% hole ich mir durch Anhängen von ein paar Slashes in der Hugo-Konfiguration. Beispiele:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# hugo.yml&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;url&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;/en/&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# /en -&amp;gt; /en/ &lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;logoHomeLink&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;/en/&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# /en -&amp;gt; /en/&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Fertig! Übrig bleiben nur noch harte, interne Fehler.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;htmltest -s public/ 2&amp;gt;&amp;amp;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; | ansi2html &amp;gt; htmltest-output.html&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# [...]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;✘✘✘ failed in 359.28ms&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;102&lt;/span&gt; errors in &lt;span style="color:#ae81ff"&gt;84&lt;/span&gt; documents&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="manuelles-suchen-und-beheben"&gt;Manuelles Suchen und Beheben&lt;/h2&gt;&#10;&lt;p&gt;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.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-md" data-lang="md"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;### Überschrift {#heading3}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;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.&lt;/p&gt;&#10;&lt;h2 id="das-ergebnis"&gt;Das Ergebnis&lt;/h2&gt;&#10;&lt;p&gt;Nach ein paar Stunden anstrengender und dröger Handrbeit werde ich belohnt:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;htmltest public/ -s 2&amp;gt;&amp;amp;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Skipping the checking of external links.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;htmltest started at 10:51:23 on public&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;========================================================================&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;✔✔✔ passed in 238.970354ms&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tested &lt;span style="color:#ae81ff"&gt;338&lt;/span&gt; documents&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Bald kann ich mit meiner neuen alten Seite online gehen!&lt;/p&gt;&#10;&lt;div class="footnotes" role="doc-endnotes"&gt;&#10;&lt;hr&gt;&#10;&lt;ol&gt;&#10;&lt;li id="fn:1"&gt;&#10;&lt;p&gt;&lt;a href="https://packages.debian.org/en/sid/colorized-logs" target="_blank" rel="noopener noreferrer" class="external-link"&gt;ansi2html bzw. colorized-logs&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; ist ein Hilfsprogramm, welches Konsolenausgabe inkl. Formatierung und Textfarben in &lt;code&gt;html&lt;/code&gt; umwandelt.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;/div&gt;&#10;</description></item><item><title>Hugo Multi-Lang: Interne Permalinks</title><link>https://blog.schallbert.de/hugo-create-language-specific-permalinks/</link><pubDate>Mon, 27 Jul 2026</pubDate><author>Schallbert</author><guid>https://blog.schallbert.de/hugo-create-language-specific-permalinks/</guid><description type="html">&#10; &lt;img src="https://blog.schallbert.de/assets/images/posts/2026-07-07-defaultcontentlanguage-in-hugo-config.avif"&#10; class="post-cover"&#10; alt="Image: A section in the hugo.yml file setting defaultContentLanguage and related parameters."&#10; title="Hugo Multi-Lang: Interne Permalinks" /&gt;&#10;&lt;p&gt;Wer in Hugo wie ich einen mehrsprachigen Blog baut, könnte folgendes Problem kennen:&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;Interne Links in Artikeln verschiedener Sprachen verweisen nur auf Seiten in der Standard-Sprache.&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;h2 id="konfiguration"&gt;Konfiguration&lt;/h2&gt;&#10;&lt;p&gt;Grundlage für das Problem ist die folgende Einstellung:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# hugo.yml&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;defaultContentLanguage&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;de&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;defaultContentLanguageInSubdir&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;disableDefaultLanguageRedirect&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Meine Standardsprache ist Deutsch und zugehörige Artikel werden in das Hauptverzeichnis des Blogs gebaut. Eine Weiterleitung in das Sprachverzeichnis &lt;code&gt;/de&lt;/code&gt; findet nicht statt.&lt;/p&gt;&#10;&lt;p&gt;Die Verzeichnisstruktur lautet:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── content&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── de&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── about.md&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── announcements&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── legal.md&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── posts&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ ├── privacy.md&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ │ └── projects&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── en&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── about.md&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── legal.md&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── posts&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── privacy.md&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── projects&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="das-problem-mit-der-standardsprache"&gt;Das Problem mit der Standardsprache&lt;/h2&gt;&#10;&lt;p&gt;Ich halte Artikel durch Nutzung von &lt;a href="https://gohugo.io/content-management/urls/#slug" target="_blank" rel="noopener noreferrer" class="external-link"&gt;slug&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; in meiner Standardsprache unter Adressen erreichbar wie &lt;code&gt;example.com/my-post&lt;/code&gt;, &lt;code&gt;example.com/my-2nd-post/&lt;/code&gt;.&#10;In der Zweitsprache hingegen erscheinen sie als &lt;code&gt;example.com/en/my-post&lt;/code&gt;, &lt;code&gt;example.com/en/my-2nd-post/&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;Wenn ich zwei Artikel nun intern verlinken möchte, dann verweist der Link stets auf den Artikel meiner Standardsprache.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# English version of my post&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# example.com/en/my-post&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;slug&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;my-post&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;Post&amp;#39;s English content&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[&lt;span style="color:#ae81ff"&gt;2nd](/my-2nd-post) &lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ich erreiche damit statt des gewünschten &lt;code&gt;/en/my-2nd-post&lt;/code&gt; nur die deutsche Version &lt;code&gt;/my-2nd-post&lt;/code&gt;. Das finde ich blöd, denn so müsste ich jeden Link in allen Artikeln manuell anpassen. Leider scheint Hugo dafür keine eingebaute Lösung mitzubringen. Also erstelle ich mir eine Vorschrift, wie Links gerendert werden sollen:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go-html-template" data-lang="go-html-template"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{- /* /layouts/_markup/render-link.html */ -}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="lösung-sprachabhängige-link-prefixes"&gt;Lösung: Sprachabhängige Link-Prefixes&lt;/h2&gt;&#10;&lt;p&gt;Dort soll folgendes passieren: Wenn beim Bauen ein relativer Link innerhalb der Seite gefunden wird, so ist genau dann ein Sprachpräfix wie &lt;code&gt;/en&lt;/code&gt; vor diesen Link zu setzen, wenn die Sprache der zu rendernden Seite nicht der Standardsprache entspricht (denn für letztere benötige ich wegen &lt;code&gt;defaultContentLanguageInSubdir: false&lt;/code&gt; keinen Sprachpräfix).&lt;/p&gt;&#10;&lt;h3 id="standardsprache-auslesen"&gt;Standardsprache auslesen&lt;/h3&gt;&#10;&lt;p&gt;Nur wie komme ich an die Standardsprache? Die Parameter &lt;code&gt;defaultContentLanguage&lt;/code&gt; sind in Templates nicht zugänglich. Nach längerer Recherche finde ich eine passende Lösung für das Problem in der &lt;a href="https://discourse.gohugo.io/t/is-there-a-way-to-retrieve-the-value-of-defaultcontentlanguage/9643" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Hugo community&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt;: Die Standardsprache ist meist die erste Sprache des gewichtsbasierten Index (welcher die &lt;a href="https://gohugo.io/configuration/languages/" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Sprachen nach Reihenfolge&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt; erscheinen lässt): &lt;code&gt;index .Page.Site.Home.AllTranslations 0 &lt;/code&gt; Wenn ich diesen nun auslese, ist die &amp;ldquo;erste&amp;rdquo; meine Standardsprache.&lt;/p&gt;&#10;&lt;h3 id="code-für-render-linkhtml"&gt;Code für render-link.html&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go-html-template" data-lang="go-html-template"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{- /* /layouts/_markup/render-link.html */ -}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Destination&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;safeURL&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$currentLang&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Page.Language.Locale&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_external&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;or&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.HasPrefix&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.HasPrefix&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;https://&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_anchor&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.HasPrefix&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;#&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_asset&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.HasPrefix&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/assets/&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_lang_prefixed&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.HasPrefix&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;printf&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/%s/&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$currentLang&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_anchor&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;printf&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;%s%s&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Page.RelPermalink&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_external&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;and&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_lang_prefixed&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_asset&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Page.Language.IsDefault&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;printf&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/%s%s&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$currentLang&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{- /* Add / to internal paths that have no file extension */ -}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;and&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_external&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_anchor&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_asset&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$parsed&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;urls&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.Parse&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;and&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$parsed&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.HasSuffix&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$parsed&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.Path&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;))&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;eq&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.Ext&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$parsed&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.Path&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;printf&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;%s/&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;a&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;relURL&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_external&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;target&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;_blank&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;noopener noreferrer&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;external-link&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;}}&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Text&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;safeHTML&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_external&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;span&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;external-link-icon&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;aria-hidden&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&amp;gt;↗&amp;lt;/&lt;span style="color:#f92672"&gt;span&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;a&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Solange die Standardsprache und der Gewichtsindex übereinstimmen, d.h. die Standardsprache ganz oben auftaucht, funktioniert dies prima.&lt;/p&gt;&#10;&lt;h3 id="zusatzfunktionen"&gt;Zusatzfunktionen&lt;/h3&gt;&#10;&lt;p&gt;Was der Code sonst noch macht:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Prüfung, ob Links nach &amp;ldquo;extern&amp;rdquo;, also von meiner Site weg gehen. Jene bekommen dann ein eigenes Fenster und den Indikator &lt;code&gt;↗&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Prüfung, ob der Link auf eine Überschrift &amp;ldquo;anchor&amp;rdquo; führt. Details dazu siehe unten.&lt;/li&gt;&#10;&lt;li&gt;Prüfung, ob der Link zu einer (Medien-)Datei &amp;ldquo;asset&amp;rdquo; führt. Asset-Links werden nicht modifiziert.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;Handelt es sich um einen Überschriftslink, so wird dieser gegebenenfalls auf die vollständige URL ergänzt. Das geschieht nach folgendem Schema: &lt;code&gt;#heading --&amp;gt; /&amp;lt;opt_lang&amp;gt;/&amp;lt;opt_category&amp;gt;/&amp;lt;title&amp;gt;/#heading&lt;/code&gt;&lt;/p&gt;&#10;&lt;h2 id="permalinks"&gt;Richtig auflösende Permalinks auf Überschriften&lt;/h2&gt;&#10;&lt;p&gt;Auch für hochspezielle Permalinks innerhalb einer Seite habe ich eine Lösung gefunden. Nehmen wir an, ich habe verschiedensprachige Überschriften :&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# German&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# content/de/posts/yyyy-mm-dd-hugo-create-language-specific-permalinks.md&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;description&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Mit _markup interne Links richtig routen&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;title&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Hugo Multi-Lang: Interne Permalinks&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;slug&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;hugo-create-language-specific-permalinks&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;## Richtig auflösende Permalinks auf Überschriften {#permalinks}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;Lorem Ipsum...&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# English&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# /content/en/posts/yyyy-mm-dd-hugo-create-language-specific-permalinks.md&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;description&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Routing internal links with _markup&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;title&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Hugo Multi-Lang: Internal Permalinks&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;slug&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;hugo-create-language-specific-permalinks&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;## Correct Permalinks to headings {#permalinks}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;Lorem Ipsum...&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Dann sollte ein Klick auf &lt;a href="https://blog.schallbert.de/hugo-create-language-specific-permalinks/#permalinks"&gt;diesen Link zurück zur Überschrift #permalinks&lt;/a&gt; sprachunabhängig wieder zurück zur Überschrift führen. Schlüssel für diese Lösung ist das Einführen einer Überschriftsdefinition (&lt;a href="https://www.markdownlang.com/cheatsheet/headings.html#heading-ids-extended-syntax" target="_blank" rel="noopener noreferrer" class="external-link"&gt;Heading-ID&lt;span class="external-link-icon" aria-hidden="true"&gt;↗&lt;/span&gt;&lt;/a&gt;) in Markdown, in diesem Fall &lt;code&gt;{#permalinks}&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h3 id="funktioniert-so-noch-nicht"&gt;Funktioniert so noch nicht.&lt;/h3&gt;&#10;&lt;p&gt;Weil &lt;code&gt;#permalinks&lt;/code&gt; auf &lt;code&gt;&amp;lt;blog's baseurl&amp;gt;/#permalinks&lt;/code&gt; verweist und somit der Link auf die aktuelle Seite fehlt. Doch auch das bekommen wir hin: Ich erweitere den Link-Renderer um ein paar Zeilen Code und gebe die aktuelle Seiten-URL als Präfix hinzu.&lt;/p&gt;&#10;&lt;h3 id="code-für-render-linkhtml-mit-unterstützung-für-überschriften"&gt;Code für render-link.html mit Unterstützung für Überschriften&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go-html-template" data-lang="go-html-template"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_anchor&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;.HasPrefix&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;#&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$is_anchor&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;printf&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;%s%s&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;.Page.RelPermalink&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$url&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;-}}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nun wird &lt;code&gt;(#permalinks)&lt;/code&gt;erweitert zu &lt;code&gt;/hugo-create-language-specific-permalinks/#permalinks&lt;/code&gt;, sodass der Link endlich zum Ziel führt.&lt;/p&gt;&#10;</description></item></channel></rss>