Wie schon erwähnt, benutzt Hugo das Script layouts/ftpedia/list.html
zur Darstellung aller pages in der section ft:pedia,
außer den beiden Übersichten für den Gesamtinhalt und die gesamten Extras.
Wir haben dafür 4 verschiedene Inhalts-Typen:
content/ftpedia/_index.md
)content/ftpedia/yyyy/_index.md
)content/ftpedia/yyyy/yyyy-n/_index.md
)content/ftpedia/yyyy/yyyy-n/_index.md
)Je nach Typ ist eine unterschiedliche Darstellung gewünscht. Die notwendige Unterscheidung funktioniert nun wie folgt: Je nach Inhalts-Typ sind im Frontmatter unterschiedliche Einträge vorhanden. Mit Beschränkung auf die Kernangaben (es gibt noch ein paar mehr aber die spielen hier keine Rolle) ergibt sich diese Übersicht:
Typ | Darstellung | layout: | launchDate: | publishDate: |
---|---|---|---|---|
Sektionswurzel | Gesamtübersicht jahrgangsweise | ftpediaAll | - | - |
Jahrgang | Übersicht der Ausgaben eines Jahres | - | - | - |
Ausgabe | Einzelne Ausgabe | issue | - | x |
Teaser | Teaser für die kommende Ausgabe | teaser | x | - |
Die Wurzel erkennt man am Vorhandensein des layout: ftpediaAll
oder
auch am Fehlen der beiden Datümer. Letzteres ist allerdings (entgegen der
Hugo-Doku) nicht mit where
möglich. Es funktioniert jedoch mit with
oder
auch if
- der Grund dafür ist nicht bekannt.
Für einen Jahrgang sind weder Layout noch die beiden Datümer angegeben.
Eine einzelne Ausgabe weist sich durch ein Layout issue
aus. Die Angabe des Layouts ist
erforderlich.
Auch wenn wir es vielleicht nie verwenden, die Möglichkeit, eine Ausgabe vorab hochzuladen,
aber erst am Stichtag - automatisch (cronjob) - zu veröffentlichen, ist
durch die Angabe eines publishDate
explizit gegeben. Dieses publishDate
wird nämlich von Hugo beim Seitenbau ausgewertet!
Liegt das Datum publishDate
in der Zukunft, wird die betroffene Seite
nicht gebaut. Wenn so ein Frontmatter ein date:
Feld hat, aber kein publishDate
,
dann gibt Hugo bei einer Abfrage von publishDate
den Wert von date
zurück.
Die zusätzliche Angabe eines
publishDate:
im Frontmatter überschreibt diese Automatik mit dem gewünschten
Datum.
Der Teaser (das Appetithäppchen mit der verschwommenen Vorschau) hat das
Layout teaser
und zusätzlich ein launchDate
. Mir fiel halt keine bessere
Übersetzung für ‘erscheint-am-datum’ ein. Der Teaser hat üblicherweise eine
Lebensdauer von wenigen Tagen und sollte nur ein einziges Mal vorkommen. Gibt
es aus Versehen mehrere Teaser, baut Hugo halt entsprechend viele
Teaser-Seiten. Die Angabe des Layouts ist erforderlich.
Das Script unterscheidet nun anhand einer einfachen Auswahllogik die diversen Darstellungsformen:
In der Gesamtübersicht und in der Jahrgangsansicht wird der Teaser wie ein Einzelheft dargestellt, aber minimal anders behandelt. Dazu später mehr.
Auf geht’s, ab in den Code!
Zuerst bekommt die Seite eine Sicherheitsabfrage gegen vergessene Titel
title:
und ihren “Rahmen”:
{{ define "main" }}
{{ if not .Title }}
{{ errorf "Oh oh, der Seitentitel 'title' fehlt oder ist leer in Seite %q" .Path }}
{{ end }}
{{ $date_format_string := "02.01.2006" }}
<div class="padding highlightable">
{{ partial "topbar.html" . }}
Dabei steuert partial "topbar.html" .
die Breadcrumbs bei.
Das ist hier die Zeile
Start > Website (Technik) > ft:pedia > Script - list.html
am oberen Bildrand.
Nun wird abgefragt, ob im Frontmatter ein Layout layout:
definiert ist
(siehe oben). Ist das der Fall, kommt sofort die nächste Frage, ob es sich um
layout: "issue"
handelt.
{{ if .Layout }}
{{ if eq .Layout "issue" }}
Bei wiederum erfoglreicher Abfrage, haben wir eine
Die Codesequenz
{{/* --- Überprüfe ob die Pflichtangaben alle vorhanden sind --- */}}
{{/* --- Check if all mandatory field entries are available --- */}}
{{ if not .Params.file }}
{{ errorf "Oh oh, der Dateiname 'file' fehlt oder ist leer in Seite %q" .Path }}
{{ end }}
{{ $AusgabeJahr := delimit (findRE "[0-9]*$" .Title) " " }}
{{ $AusgabeNummer := delimit (findRE "^[0-9]*" .Title) " " }}
leitet den Aufbau einer Seite für eine ft:pedia Einzelausgabe ein.
Das Pflichtfeld file
wird auf Anwesenheit geprüft. Bei fehlender Angabe
verweigert Hugo. Leider ist eine Prüfung auf fehlendes publishDate
nicht
machbar, da Hugo ein solches automatisch aus date:
ableitet.
Für die weiteren Zwecke wird aus dem Titel title:
das Jahr und auch die
Heftnummer als Zeichenkette extrahiert. findRE
benutzt hierbei RegExp-Syntax
(RegExp = regular expression),
um aus dem Titel “3 / 2019” die Jahreszahl vom Stringende her sowie die
Ausgabennummer vom Stringanfang her zu ermitteln.
Diese Konstrukte mit findRE
bieten den Vorteil, unabhängig von der trennenden
Sequenz (” / “) zu arbeiten. Beim alternativen split
wäre das Trennzeichen
explizit anzugeben.
Der Zusatz mit delimit
beseitigt eine Eigenheit von Hugo und wie es diese
Variablen behandelt. Jedenfalls bleibt nach delimit genau die gewünschte
Zeichenkette übrig.
Es ergibt sich für das Beispiel $AusgabeJahr := "2019"
und
$Ausgabenummer := "3"
.
Nun wird der innere Bereich eröffnet (außenrum ist die weiße Fläche und die Navigation), der Seitentitel als Überschrift gesetzt und das Titelbild als Hyperlink dargestellt. Zusätzlich gibt es noch Auskunft zum Erscheinungstag und zur Dateigröße.
<div id="body-inner">
<h2>Ausgabe {{.Title}}</h2>
<div style = "float:left; text-align: center; margin: 0.25em 1.5em 0 0.4em;">
<a href = "{{.RelPermalink}}{{.Params.file}}">
<img style = "display: block; max-width: 100%; margin: 0;"
src = "{{- .RelPermalink -}} titelseite.png"
alt = "{{.RelPermalink}}{{.Params.file}}">
</a>
<small>
Erschienen am {{ dateFormat $date_format_string .Params.publishDate }}
<br />
( {{- partial "download-size.html" . -}} )
</small>
</div>
<div id="body-inner">
eröffnet den inneren Darstellungsbreich.
<h2>Ausgabe {{.Title}}</h2>
kümmert sich um die Überschrift aus title:
.
Die Darstellung von Hefttitelbild und den Zusatzangaben wird in eine eigene
Fläche montiert. Inline-css sorgt für deren Position und Aussehen:
<div style = "float:left; text-align: center; margin: 0.25em 1.5em 0 0.4em;">
Was das genau bewirkt, erklärt uns w3school am besten.
Es folgt der Hyperlink auf die Heftdatei
<a href = "{{.RelPermalink}}{{.Params.file}}">
,
wie sie im Frontmatter file:
angegeben ist.
Zum Anklicken gibt es das Thumbnail des Titelbildes. Ein wenig inline-css
bewirkt auch hier ein angepasstes Aussehen, der Übersichtlichkeit halber ist
das Konstrukt in drei Zeilen zerlegt:
<img style = "display: block; max-width: 100%; margin: 0;"
src = "{{- .RelPermalink -}} titelseite.png"
alt = "{{.RelPermalink}}{{.Params.file}}">
<small>
sorgt für eine kleinere Darstellung der Schrift für die kommenden
Angaben.
Erschienen am
leitet den Text ein, und als Erscheinungsdatum wird das
publishDate:
aus dem Frontmatter herangezogen - beziehungsweise das was
Hugo intern dafür ermittelt hat wenn die explizite Angabe fehlt. Die
Formatierung auf das gewünschte Aussehen kommt per dateFormat
aus dem
eingangs definierten $date_format_string
zu Stande.
<br/>
schaltet zur nächsten Zeile und dort gibt es die Dateigröße in human
gut lesbarer Darstellung. Dafür benutzen wir
unser Partial download-size.html
.
</small>
und </div>
beenden diesen kleinen Bereich.
Rechts neben den Titelbild-Link wird das Inhaltsverzeichnis für diese Ausgabe als zweispaltige Tabelle gesetzt. Die Daten dafür kommen aus dem Gesamtinhalt-csv. Angezeigt werden zeilenweise der Artikeltitel und die Seitenzahl, auf der der Artikel beginnt. Der jeweilige Artikeltitel ist als seitengenauer Link auf das pdf der ft:pedia gestaltet.
<table style="width: auto; max-width: 75%; min-width: 250px; border: none;">
{{ $data := (getCSV ";" "content/ftpedia/ftPedia_Artikeluebersicht.csv") }}
<thead>
<tr>
{{ $header := first 1 $data }}
{{ range $row := $header }}
<!--<th>{{ index $row 0 }}</th>-->
<!--<th>{{ index $row 1 }}</th>-->
<!--<th>{{ index $row 2 }}</th>-->
<th style="border:none; width: 100%;">{{ index $row 3 }}</th>
<th style="border:none; text-align: right;">Seite</th>
<!--<th>{{ index $row 5 }}</th>-->
{{end}}
</tr>
</thead>
<tbody>
{{ $body := after 1 $data }}
{{ range $row := $body }}
{{/* index $row 0 enthält die Ausgabe im Stile '2018-3'. */}}
{{ $Ausgabe := index $row 0 }}
{{ $InhaltJahr := delimit (findRE "^[0-9]*" $Ausgabe) " " }}
{{ $InhaltNummer := delimit (findRE "[0-9]*$" $Ausgabe) " " }}
{{ if eq $InhaltJahr $AusgabeJahr }}
{{ if eq $InhaltNummer $AusgabeNummer }}
<tr>
<!--<td>{{ index $row 0 }}</td>-->
<!--<td>{{ index $row 1 }}</td>-->
<!--<td>{{ index $row 2 }}</td>-->
<td style="border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; vertical-align: middle;">
{{/* index $row 4 enthält die Seitenzahlen im Stile '5-33'. */}}
{{ $Seite := delimit (findRE "^[0-9]*" (index $row 4)) " " }}
<a href = "{{- $.Site.BaseURL -}}ftpedia/{{- $InhaltJahr -}}/{{- $Ausgabe -}}/ftpedia-{{- $Ausgabe -}}.pdf#page={{- $Seite -}}">
{{/* index $row 3 enthält den Titel des Artikels. */}}
{{ index $row 3 }}
</a>
</td>
<td style="border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; text-align: right; vertical-align: middle;">{{ $Seite }}</td>
<!--<td>{{ index $row 5 }}</td>-->
</tr>
{{ end }}
{{ end }}
{{ end }}
</tbody>
</table>
Die Tabelle soll je nach Bildschirmgröße ihre Breite ändern oder gar unter die
ft:pedia-Ausgabe wandern. Dafür sorgt das inline-css
<table style="width: auto; max-width: 75%; min-width: 250px; border: none;">
.
Die Tabelle nimmt maximal 75 % des Viewports ein, die anderen 25 % sind für
die Titelseite reserviert.
Der Gesamtinhalt wird eingelesen:
$data := (getCSV ";" "content/ftpedia/ftPedia_Artikeluebersicht.csv")
.
Der zweispaltige Tabellenkopf wird aus den vorgefundenen Daten aufgebaut.
Die restlichen Spalten sind zwar auch im Code zu sehen, aber auskommentiert
und gelangen daher nicht zur Darstellung.
Relevant ist hier die erste Zeile der csv ($header := first 1 $data
), die
Startseitenzahl bekommt allerdings eine minimal andere Überschrift
(<th style="border:none; text-align: right;">Seite</th>
).
<thead>
<tr>
{{ $header := first 1 $data }}
{{ range $row := $header }}
<!--<th>{{ index $row 0 }}</th>-->
<!--<th>{{ index $row 1 }}</th>-->
<!--<th>{{ index $row 2 }}</th>-->
<th style="border:none; width: 100%;">{{ index $row 3 }}</th>
<th style="border:none; text-align: right;">Seite</th>
<!--<th>{{ index $row 5 }}</th>-->
{{end}}
</tr>
</thead>
Der besondere Kniff ist nun die Definition der ersten Spaltenbreite auf 100 %. Dadurch wird die Spalte auf maximale Breite aufgeblasen, wobei die gesamte Tabelle auf insgesamt 75 % der verfügbaren Darstellungsbreite begrenzt ist. Ohne diese Einstellung werden Inhaltsverzeichnisse mit kurzen Titeln mit geringerer Breite dargestellt und stören die Harmonie beim Blättern zwischen den Ausgaben. Die Spalte mit den Seitenzahlen wird rechtsbündig gesetzt.
Nun kommen noch die relevanten Artikel in den Tabellenkörper <tbody>
. Diese
müssen natürlich aus dem Gesamtangebot herausgefiltert werden.
<tbody>
{{ $body := after 1 $data }}
{{ range $row := $body }}
{{/* index $row 0 enthält die Ausgabe im Stile '2018-3'. */}}
{{ $Ausgabe := index $row 0 }}
{{ $InhaltJahr := delimit (findRE "^[0-9]*" $Ausgabe) " " }}
{{ $InhaltNummer := delimit (findRE "[0-9]*$" $Ausgabe) " " }}
{{ if eq $InhaltJahr $AusgabeJahr }}
{{ if eq $InhaltNummer $AusgabeNummer }}
<tr>
<!--<td>{{ index $row 0 }}</td>-->
<!--<td>{{ index $row 1 }}</td>-->
<!--<td>{{ index $row 2 }}</td>-->
<td style="border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; vertical-align: middle;">
{{/* index $row 4 enthält die Seitenzahlen im Stile '5-33'. */}}
{{ $Seite := delimit (findRE "^[0-9]*" (index $row 4)) " " }}
<a href = "{{- $.Site.BaseURL -}}ftpedia/{{- $InhaltJahr -}}/{{- $Ausgabe -}}/ftpedia-{{- $Ausgabe -}}.pdf#page={{- $Seite -}}">
{{/* index $row 3 enthält den Titel des Artikels. */}}
{{ index $row 3 }}
</a>
</td>
<td style="border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; text-align: right; vertical-align: middle;">{{ $Seite }}</td>
<!--<td>{{ index $row 5 }}</td>-->
</tr>
{{ end }}
{{ end }}
{{ end }}
</tbody>
Der Tabellenkopf wurde bereits gelesen und so entfällt hier die erste Zeile
($body := after 1 $data
).
Das Script arbeitet sich Zeile für Zeile durch die Datensätze
(range $row := $body
).
Die Ausgabe wird abgelesen ($Ausgabe := index $row 0
) und das Jahr sowie die
Nummer extrahiert (delimit (findRE ...
).
Stimmt das Jahr aus dem csv-Datensatz mit dem Jahr der gerade bearbeiteten
Ausgabe überein, wird noch die Nummer überprüft.
{{ if eq $InhaltJahr $AusgabeJahr }}
{{ if eq $InhaltNummer $AusgabeNummer }}
Stimmen beide überein, ist ein Artikel für die Inhaltsangabe gefunden. <tr>
baut eine Zeile in die Tabelle ein. Der Artikeltitel wird benutzt, um den
Hyperlink in der ersten Spalte aufzubauen, dazu kommt noch die Startseitenzahl
in der zweiten Spalte.
<tr>
...
<td style="border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; vertical-align: middle;">
...
{{ $Seite := delimit (findRE "^[0-9]*" (index $row 4)) " " }}
<a href = "{{- $.Site.BaseURL -}}ftpedia/{{- $InhaltJahr -}}/{{- $Ausgabe -}}/ftpedia-{{- $Ausgabe -}}.pdf#page={{- $Seite -}}">
{{/* index $row 3 enthält den Titel des Artikels. */}}
{{ index $row 3 }}
</a>
</td>
<td style="border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; text-align: right; vertical-align: middle;">{{ $Seite }}</td>
...
</tr>
Mit den üblichen schließenden Tags wird die Tabelle beendet. Prinzipiell
ist das eine minimierte Version des Gesamtinhaltsverzeichnisses
(layouts/ftpedia/ftptoc.html
).
Mit dem Ende der Tabelle endet der Bereic,h in dem links die ft:pedia zum
Herunterladen bereitsteht. Ab hier wird wieder die volle Darstellungsbreite
benutzt. <div style = "clear: left">
eröffnet diesen Bereich, der zuerst
einen horizontalen Trennstrich <hr style = "margin-top: 0px"/>
enthält.
Finden sich im Verzeichnis dieser Ausgabe (content/ftpedia/yyyy/yyyy-n/
)
weitere Dateien des Typs .md
, so wird davon ausgegangen, dass es sich um
begleitende Downloads zur Ausgabe handelt (“Extras”) und ein entsprechender
Hinweis gegeben.
Das Script erkennt die “Extras” am Vorhandensein von .Pages
. Dabei schaltet
with .Pages
auch gleich den Kontext zu diesen Seiten um.
Diese Dateien werden entsprechend, auch per Tabelle, bereitgestellt. Es wird
dazu eine dreispaltige Tabelle aufgebaut, erste Spalte der Name des Downloads
mit Link auf die Infoseite, zweite Spalte Download-Icon als
Download-Direkt-Link mit Dateigröße und dritte Spalte der Autor.
{{ with .Pages }}
Zu einigen Artikeln dieser Ausgabe gibt es begleitende Downloads:<br />
<br />
<table>
<thead>
<tr>
<th>Thema</th>
<th style = "text-align: center;"><i class="fas fa-download"></i></th>
<th>Autor(en)</th>
</tr>
</thead>
<tbody>
{{ range .ByTitle }}
<tr>
<td>
<a href = "{{ .RelPermalink }}">
{{ .Title }}
</a>
</td>
<td style = "text-align: center;">
<a style = "display: block;"
href="{{ path.Dir .RelPermalink | path.Dir }}/{{ .Params.file }}">
{{ partial "download-icon.html" . }}
</a>
{{ partial "download-size.html" . }}
</td>
<td>
{{ partial "authors-list.html" . }}
</td>
</tr>
{{end}}
</tbody>
</table>
{{ else }}
Zu dieser Ausgabe gibt es keine begleitenden Downloads.
{{ end }}
Dabei werden die Tabelleneinträge alphabetisch absteigend geordnet
(range .ByTitle
, ‘A’ steht oben). Die Dateinamen der eigentlichen
Download-Dateien werden aus den zugehörigen Markdown-Dateien (Frontmatter)
geholt und in der ersten Spalte eingetragen:
<td>
<a href = "{{ .RelPermalink }}">
{{ .Title }}
</a>
</td>
In der nächsten Spalte folgt das Icon sowie die Dateigröße. Das erledigt die Zeilenfolge
<td style = "text-align: center;">
<a style = "display: block;"
href="{{ path.Dir .RelPermalink | path.Dir }}/{{ .Params.file }}">
{{ partial "download-icon.html" . }}
</a>
{{ partial "download-size.html" . }}
</td>
Abschließend baut ein Partial die Liste der Autoren in die dritte Spalte
<td>
{{ partial "authors-list.html" . }}
</td>
Gibt es dagegen keine weiteren Dateien zum Heft, so erscheint stattdessen die
entsprechende Notiz Zu dieser Ausgabe gibt es keine begleitenden Downloads.
Zweimal </div>
beendet diese Tabelle sowie den inneren Darstellungsbreich.
Die noch fehlende Navigation liegt bekanntlich im Außenbereich.
Nun soll zwischen den einzelnen Ausgaben durchgeblättert werden können. Dazu gibt es - analog zum Bilderpool - rechts und links eine spitze Klammer, die linksseitig zur nächstälteren Ausgabe führt, rechtsseitig zur nächstjüngeren Ausgabe. Dabei ist allerdings aufzupassen, dass diese Navigation nicht über die Grenzen hinausführt. ft:pedia gibt es erst seit 1 / 2011 - das ist der einfache Fall. Die jüngste Ausgabe wandert immer weiter. Mit diesem Vorwissen schauen wir jetzt mal in den Code:
<div id="navigation">
{{ $n := int $AusgabeNummer }}
{{ $y := int $AusgabeJahr }}
{{ $yp := $y }}
{{ $np := $n }}
{{ $yn := $y }}
{{ $nn := $n }}
{{ if gt $n 1 }}
{{ $np = sub $n 1 }}
{{ else }}
{{ $yp = sub $y 1 }}
{{ $np = 4 }}
{{ end }}
{{ if lt $n 4 }}
{{ $nn = add $n 1 }}
{{ else }}
{{ $yn = add $y 1 }}
{{ $nn = 1 }}
{{ end }}
{{ with .Parent }}
{{ with .Parent }}
{{ if ge $yp 2011 }}
<a class="nav nav-prev" href="{{.RelPermalink}}{{$yp}}/{{$yp}}-{{$np}}/" title="{{$np}} / {{$yp}}"> <i class="fas fa-chevron-left"></i></a>
{{ else }}
<a class="nav nav-prev" href="{{.RelPermalink}}{{$y}}/" title="{{$y}}"> <i class="fas fa-arrow-up"></i></a>
{{ end }}
{{ if fileExists (printf "%s/%d/%d-%d/_index.md" .Section $yn $yn $nn) }}
<a class="nav nav-next" href="{{.RelPermalink}}{{$yn}}/{{$yn}}-{{$nn}}/" title="{{$nn}} / {{$yn}}"> <i class="fas fa-chevron-right"></i></a>
{{ else }}
<a class="nav nav-next" href="{{.RelPermalink}}{{$y}}/" title="{{$y}}"> <i class="fas fa-arrow-up"></i></a>
{{ end }}
{{ end }}
{{ end }}
</div>
<div id="navigation">
eröffnet den Reigen. Ohne id
ginge es auch, hilft
aber per CTRL-F den Teil schneller aufzustöbern (aufpassen, im File gibt es
mehrere unterschiedliche Navigationen!).
$n := int $AusgabeNummer
nimmt sich die weiter oben ermittelte Nummer der
Ausgabe und wandelt, per int
, diese Zeichenkette (String) in eine Zahl um.
$y := int $AusgabeJahr
übernimmt baugleich die Jahreszahl.
Diese beiden Angaben werden dann noch in Variablen für die vorherige Ausgabe
(``$ypund
$np mit 'p' = previous) sowie die nächste Ausgabe (
$nn und
$yn` mit ‘n’ = next) kopiert. Und jetzt beginnen die grenzwertigen Spiele:
Wenn $n
größer als 1 ist (if gt $n 1
) , dann wird von $n
eins abgezogen
und an $np
zugewiesen ($np = sub $n 1
).
Ansonsten (else
) handelt es sich um die erste Ausgabe im Jahr und der
Vorgänger ist die Nummer 4 des Vorjahres, also $np = 4
und $yp = sub $y 1
.
{{ if gt $n 1 }}
{{ $np = sub $n 1 }}
{{ else }}
{{ $yp = sub $y 1 }}
{{ $np = 4 }}
{{ end }}
Umgekehrt wird alles vor der Ausgabe 4 im Jahr (if lt $n 4
) zur nächsten
Ausgabe hochgezählt ($nn = add $n 1
). Logischerweise muss für die 4te
Ausgabe des Jahres die Nummer 1 des Folgejahres angewählt werden ($nn = 1
und $yn = add $y 1
)
{{ if lt $n 4 }}
{{ $nn = add $n 1 }}
{{ else }}
{{ $yn = add $y 1 }}
{{ $nn = 1 }}
{{ end }}
So ist für jede Ausgabe ein Vorgänger und ein Nachfolger nominiert. Dabei kann
es passieren, dass hier die Ausgabe ‘4 / 2010’ oder auch eine Ausgabe hinter
der jüngsten Ausgabe (beim Schreiben dieser Zeilen wäre das die ‘4 / 2019’)
als Ziele vorgegeben sind. Nun muss aus den 4 ‘Kennzahlen’ ($np
, $yp
,
$nn
und $yn
) jeweils ein Link gebaut werden.
{{ with .Parent }}
{{ with .Parent }}
...
{{ end }}
{{ end }}
Per with .Parent
wechselt der Kontext zunächst von der Einzelausgabe zu
deren Jahrgang. Das zweite with .Parent
schaltet den Kontext zur kompletten
Section ft:pedia um. Von hier aus sind Jahrgänge und Einzelhefte erreichbar,
.RelPermalink
liefert bequem die nötigen Vorgaben dazu.
Die linksseitige Navigation soll stets zur älteren Ausgabe zurückführen - ohne auf eine ungültige Ausgabe zu zeigen. Das ist der Teil
{{ if ge $yp 2011 }}
<a class="nav nav-prev" href="{{.RelPermalink}}{{$yp}}/{{$yp}}-{{$np}}/" title="{{$np}} / {{$yp}}"> <i class="fas fa-chevron-left"></i></a>
{{ else }}
<a class="nav nav-prev" href="{{.RelPermalink}}{{$y}}/" title="{{$y}}"> <i class="fas fa-arrow-up"></i></a>
{{ end }}
if ge $yp 2011
erledigt diese
Sicherungsmaßnahme. Alles mit Jahreszahl größer oder gleich 2011 ist eine
gültige ältere Ausgabe.
<a class="nav nav-prev"
leitet den Hyperlink ein, die css-Klasse
nav nav-prev
bestimmt Position und Verhalten des Linksymbols.
Der eigentliche Link auf die Ausgabe wird nun ausgehend von der Section
ft:pedia zusammengebaut:
href="{{.RelPermalink}}{{$yp}}/{{$yp}}-{{$np}}/"
.
Sind wir zum Beispiel gerade auf der Seite der ft:pedia 1 / 2017 unterwegs
(‘ftpedia/2017/2017-1/'),
führt die linksseitige Navigation nach ‘ftpedia/2016/2016-4/'.
title="{{$np}} / {{$yp}}"
schreibt noch ordentlich den Ausgabenamen in den
Tooltip und als Symbol wird ein ‘Chevron nach links’ vom
Fontawesome
verwendet (<i class="fas fa-chevron-left"></i>
).
Ist dagegen die Jahreszahl der vermuteten Vorgängerausgabe kleiner als 2011,
dann führt die Navigation eine Etage aufwärts zum Jahrgang 2011:
<a class="nav nav-prev" href="{{.RelPermalink}}{{$y}}/" title="{{$y}}"> <i class="fas fa-arrow-up"></i></a>
Statt zu einer Ausgabe geht es zu einem Jahrgang, daher fehlen die
Ausgabenummern. Und anstelle ‘Chevron nach links’ kommt ein ‘Pfeil nach oben’.
So nachträglich betrachtet, hätte man den Fall hier auch hart codieren können:
<a class="nav nav-prev" href="{{.RelPermalink}}2011/" title="2011"> <i class="fas fa-arrow-up"></i></a>
.
Für die rechtsseitige Navigation zeichnet der Teil
{{ if fileExists (printf "%s/%d/%d-%d/_index.md" .Section $yn $yn $nn) }}
<a class="nav nav-next" href="{{.RelPermalink}}{{$yn}}/{{$yn}}-{{$nn}}/" title="{{$nn}} / {{$yn}}"> <i class="fas fa-chevron-right"></i></a>
{{ else }}
<a class="nav nav-next" href="{{.RelPermalink}}{{$y}}/" title="{{$y}}"> <i class="fas fa-arrow-up"></i></a>
{{ end }}
verantwortlich. Formal wird $yp
durch $yn
und $np
durch $nn
ersetzt um
die Links zu bauen. ‘Chevron nach rechts’ ersetzt das ‘Chevron nach links’,
der ‘Pfeil nach oben’ ist der gleiche wie vor.
Erheblich interessanter ist hier die “schwimmende” Begrenzung auf die neueste
erreichbare Ausgabe (oder deren Teaser, der wird nämlich auch ‘mitgenommen’).
if fileExists (printf "%s/%d/%d-%d/_index.md" .Section $yn $yn $nn)
erledigt
die Magie relativ knapp formuliert.
printf "%s/%d/%d-%d/_index.md" .Section $yn $yn $nn
erklärt sich besser mit
einem Beipiel: Möge $yn
= 2019 sein und $nn
= 4. Hieraus ergibt sich die
Zeichenfolge ‘ftpedia/2019/2019-4/_index.md’.
if fileExists ...
prüft nun ab, ob diese Datei existiert. Das ist der Fall
für einen Teaser oder für die Ausgabe selbst. Ansonsten ist der Ordner wohl
“auf Vorrat” angelegt und es gibt diese Seite nicht im Angebot. Und wenn das
festgestellt wird, geht die Naviagtion nicht “nach rechts” sondern “eins rauf”
zum aktuellen Jahrgang.
Ein paar zugehörige end
und das </div>
beenden den Code dieser Navigation
sowie den Bau einer Ausgabenseite (Seite für ein Einzelheft).
War es allerdings keine Einzelausgabe, so landen wir bei der nächsten Prüfung
{{ else }} {{/* not eq .Layout "issue" */}}
{{if eq .Layout "teaser" }}
Ist diese zutreffend, handelt es sich um den
Viel zu tun gibt es für den Teaser nicht. Zuerst wird geprüft ob das
launchDate
angegeben ist. Falls nicht, soll Hugo meckern.
{{/* --- Überprüfe ob die Pflichtangaben alle vorhanden sind --- */}}
{{/* --- Check if all mandatory field entries are available --- */}}
{{ if not .Params.launchDate }}
{{ errorf "Oh oh, das Veröffentlichungsdatum 'launchDate' fehlt oder ist leer in Seite %q" .Path }}
{{ end }}
Ist alles wie es sein soll, wird der minimale Seiteninhalt aufgebaut.
<div id="body-inner">
<h2>Ausgabe {{.Title}}</h2>
<div style = "float:left; text-align: center; margin: 0.25em 1.5em 0 0.4em;">
<img src = "{{- .RelPermalink -}} titelseite.png"
alt = {{.Title}}>
</div>
<p style = "text-align: center;">
Noch etwas Geduld bitte! Die neue Ausgabe kommt am {{ dateFormat $date_format_string .Params.launchDate }} ins Angebot.
</p>
</div>
<div id="body-inner">
leitet den dafür nötigen inneren Darstellungsbereich
ein.
Der Titel der kommenden Ausgabe erscheint als Überschrift
(<h2>Ausgabe {{.Title}}</h2>
).
Das verschwommene Titelbild (oder sagen wir mal lieber: das Bild, das von der Redaktion als Vorschaubild geliefert wird) bekommt einen Bereich und soll links von weiterem Text erscheinen. Es gibt keinen Download-Link, weil es ja auch noch kein Heft gibt:
<div style = "float:left; text-align: center; margin: 0.25em 1.5em 0 0.4em;">
<img src = "{{- .RelPermalink -}} titelseite.png"
alt = {{.Title}}>
</div>
Dazu kommt noch ein freundlicher Text mit dem Hinweis auf das geplante Erscheinungsdatum. Ein Hauch inline-css setzt den Text an die gewünschte Stelle.
<p style = "text-align: center;">
Noch etwas Geduld bitte! Die neue Ausgabe kommt am {{ dateFormat $date_format_string .Params.launchDate }} ins Angebot.
</p>
Das war es auch schon für den Teaser, der innere Bereich wird vom </div>
geschlossen.
Die Navigation beim Teaser findet im äußeren Bereich statt. Sie ist auch recht einfach gehalten. Zurück geht es bis zur ft:pedia 1/2011. Naja, das wäre nicht nötig, da heutzutage immer ein Vorgänger existiert. Aber es war am einfachsten, den Code von der Einzelausgabe zu kopieren.
Die neueste Ausgabe ist hier sehr einfach: Der Teaser ist die neueste Ausgabe (sozusagen) und die rechte Navigation führt immer eine Etage nach oben.
<div id="navigation">
{{ $AusgabeJahr := delimit (findRE "[0-9]*$" .Title) " " }}
{{ $AusgabeNummer := delimit (findRE "^[0-9]*" .Title) " " }}
{{ $n := int $AusgabeNummer }}
{{ $y := int $AusgabeJahr }}
{{ $yp := $y }}
{{ $np := $n }}
{{ if gt $n 1 }}
{{ $np = sub $n 1 }}
{{ else }}
{{ $yp = sub $y 1 }}
{{ $np = 4 }}
{{ end }}
{{ with .Parent }}
{{ with .Parent }}
{{ if ge $yp 2011 }}
<a class="nav nav-prev" href="{{.RelPermalink}}{{$yp}}/{{$yp}}-{{$np}}/" title="{{$np}} / {{$yp}}"> <i class="fas fa-chevron-left"></i></a>
{{ else }}
<a class="nav nav-prev" href="{{.RelPermalink}}{{$y}}/" title="{{$y}}"> <i class="fas fa-arrow-up"></i></a>
{{ end }}
<a class="nav nav-next" href="{{.RelPermalink}}{{$y}}/" title="{{$y}}"> <i class="fas fa-arrow-up"></i></a>
{{ end }}
{{ end }}
</div>
Für die Details zur Ermittlung des Vorgängers (also der vorhergehenden Einzelausgabe) sei hier der Verweis auf das Kapitel zur Navigation im Einzelheft verwiesen.
Damit ist der Teaser komplett. Sollte es jedoch auch nicht der Teaser sein, den Hugo da gerade als Bauauftrag bekommt, dann wird nachgesehen ob es die Hauptseite der section mit der Gesamtübersicht über alle Ausgaben ist:
{{ else }} {{/* not eq .Layout "teaser" */}}
{{ if eq .Layout "ftpediaAll" }}
Bei einem Treffer beginnt der Seitenbau der
Hier kommt nun die Übersicht über alle bisher erschienenen Hefte und einen eventuell gerade existierenden Teaser. Die Übersicht ist nach Jahrgängen gegliedert und der jüngste Jahrgang steht ganz oben.
Aber zunächst eröffnen wir den inneren Darstellungsbereich mit
<div id="body-inner">
und geben der Seite ihren Titel aus dem Frontmatter
(<h2>{{.Title}}</h2>
). Dazu kommt noch der freundliche Text (.Content
) aus
der Markdown-Datei.
<div id="body-inner">
<h2>{{.Title}}</h2>
{{ .Content }}
Unser Script gräbt sich nun durch die unmittelbar unterliegenden sections die den jeweiligen Jahrgang darstellen.
{{ range .Sections.ByTitle.Reverse }}
<hr>
<h4>
<a class = "ftplink" href = "{{.Title}}">
Jahrgang {{.Title}}
</a>
</h4>
.ByTitle.Reverse
gibt die gewünschte Reihenfolge mit dem jüngsten Jahrgang
zuerst. Der jeweilige Jahrgang steuert seinen Titel .Title
bei, der unter
einem horizontalen Trennstrich <hr
erscheint.
Dieser Titel ist als Hyperlink in die Jahrgangsansicht angelegt, aber speziell
formatiert (class = "ftplink"
).
Eine Variable {{ $accompanions := false }}
wird angelegt und auf false
initialisiert. Es gibt erstmal keine heftbegleitenden Extras (AKA Downloads).
Innerhalb des Jahrgangs werden alle vorhandenen Ausgaben aufgespürt und
nebeneinander zur Anzeige gebracht; jede ft:pedia-Ausgabe erhält ihren eigenen
<figure class="ftpedia-thumbnail">
-Bereich.
Dabei findet das Script noch heraus ob es zu den Ausgaben begleitende
Downloads gibt.
Derartige Begleitdateien weisen sich durch ein zugehöriges .md
aus.
Hugo registriert diese als page und deren Anzahl liefert .Pages
.
{{range.Sections.ByTitle }}
<figure class="ftpedia-thumbnail">
<a class = "ftplink" href = "{{.RelPermalink}}">
{{.Title}}
</a>
{{ if eq .Params.layout "teaser" }}
<img src = "{{- .RelPermalink -}} titelseite.png"
alt = {{.Title}}>
<small>
Ab {{ dateFormat $date_format_string .Params.launchDate }}
</small>
{{ else }}
<a href = "{{.RelPermalink}}{{.Params.file}}">
<img src = "{{- .RelPermalink -}} titelseite.png"
alt = "{{.RelPermalink}}{{.Params.file}}">
</a>
<small>
{{ .Date.Format $date_format_string }}
</small>
{{ if gt .Pages 0 }}
{{ $accompanions = true }}
{{ end }}
{{ end }}
</figure>
{{end}}
Der Teaser (layout: "teaser"
) erfährt dabei eine Sonderbehandlung!
Er wird lediglich durch seinen Titel, sein geplantes Erscheinungsdatum und
sein Vorschaubild (alles ohne Link) dargestellt. Irgendwelche bereits
existenten Extras werden nicht gesucht.
Alle normalen Ausgaben erhalten ihren Titel und Titelbild als klickbaren
Download-Link mit ihrem Erscheinungsdatum darunter.
In diesem Fall wird noch anhand if $accompanions
festgestellt, ob es Dateien
zur Ausgabe gibt und ein entsprechender Link auf den Jahrgang beigefügt.
Ohne begleitende Downloads gibt es keinen entsprechenden Link.
Ein Zeilenvorschub schließt diesen Jahrgang ab.
{{ if $accompanions }}
<br/>
<a href = "{{.Title}}">
Es gibt begleitende Downloads zu einigen Ausgaben.
</a>
{{ end }}
<br />
Sind alle Jahrgänge abgearbeitet (end
), wird der innere Bereich wiederverlassen
(</div>
).
{{end}}
</div>
Auf der ft:pedia-Hauptseite gibt es keine Navigation auf der linken oder rechten Seite.
Hat nun bis hierher keines der angegebenen Layouts gepasst, so deutet das auf eine Fehlfunktion / Fehlbedienung hin. Hugo wird dem Admin eine deutliche Fehlermeldung geben und die Seite nicht bauen:
{{ else }} {{/* not eq .Layout "ftpediaAll" */}}
{{ errorf "Oh oh, section ftpedia enthält einen unbekannten Seitentyp 'layout' %q für Seite %q" .Layout .Path }}
{{ end }} {{/* .Layout "ftpediaAll" */}}
{{ end }} {{/* .Layout "teaser" */}}
{{ end }} {{/* .Layout "issue" */}}
{{ else }} {{/* not .Layout */}}
Ist dagegen gar kein Layout angegeben, so handelt es sich um die
Auch ein einzelner Jahrgang wird in einem inneren Bereich dargestellt. Die
Seite bekommt ihren Titel .Title
aus dem Frontmatter.
{{/* Ein Jahrgang (Titelbilder als Download-Links) */}}
{{/* One year's editions (frontpages as download-links) */}}
<div id="body-inner">
<h2>{{.Title}}</h2>
$accompanions := false
stellt zunächst eine Variable bereit, die erklärt, ob es
Extras zu den Heften gibt. Die Voreinstellung ist ‘nein’.
Jede Einzelausgabe (with .Sections
) wird zunächst auf formal korrekte
Frontmatter untersucht. Bei Fehlern gibt es deutlichen Mecker. Das trifft auch
für eventuell zusätzlich vorhandene Extras zu.
{{ with .Sections }}
<br />
{{ range .ByTitle }}
{{/* --- Überprüfe ob die Pflichtangaben alle vorhanden sind --- */}}
{{/* --- Check if all mandatory field entries are available --- */}}
{{ if not .Title }}
{{ errorf "Oh oh, der Seitentitel 'title' fehlt oder ist leer in Seite %q" .Path }}
{{ end }}
{{ if eq .Params.layout "file" }}
{{ if not .Params.file }}
{{ errorf "Oh oh, der Dateiname 'file' fehlt oder ist leer in Seite %q" .Path }}
{{ end }}
{{ end }}
with .Sections
gibt die Inhalte nur aus, wenn auch eine section existiert.
range .ByTitle
sorgt für die gewünschte Sortierung (1 links, 4 rechts).
Dann erfolgen noch die Prüfungen zu jeder Ausgabe. Es langt durchaus, das nur
hier zu machen (und nicht auch noch beim Bau der ft:pedia-Hauptseite), weil
Hugo eh beide Seitentypen bauen muss.
Ist das Vorgeplänkel soweit erledigt, wird die Ausgabe mit Titelbild und ein paar Angaben dargestellt. Der Code und das erzeugte Aussehen ist identisch mit dem Bau der ft:pedia-Hauptseite.
<figure class="ftpedia-thumbnail">
<a class = "ftplink"
href = "{{.RelPermalink}}">
{{.Title}}
</a>
{{ if eq .Params.layout "teaser" }}
<img src = "{{- .RelPermalink -}} titelseite.png"
alt = {{.Title}}>
<small>
Ab {{ dateFormat $date_format_string .Params.launchDate }}
</small>
{{ else }}
<a href = "{{.RelPermalink}}{{.Params.file}}">
<img src = "{{- .RelPermalink -}} titelseite.png"
alt = {{.Title}}>
</a>
<small>
{{ .Date.Format $date_format_string }}
</small>
{{ if gt .Pages 0 }}
{{ $accompanions = true }}
{{ end }}
{{ end }}
</figure>
Es folgt nun ein horizontaler Trennstrich und die Abfrage, ob begleitende
Downloads gesichtet wurden (if $accompanions
). Falls ja, geht es auch direkt
los mit dem Tabellenbau.
<hr />
{{ if $accompanions }}
Zu einigen Artikeln dieser Ausgabe gibt es begleitende Downloads:<br />
<br />
<table>
In der Tabelle werden die existenten Dateien aufgelistet. Es gibt 4 Spalten
und entsprechend sieht der Kopf aus:
<thead>
<tr>
<th style = "text-align: center;">Ausgabe</th>
<th>Thema</th>
<th style = "text-align: center;"><i class="fas fa-download"></i></th>
<th>Autor(en)</th>
</tr>
</thead>
Für den Bau der Tabellenkörpers gräbt sich Hugo nun wieder durch die Ausgaben
dieses Jahrgangs (range .Sections.ByTitle
) um die zugehörigen Dateien zu
finden (range .Pages.ByTitle
).
<tbody>
{{ range .Sections.ByTitle }}
{{ $edition := .Title }}
{{ range .Pages.ByTitle }}
<tr>
Für jede gefundene Datei wird eine Zeile in der Tabelle angelegt. In der
ersten Spalte erscheint profan der Name der Ausgabe ($edition
).
<td style = "text-align: center;">
{{ $edition }}
</td>
In der zweiten Spalte wird der Name der Seite (ist eine page und wir brauchen
deren .Title
) angegeben. Dieser Seitenname wird mit einem Hyperlink
(href = "{{ .RelPermalink }}"
) hinterlegt. Auf dieser Seite gibt es dann
noch weitere Details zum Download - für all die, die es genau wissen wollen.
<td>
<a href = "{{ .RelPermalink }}">
{{ .Title }}
</a>
</td>
Diese spezielle Unterseite wird vom globalen Script für alle Download-Dateien
gebaut (layouts/_default/file.html
) und hier nicht weiter erklärt.
Für unsere eiligen Surfer kommt in der dritten Spalte der Direktlink auf den
Download. Allerdings - auch um Platz zu sparen - wird der Dateiname durch ein
Icon ersetzt. Um dieses Icon kümmert sich das partial download-icon.html
.
Für die Gestaltung sorgt etwas Inline-style. Dazu gibt es noch die Dateigröße
der Download-Datei; auch hier hilft ein partial: download-size.html
.
<td style = "text-align: center;">
<a style = "display: block;"
href="{{ path.Dir .RelPermalink | path.Dir }}/{{ .Params.file }}">
{{ partial "download-icon.html" . }}
</a>
{{ partial "download-size.html" . }}
</td>
Damit fehlt nur noch die Angabe zu dem/den Autor(en). Hierfür bietet sich auch
das, aus einem anderem Grund bereits vorhandene, partial authors-list.html
zur Nutzung an. Die Tabellenzeile endet mit dieser vierten Spalte.
<td>
{{ partial "authors-list.html" . }}
</td>
</tr>
Der Vorgang wiederholt sich für jede page (= Download zu einer Ausgabe) und jede weitere section (= Ausgabe) des Jahrgangs. Sind alle Inhalte abgefrühstückt, endet die Tabelle.
{{end}}
{{end}}
</tbody>
</table>
Gibt es zum ganzen Jahrgang keine Begleitdateien ($accompanions
ist false
)
dann erhält der Nutzer diese Auskunft anstelle der Tabelle mit Dateien:
{{ else }}
Zu diesen Ausgaben gibt es keine begleitenden Downloads.
{{ end }}
</div>
Mit dem Ende der Jahrgangsdarstellung endet auch der innere Bereich (</div>
).
Nun kommt noch die Navigation. Das ist eigentlich nichts anderes als speziell platzierte Links auf bestimmte Seiten. Und so funktioniert das Ganze denn auch. Ältere Jahrgänge erreicht man durch Linksblättern, zu jüngeren Jahrgängen blättert man auf der rechten Seite.
<div id="navigation">
{{ $AusgabeJahr := delimit (findRE "[0-9]*$" .Title) " " }}
{{ $y := int $AusgabeJahr }}
{{ $yp := sub $y 1 }}
{{ $yn := add $y 1 }}
{{ with .Parent }}
{{ if ge $yp 2011 }}
<a class="nav nav-prev" href="{{.RelPermalink}}{{$yp}}/" title="{{$yp}}"> <i class="fas fa-chevron-left"></i></a>
{{ else }}
<a class="nav nav-prev" href="{{.RelPermalink}}" title=".Title"> <i class="fas fa-arrow-up"></i></a>
{{ end }}
<!-- Da muss auch wenigstens ein Unterordner für yyyy-1/ existieren und da muss auch ein _index.md drin sein! Vorbereitete "leere" Jahrgangs-Ordner werden so ignoriert!
Den Rest macht oben der Teil für die Einzelausgabe. -->
{{ if fileExists (printf "%s/%d/%d-1/_index.md" .Section $yn $yn) }}
<a class="nav nav-next" href="{{.RelPermalink}}{{$yn}}/" title="{{$yn}}"> <i class="fas fa-chevron-right"></i></a>
{{ else }}
<a class="nav nav-next" href="{{.RelPermalink}}" title=".Title"> <i class="fas fa-arrow-up"></i></a>
{{ end }}
{{ end }}
</div>
Eingeleitet wird der Abschnitt durch <div id="navigation">
.
$AusgabeJahr := delimit (findRE "[0-9]*$" .Title) " "
fischt den Jahrgang
aus dem Frontmatter. $y
bekommt die Jahreszahl nun tatsächlich als Zahl
zugewiesen. Der vorherige Jahrgang $yp
ist dann eins weniger
($yp := sub $y 1
) und der nachfolgende Jahrgang ist eins mehr
($yn := add $y 1
).
with .Parent
schaltet den Kontext zur Section ft:pedia um, das vereinfacht
den Linkbau.
Wenn nun der Jahrgang mindestens 2011 ist (if ge $yp 2011
), weist der
Hyperlink
<a class="nav nav-prev" href="{{.RelPermalink}}{{$yp}}/" title="{{$yp}}"> <i class="fas fa-chevron-left"></i></a>
auf die entsprechende Jahrgangsseite.
Ansonsten (else
) geht es eine Ebene nach oben zur Section ft:pedia mit der
großen Übersicht
(<a class="nav nav-prev" href="{{.RelPermalink}}" title=".Title"> <i class="fas fa-arrow-up"></i></a>
).
Oder hat jemand eine ft:pedia aus 2010?
Zum jüngeren Jahrgang geht es auf der rechten Seite, aber nur wenn dort
wenigstens eine Ausgabe 1 (‘1 / yyyy’) existiert.
if fileExists (printf "%s/%d/%d-1/_index.md" .Section $yn $yn)
forscht das
aus.
Dabei baut das printf
den Pfad auf die vermutete Seite, ausgewiesen durch
ein _index.md
, zusammen und if fileExists
prüft deren Vorhandensein.
Bei Erfolg wird zu diesem Jahrgang verlinkt:
<a class="nav nav-next" href="{{.RelPermalink}}{{$yn}}/" title="{{$yn}}"> <i class="fas fa-chevron-right"></i></a>
Im anderen Fall gibt es diesen Jahrgang (noch) nicht und der Link geht zur
_Section ft:pedia nach oben.
Damit endet die Darstellung eines einzelnen Jahrgangs.
Abgeschlossen wird die Seite und das Script durch ein paar weitere Zeilen:
{{ end }} {{/* .Layout */}}
</div>
{{ end }}