{# Filter als Adressen (Etappe 3, Task 4, Spec §8). **Jeder Zustand ist eine Adresse**, und jeder Weg aus einer Liste heraus nimmt die uebrigen Filter mit. Genau dort gehen sie sonst still verloren: Ein Klick auf ein Jahr hob bis Task 3 den Statusfilter auf, ohne dass jemand ihn aufgehoben haette. Darum entsteht JEDE Adresse an einer Stelle: `filteradresse()` in `vorlage.py`, hier als Funktion aufrufbar. Sie liefert rohen Text, der beim Einsetzen ins Attribut genau EINMAL escapt wird; ein Jinja-Makro koennte das nicht, weil sein Ergebnis `Markup` ist und ein `|ziel` dahinter die Kennzeichnung verliert (der Link zeigte dann auf einen Parameter namens «amp;jahr», gemessen am 2026-09-03). #} {# Alle geltenden Filter als verborgene Felder — ausser dem, den das Formular selbst setzt. **Nicht einzeln aufgezaehlt.** Genau so hat das Wechselformular der Werkzeugleiste `status` und `jahr` verloren: Wer eine Zeile mit `{% if %}` schreibt, denkt an den Wert, den er gerade vermisst (Code-Review 2026-09-03). Die Liste kommt darum aus `FILTERNAMEN`, und ein weiterer Filter reist ohne Aenderung an dieser Datei mit. #} {% import "bausteine/bausatz.html" as b %} {% macro verborgene(f, ohne=()) -%} {#- **`ohne` ist eine LISTE, kein Name.** Die Filterleiste setzt drei Felder auf einmal; mit einem einzelnen Namen stuende jedes uebrige zweimal im Formular — einmal als verborgenes Feld mit dem alten Wert, einmal als Auswahl mit dem neuen. Der Browser sendet beide, und der Server liest das erste. Ein String bricht darum ab, statt sich als Teilzeichenkette zu verhalten («status» steckt in «statusfilter»). -#} {%- if ohne is string %}{{ OHNE_IST_EINE_LISTE_VON_NAMEN_KEIN_EINZELNER_NAME }}{% endif -%} {%- for name in FILTERNAMEN if name not in ohne and f.get(name) %}{% endfor -%} {%- endmacro %} {# Was gerade gilt, mit einem Weg heraus je Filter. «Alles zuruecksetzen» steht daneben, weil sonst drei Klicks noetig sind. **Jede Aussage steht genau einmal.** Den Status zeigt die Kachel, das Jahr sein Auswahlfeld; beide zeigen, was gilt, und beide führen zurück. Eine Kapsel daneben wäre eine zweite Aussage über dieselbe Sache, und die Sichtprobe zu Task 4 zeigte genau das: «2026» im Facettentitel, «2026» markiert in der Liste und «2026 ×» darunter. Was keine eigene Anzeige hat, ist die Suche. **Die Zeile erscheint trotzdem, sobald ZWEI Filter gelten**: Dann ist «Alles zuruecksetzen» der kuerzeste Weg, und es braucht einen Ort. #} {% macro kapseln(pfad, f, kapseln_werte, ohne_filter) -%} {#- `kapseln_werte` kommt aus `_filterkapseln` in `main.py`: `{zeigen, kapseln}` — je Filter, der gilt UND keine eigene Anzeige hat, ein `{name, wort, hilfe}`. **`zeigen` ist nicht dasselbe wie «es gibt Kapseln».** Gelten zwei Filter und tragen beide ihre eigene Anzeige, steht hier keine einzige Kapsel — «Alles zuruecksetzen» aber schon, denn drei Klicks sind der Weg, den es sonst braucht. **Warum die Liste in Python entsteht.** Sie zaehlte hier bis Task 2 der Etappe 4 drei Filter einzeln auf, mit je einem `mit_…`-Schalter — und genau diese Bauform hat am Wechselformular zwei Filter verloren (Code-Review 2026-09-03). Jeder Filter braucht ausserdem sein eigenes Wort («Offen», «2026», ««Lift»»), und das ist eine Entscheidung, keine Formatierung: Sie gehoert dorthin, wo die Filter herkommen. -#} {%- if kapseln_werte.zeigen %}
{%- endmacro %} {# Der Rahmen: Suchfeld, Auswahlfelder, Knopf. **Welche Felder es gibt, entscheidet Python** (`_filterfelder` in `main.py`) — aus demselben Grund wie bei den Kapseln: Die Liste treibt HIER beides, die Felder UND die Namen, die nicht zusätzlich als verborgenes Feld mitreisen dürfen. Zwei Aufzählungen von Hand wären zwei Gelegenheiten, sie auseinanderlaufen zu lassen — und ein Filter, der zweimal im Formular steht, sendet zwei Werte, von denen der Server den ersten liest. `q` steht darum ebenfalls in der Ausschlussliste: Das Suchfeld setzt es selbst. **Ein Feld ohne einen einzigen Wert erscheint nicht.** Es wäre eine Auswahl, in der es nichts zu wählen gibt; `_filterfelder` lässt es weg. Die Zeile steht trotzdem — das Suchfeld gibt es auf jeder Liste, auch wenn gerade kein Filter etwas zu wählen hat. #} {% macro leiste(pfad, f, felder, was='') -%} {%- if not felder and not was %}{{ EINE_WERKZEUGZEILE_OHNE_FELD_UND_OHNE_SUCHE_IST_EIN_KNOPF_OHNE_WIRKUNG }}{% endif %} {%- endmacro %}