Zu einer Downloaddatei wird die Dateigröße ermittelt und für eine humane Darstellung aufbereitet.
Zuerst muss der Name der Downloaddatei mitsamt deren Zugriffspfad ermittelt werden.
{{- $finfo := path.Join .File.Dir .Params.file | os.Stat -}}
{{- $fsize := $finfo.Size -}}
Wir machen uns zu Nutze, dass die Markdown-Datei (.md) mit der Beschreibung
im Dateibaum gleich “daneben” steht.
Beide Dateien haben daher den gleichen Zugriffspfad, .File.Dir
gibt uns
den bekannt.
.Params.file
steht für den Dateinamen der Downloaddatei
wie er im Frontmatter angegeben ist.
Für das Zusammenfügen der beiden Bestandteile wird path.Join
bemüht.
Mittels des ‘pipe’-Operators |
wird der zusammengefügte Pfad mit Dateiname
zur Downloaddatei an os.Stat
weitergereicht.
Dieses os.Stat
holt die Datei-Info der angegebenen Datei vom Betriebssystem
und weist die Datei-Info an $finfo
zu.
Die Dateigröße ($finfo.Size
) wird dann an $fsize
zugewiesen.
Die Dateigröße ist generell in Bytes angegeben. Große Zahlen sind aber für den Leser eher schwer zu erfassen. Außerdem kommt es ab einigen Kilobyte (kB) nicht mehr auf eine exakte Angabe an. Die Dateigröße wird daher für eine angenehme Darstellung aufbereitet. Dazu sind zwei Pfade zu behandeln: Einer für den Zahlenwert und einer für die Einheit. Beides ginge auch in einem Aufwasch, aber damit gibt es ein Häkchen, das später bei der eigentlichen Darstellung erst auffiele.
{{- $fsize_unit := "Bytes" -}}
{{- $scratch1 := newScratch -}}
{{- if gt $fsize 104857600}}
{{- printf "%.0f" (div $fsize 1048576.0) | $scratch1.Set "fsize_txt" -}}
{{- $fsize_unit = "MB" -}}
{{- else if gt $fsize 10485760}}
{{- printf "%.1f" (div $fsize 1048576.0) | $scratch1.Set "fsize_txt" -}}
{{- $fsize_unit = "MB" -}}
{{- else if gt $fsize 1048576}}
{{ printf "%.2f" (div $fsize 1048576.0) | $scratch1.Set "fsize_txt" -}}
{{ $fsize_unit = "MB" -}}
{{- else if gt $fsize 102400 -}}
{{- printf "%.0f" (div $fsize 1024.0) | $scratch1.Set "fsize_txt" -}}
{{- $fsize_unit = "kB" -}}
{{- else if gt $fsize 10240 -}}
{{- printf "%.1f" (div $fsize 1024.0) | $scratch1.Set "fsize_txt" -}}
{{- $fsize_unit = "kB" -}}
{{- else if gt $fsize 1024 -}}
{{- printf "%.2f" (div $fsize 1024.0) | $scratch1.Set "fsize_txt" -}}
{{- $fsize_unit = "kB" -}}
{{- else -}}
{{- printf "%d" $fsize | $scratch1.Set "fsize_txt" -}}
{{- $fsize_unit = "Bytes" -}}
{{- end -}}
$fsize_unit := "Bytes"
erhält als die Einheit der Dateigröße zunächst
“Bytes”.
Für den Zahlenwert wird ein “Notizzettel” angelegt:
$scratch1 := newScratch
.
Nun wird der Reihe nach, beginnend mit einem sehr großen Wert, geprüft, ob die
Dateigröße diesen (willkürlich) gewählten Wert überschreitet.
Falls nicht, kommt der nächstniedrigere Wert an die Reihe.
Trifft ein Vergleich if gt $fsize xxxx
(if $fsize > xxxx
) zu, wird die
Dateigröße durch einen Teiler skaliert (div $fsize 1024.0
entspricht
$fsize / 1024.0
).
Dabei sorgt die angehängte ‘.0’ dafür, dass das Ergebnis als Fließkommazahl
erscheint.
Diese Fließkommazahl wird nun per printf "%._f"
in einen String umgewandelt.
Dabei bestimmt die Zahl anstelle des Platzhalters die Anzahl der
Nachkommastellen in der Anzeige; "%.2f"
erzwingt zwei Nachkommastellen.
Das Ergebnis des printf
wird per |
zum “Notizzettel” weitergereicht und
per $scratch1.Set
zur späteren Verwendung aufbewahrt.
Die kaufmännische Rundung erledigt das printf übrigens gleich mit.
Aus 12.73 wird so 12.7 und aus 12.77 wird 12.8.
Trifft keiner der Vergleiche zu, wird die Dateigröße direkt als Integerwert und mit der Einheit ‘Bytes’ angegeben. In diesem Fall ist nichts zu runden.
Passend zum Teiler wird die Einheit auf ‘MB’, ‘kB’ oder ‘Bytes’ umgestellt
und in $fsize_unit
abgelegt.
Nun wird noch das Ergebnis zurückgeliefert.
{{- $scratch1.Get "fsize_txt" -}} {{- $fsize_unit -}}
Der Zahlenwert wird per $scratch1.Get "fsize_txt"
hervorgelockt.
ist ein spezielles Leerzeichen, das nicht durch einen Zeilenumbruch
ersetzt werden darf.
$fsize_unit
gibt noch die Einheit der Dateigröße dazu.
Insgesamt kommt da sowas wie 12.7 kB
heraus.
Wegen des  
ist die Einheit untrennbar mit der Zahl verbunden und beide
Teile werden immer gemeinsam in einer Zeile stehen, obwohl ein normgerechter
Abstand dazwischen eingehalten wird.
Leider hat sich herausgestellt, dass das
nicht durch Hugos printf
erzeugt werden kann und deswegen ist die getrennte Behandlung von Zahl und
Einheit bis hierher erforderlich.
Die errechnete und aufbereitete Dateigröße wird durch die letzte Zeile
{{- $scratch1.Get "fsize_txt" -}} {{- $fsize_unit -}}
an der Stelle
erscheinen, wo das Partial ‘aufgerufen’ wird.
{{-
sowie -}}
unterdrücken jeglichen Whitespace.
( {{- partial "download-size.html" . -}} )
wird im fertigen HTML-Code dann z. B. durch
(12.7 kB)
ersetzt.
Der beschriebene Code sollte dem tatsächlichen Inhalt von /layouts/partials/download-size.html entsprechen. Eventuell ergeben sich marginale Abweichungen, weil einer der Grenzwerte verändert wurde ohne die hiesige Doku anzupassen. Das ist dann halt so und es gilt immer der ‘produktive’ Wert.
Stand: 25. Oktober 2019