{# Die Dateien einer Meldung — Bilder als Vorschau, alles andere als Verweis. **Anlass**, der Auftraggeber am 10.09.2026: «Zudem sollten die Anhänge direkt anzeigbar sein. Jetzt muss ich diese herunterladen.» Zwei Dinge waren nötig, und keines genügt allein: Die Auslieferung sagt jetzt `inline` statt `attachment` (`features/anhaenge.disposition`, samt der Erlaubnisliste und dem fehlenden SVG), und hier steht das Bild in der Seite, statt dass man es erst anklicken muss. Erwartet im Kontext: - `dateien` — Einträge mit `id`, `dateiname`, `inhaltstyp` - `dateien_basis` — Pfad-Präfix OHNE Schrägstrich am Ende, vom Aufrufer gebaut UND von ihm kodiert (`vorlage.pfadteil`), wie `anhang_basis` **Ein Eintrag darf ein eigenes Zwischensegment tragen** (`quelle`), und das ist kein Sonderweg für einen Verbraucher, sondern der Fall, den es hier gibt: Die Auftragsseite des Handwerkers zeigt zwei Töpfe in einer Liste (`auftrag_anhaenge` und `ticket_anhaenge`), und der Weg zum Herunterladen schlägt je nach Topf in einer anderen Tabelle nach (`/a//anhang//`). Es steckt darum am EINTRAG und nicht in der Basis: Innerhalb einer Liste wechselt es von Zeile zu Zeile. Wer es nicht setzt, bekommt den Pfad wie bisher. **Die Entscheidung «Vorschau oder Verweis» kommt FERTIG von drüben.** Jeder Eintrag trägt `vorschau`, gesetzt von `anhaenge.zeigt_vorschau` in der API — also von derselben Stelle, die auch entscheidet, ob die Datei `inline` ausgeliefert wird. Hier die Endung zu lesen oder eine eigene Typenliste zu führen wäre eine zweite Wahrheit über dieselbe Frage, und die eine von beiden hängt an der Auslieferung. Drei Dinge stecken in dem einen Merkmal, und alle drei stehen drüben: der Typ darf angezeigt werden, er ist ein Bild und nicht ein PDF, und die Datei ist klein genug. `image/svg+xml` gilt darum nicht als Bild (es darf Skript enthalten), `image/heic` auch nicht (nur Safari zeigt es), und ein Foto über zwei Megabyte bleibt ein Verweis — der es dank `inline` trotzdem im Browser öffnet. #} {% import "bausteine/symbol.html" as s %} {#- **Ein Durchgang und kein `selectattr`.** Die Umgebung läuft mit `StrictUndefined`: Ein Eintrag ohne das Merkmal `vorschau` nähme mit `selectattr` die ganze Seite mit. `a.get(...)` behandelt ihn als Nicht-Bild, und das ist die sichere Seite und dieselbe wie drüben bei `disposition`: Wer nichts sagt, bekommt einen Verweis. **Und die Reihenfolge bleibt.** Ein erster Entwurf sammelte die fehlenden Merkmale getrennt von den ausdrücklich falschen und stellte sie damit voran; der Code-Review vom 10.09.2026 hat es gemeldet. Die Dateien kommen nach `created_at` sortiert, und das soll so bleiben. -#} {% set bilder = [] %} {% set uebrige = [] %} {%- for a in dateien %} {%- if a.get("vorschau") %}{% set _ = bilder.append(a) %} {%- else %}{% set _ = uebrige.append(a) %}{% endif %} {%- endfor %} {% if bilder %} {% endif %} {% if uebrige %}
    {%- for a in uebrige %} {%- set adresse = dateien_basis ~ "/" ~ (a.quelle|pfadteil ~ "/" if a.get("quelle") else "") ~ (a.id|pfadteil) %} {#- **Die Grösse steht dabei, wo keine Vorschau ist.** Bei einem grossen Foto ist sie der Grund dafür; bei einem PDF ist sie schlicht nützlich, bevor man es am Telefon öffnet. **Kilobyte unter einem Megabyte.** Ein erster Anlauf rechnete immer in MB und schrieb an jede kleine Datei «0.0 MB» — eine Angabe, die falscher ist als keine (Code-Review 10.09.2026). -#} {%- set kb = (a.get("groesse_bytes") or 0) / 1024 %}
  • {{ s.symbol("klammer", 14) }}{{ a.dateiname }}{% if kb %} {% if kb < 1024 %}{{ kb|round|int }} KB{% else %}{{ (kb / 1024)|round(1) }} MB{% endif %}{% endif %}
  • {%- endfor %}
{% endif %}