Script - list.html

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:

  • Den Wurzelknoten der section (content/ftpedia/_index.md)
  • Die jahrgangsweise Struktur, für jedes Jahr ‘yyyy’ eine section (content/ftpedia/yyyy/_index.md)
  • Eine einzelne Ausgabe ‘yyyy-n’ (content/ftpedia/yyyy/yyyy-n/_index.md)
  • Der Teaser für die kommende Ausgabe (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:

graph TD St(("Start")) Q1{".Layout definiert?"} Q2{".Layout == 'issue'?"} Q3{".Layout == 'teaser'?"} Q4{".Layout == `ftpediaAll'?"} A["Baue Seite für Ausgabe"] H["Baue ft:pedia-Hauptseite"] J["Baue Seite für Jahrgang"] T["Baue Seite für Teaser"] M["Fehlermeldung"] F(("Abbruch!")) E(("Ziel")) St --> Q1 Q1 -->|true| Q2 Q1 -->|false| J Q2 -->|true| A Q2 -->|false| Q3 Q3 -->|true| T Q3 -->|false| Q4 Q4 -->|true| H Q4 -->|false| M A --> E H --> E J --> E T --> E M --> F classDef fehler fill:#fdd, stroke:#500 class F,M fehler

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

Ausgabe (Einzelheft)

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

Teaser

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

ft:pedia-Hauptseite

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

Seite für einen Jahrgang

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

  • Ausgabe
  • Thema
  • Download-Link (durch ein Icon dargestellt)
  • Autor(en)

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.

Abschluss

Abgeschlossen wird die Seite und das Script durch ein paar weitere Zeilen:

      {{ end }}   {{/* .Layout */}}
   </div>
{{ end }}
Stand: 27. Oktober 2019