Metadaten in Hugo
In Hugo werden Metadaten in der sogenannten Frontmatter definiert. Einige der vordefinierten Felder werden nur dadurch wirksam, dass wir im Rahmen von Layouts auf sie zugreifen. So lassen sich die in den Markup-Dateien gespeicherten Informationen in standardisierter Form in den HTML-Code einfügen. Andere Felder werden hingegen automatisch während des Build-Vorgangs der Webseite berücksichtigt.
Dieser Artikel gibt einen Überblick darüber, wie solche Felder definiert werden und welche Informationen sinnvollerweise in der Frontmatter gespeichert werden sollten.
Datenformate
Hugo unterstützt für die Frontmatter verschiedene Formate: YAML, TOML und JSON. In der Praxis gibt es kaum entscheidende Vor- oder Nachteile zwischen ihnen; man kann einfach das Format wählen, dessen Syntax einem am ehesten zusagt. Persönlich bevorzuge ich YAML.
JSON gruppiert notwendig mit Klammern, was für einfach strukturierte Daten unnötig erscheint. Gegen TOML spricht meinem Eindruck nach die etwas umständliche Handhabung hierarchischer Daten. Listen werden in Array-Syntax dargestellt: [a, "b", 2]
. Bei ineinander verschachtelten Strukturen müssen die Tabellenköpfe wiederholt werden: [servers]
, dann [servers.alpha]
, dann [servers.alpha.a]
.
Wir können Datenstrukturen auch in YAML durch die eben anführten Klammer-Literale notieren. Doch wir können die skalaren Elemente von Strukturen auch einfach auflisten, wie man es mit ungeordneten Listen in Markdown machen würde. Bei verschachtelten Strukturen werden die Ebenen dadurch gruppiert, dass man sie syntaktisch bedeutungsvoll einrückt.
String-Werte können in YAML ohne Anführungszeichen geschrieben werden, auch wenn sie Leerzeichen enthalten. Anführungszeichen sind nur erforderlich, wenn ein reserviertes Zeichen wie :
im String vorkommt. Zahlen- und Datumsangaben wie 12
oder 2014-12-31
werden in YAML automatisch als entsprechende Datentypen erkannt. In Ausnahmefällen könnten sie dennoch in Anführungszeichen gesetzt werden ("12"
).
Empfohlene Verwendung vordefinierter Felder
Die Doku
empfiehlt, in der Frontmatter jeder Seite zumindest title
und date
festzulegen. Diese Felder haben nur dann einen Effekt, wenn sie in Layouts verwendet werden.
Für die meisten Benutzer ist es sinnvoll, diese Informationen in den HTML-Head zu integrieren und mit den Daten aus der Frontmatter zu füllen. Standards wie schema.org oder Dublin Core definieren darüber hinaus, wie Metadaten strukturiert und maschinenlesbar bereitgestellt werden sollten. Wer ein Interesse daran hat, kann die Metadaten der Frontmatter nutzen, um die Empfehlungen dieser Guidelines umzusetzen.
Informationen über Inhalte
Der Titel sollte immer im Head einer Seite enthalten sein. Er erscheint nicht nur in der Titelleiste oder im Tab des Browsers, sondern spielt auch eine wichtige Rolle für die Suchmaschinenoptimierung. Im Base-Layout könnte dies folgendermaßen umgesetzt werden:
{{ if .Page.Title }}<title>{{ .Page.Title }}</title>{{ end }}
Zwei Felder erlauben es, Hauptinhalte in kompakter Form wiederzugeben. Das description
-Feld ergänzt den Titel um eine allgemeine
Beschreibung. Diese wird im Head der Seite durch ein entsprechendes Meta-Tag bereitgestellt, das mithilfe der PAGE.Description
-Methode erstellt wird:
<meta name="description" content="{{ if .Params.description }} {{ .Params.description }}{{ end }}" />`.
Diese Beschreibung kann unter anderem von Google für die Snippets in Suchergebnissen genutzt werden.
Davon zu unterscheiden ist das summary
-Feld. Es wird für Inhaltsausschnitte genutzt, die für den Besucher sichtbar sind, beispielsweise in Exzerpten einzelner Blogbeiträge. Diese Zusammenfassungen können in Layouts über die PAGE.Summary
-Methode eingefügt werden.
Zeitliche Informationen und Festlegungen
Mit date
wird dokumentiert, wann eine Seite ursprünglich veröffentlicht wurde. Wenn
Archetypen verwendet werden, kann das aktuelle Datum beim Erstellen einer Markup-Datei automatisch in die Frontmatter eingefügt werden. Bei manuellen Eingaben empfiehlt es sich, ein einfaches Datumsformat wie YYYY-MM-DD
nutzen.
Während dieses Datum für den Autor von Interesse sein kann, dient es in erster Linie dazu, den Besuchern der Seite das Veröffentlichungsdatum zu präsentieren. Der Webentwickler hat die Freiheit zu entscheiden, wo diese Information sichtbar eingefügt wird. In Layouts kann das Datum über die PAGE.Date
-Methode eingebunden werden.
Dabei ist man nicht auf das Datumsformat beschränkt, das in der Frontmatter verwendet wird. Mit time.Format lässt sich die Darstellungsform anpassen. Bei mehrsprachigen Seiten werden Wörter wie Monatsnamen automatisch übersetzt.
Zusätzlich kann man in lastmod
festhalten, wann Inhalte zuletzt bearbeitet wurden. Dies ist besonders wichtig für Themen, die einem schnellen Wandel unterliegen. In solchen Fällen sollten Besucher informiert werden, wie aktuell die Informationen sind. Die PAGE.Lastmod
-Methode wird verwendet, um dieses Datum in den Layouts anzuzeigen.
Mehrere Felder betreffen den Veröffentlichungsstatus der in Frage stehenden Seite. Mit dem draft
-Feld kann durch einen booleschen Wert festgelegt werden, ob die Seite noch als Entwurf betrachtet wird. Ist der Wert true
gesetzt, erscheint die Seite nicht auf der veröffentlichten Webseite. Mit publishDate
kann eingestellt werden, ab wann eine Seite auf der Webseite abrufbar ist, während das expiryDate
ein Datum festlegt, ab dem die Seite nicht mehr angezeigt werden soll.
Klassifikation von Inhalten
In der Frontmatter kann explizit der Typ einer Seite definiert werden. Die Festlegung im type
-Feld hat Vorrang gegenüber dem Typ, der sich aus Sektionszugehörigkeit ergibt. Es kann ein gleichnamiges Layout angelegt werden, womit man mehr Kontrolle darüber hat, welche weiteren Inhalte für Seiten eingefügt werden sollen. Damit sind auch seitenspezifische Layouts möglich.
Durch sogenannte Taxonomien können Inhalte in der Frontmatter mit Schlagworten klassifiziert werden. Dieses Thema wird in einem Teil der Serie zur Inhaltsverwaltung ausführlich besprochen.
Eine maßgefertigte Organisation der Seite durch eigene URLs
URLs folgen in Hugo standardmäßig der Verzeichnisstruktur unter content/
. Entwickler müssen diesem Grundprinzip jedoch nichts zwangsweise folgen. Je stärker man vom Standard abweicht, desto größer ist der Mehraufwand.
URLs individuell für Einzelseiten festlegen
Wer lediglich die letzte Komponente der URL einer Einzelseite abändern möchte, kann das slug
Feld in der Frontmatter der entsprechenden Markup-Datei verwenden. Dadurch wird die Einzelseite über den Wert für diesen Schlüssel und nicht über den Dateinamen (ohne Dateiendung) aufgerufen.
Mit dem url
-Feld kann man die gesamte URL beeinflussen. Oder genauer gesagt auf den Teil der URL, der nach der Basis-URL kommt, die in der Hauptkonfiguration festgelegt wird. Nehmen wir das Beispiel aus der
offiziellen Dokumentation. Angenommen https://domain.com/
ist die Basis-URL. Wenn wir eine Datei unter content/posts/post-1.md
erstellen und in ihrer Frontmatter url = '/articles/my-first-article.html'
festlegen, dann ist die entsprechende Seite unter https://domain.com/articles/my-first-article.html
erreichbar.
Es ist wichtig zu beachten, dass bei einer mehrsprachigen Webseite – und nur bei einer mehrsprachigen Webseite – das vorangestellte /
im url
-Feld einen Unterschied macht: Nur ohne vorangestelltes /
wird zwischen Basis-URL und url
-Wert das Präfix für die Sprache eingefügt. Bei einer einsprachigen Seite macht es prinzipiell keinen Unterschied, die Variante ohne /
ist jedoch schlicht die technisch korrekte Option (wir wollen keine zwei /
in der URL).
Permalinks
Permalinks fallen in eine ähnliche Kategorie. Sie erlauben es, URLs für die Sektionen festzulegen, die sich auf der obersten Ebene des content/
-Verzeichnisses befinden. Damit kann der hintere Teil einer URL wie domain.com/name-of-section/
durch beliebige andere URL-Komponenten ersetzt werden.
Permalinks werden in der Hauptkonfiguration definiert und folgen dem Muster:
[permalinks]
[permalinks.section]
name-of-section = '/what/you/want/instead/'
Wenn der Wert nur eine Komponente hat, dann wäre das gleichbedeutend damit, dass man das content/name-of-section
-Verzeichnis umbenannt hätte.
Mit Version v0.131.0 wurden sogenannte Permalink-Tokens hinzugefügt, die das Feature weitaus nützlicher machen. Damit können bei der URL der Einzelseiten vom entsprechenden Typ weitere Komponenten hinzugefügt werden, deren Werte sich aus der Frontmatter ergeben.
Zu den nützlichen Tokens gehören insbesondere :year
, :month
(oder :monthname
) und :day
. Sie sind hilfreich, um beispielsweise das Datum in die URL von Blogbeiträgen einzufügen. Häufig wird auch :filename
(oder slugorfilename
) verwendet, um den Dateinamen in die URL zu integrieren, ebenso wie den Namen der :section
.
Permalink-Tokens werden entweder im Wert für das url
-Feld verwendet oder in einem weiteren Eintrag der Hauptkonfiguration hinzugefügt:
[permalinks]
[permalinks.page]
blog = '/:section/:year-:month-:day-:slugorfilename/'
Permalinks können nicht nur für Sektionen, sondern auch für Taxonomie-Terme definiert werden.
[permalinks]
[permalinks.term]
tags = '/:slug/'
Ein Beitrag, dessen Hauptinhalt unter content/blog/post-1.md
festgelegt wird und dessen Frontmatter date: 2024-08-24
enthält, wäre damit unter domain.com/blog/2024-08-24-post-1/
erreichbar.
Bei mehrsprachigen Webseiten empfiehlt es sich unter Umständen, Permalinks relativ zu den einzelnen Sprachen zu definieren. Dazu werden sie unter [languages]
definiert:
[languages]
[languages.de]
[languages.de.permalinks]
[permalinks.page]
blog = '/blogbeitraege/:year-:month-:day-:slugorfilename/'