Skip to content

feat: Datenkatalog im Frontend — [odw_catalog] und Block „Datenkatalog" (v2.43.0) - #142

Merged
daimpad merged 4 commits into
mainfrom
claude/fix-data-prep-errors-kJYpl
Oct 27, 2026
Merged

daimpad merged 4 commits into
mainfrom
claude/fix-data-prep-errors-kJYpl

Conversation

@daimpad

@daimpad daimpad commented Oct 27, 2026 •

Copy link
Copy Markdown
Owner

Worum es geht

Neben der Download-Card für einen Datensatz ([odw_dataset id="…"]) gibt es jetzt eine Übersicht aller veröffentlichten Datensätze auf einer Seite — als Shortcode [odw_catalog] und als Block „Datenkatalog".

Was sich ändert

  • ODW_Catalog (includes/class-catalog.php): Liste mit Titel, Aktualisierungsdatum, Auszug, Badges (Thema, Format, Größe, Lizenz, eingeschränkter Zugang) und direktem Link zur Datei bzw. zum Datenangebot. Attribute per_page (1–50), orderby (title/modified), theme (EU-Codes), title, excerpt, show_demo; Filter odw_catalog_query_args.
  • Detailansicht auf derselben Seite über ?odw_ds=<ID> mit der bestehenden Karte (der CPT hat bewusst keine öffentlichen Einzelseiten); „Zurück zum Katalog" führt auf die besuchte Listenseite.
  • Eigene Paginierung über ?odw_page=<n> (nicht page/paged).
  • Ein Katalog pro Seite: Block mit "multiple": false, Einschränkung in README/CHANGELOG.
  • Performance: Die Liste liest Roh-Meta aus dem Cache, den WP_Query vorlädt — statt 29–32 Carbon-Fields-Abfragen pro Karte bleibt eine Seite bei rund einem halben Dutzend Abfragen. Auswahlfelder (Format, Lizenz, Zugriffsrecht) werden dabei genau wie in Carbon Fields ausgewertet (ungültiger Wert → erste Option, fehlende Meta → Standardwert), damit Liste und Karte nie auseinanderlaufen.
  • Links bleiben auf der aufgerufenen Website (auch gegen //fremde-domain im Pfad), Unterseiten (<!--nextpage-->), Vorschau, Feeds und REST-Antworten verlinken richtig.
  • ODW_Shortcode: gemeinsame öffentliche Helfer (license_label(), file_info(), download_target(), format_bytes(), contact_line()). Die Karte gibt dasselbe aus wie zuvor; einzige Änderung: Die Kontakt-E-Mail ist per antispambot() verschleiert (nur reine ASCII-Adressen).
  • Sichtbarkeit: Entwürfe, private, geplante und passwortgeschützte Datensätze erscheinen weder in der Liste noch über ?odw_ds=. Der Beispieldatensatz ist nur ausgeblendet, solange er unverändert ist.
  • Änderung außerhalb des Katalogs: _odw_modified (dct:modified) folgt jetzt post_modified statt dem heutigen Datum. Beim normalen Speichern identisch; ein geplanter Datensatz behält beim Veröffentlichen durch den Cron sein Bearbeitungsdatum — sonst widersprächen sich Sortierung „zuletzt aktualisiert" und angezeigtes Datum.
  • Blocktitel/-beschreibungen (Katalog und Datensatz-Karte) jetzt übersetzt; CSS für Reflow bei 320 px und sichtbaren Tastaturfokus; eigener Playwright-Berichtsordner je CI-Schritt.
  • Doku & Version: README, DOCUMENTATION.md, CLAUDE.md, CHANGELOG, Version 2.43.0.

Review

Zwei Prüfrunden mit adversarischer Gegenprüfung je Befund:

  1. Review des Features (6 Linsen + Vollständigkeitskritik): 19 bestätigte Befunde, 1 strittig → alle behoben in ecde150.
  2. Gegenprüfung dieses Korrektur-Commits: 3 neue, geringe Fehler (Escaping-Reihenfolge, Sprach-Domains, Customizer-Cache) → behoben in cd89b6e.

Tests

  • tests/test-catalog.php — Attribute, Anfrage, Query-Argumente, Trefferzeile/Position, Seitenfenster, Listen-Daten inkl. Auswahlfeld-Regeln, Basisadresse, frühes Stylesheet, Beispieldatensatz, Änderungsdatum; Wächter gegen Rohzugriffe auf Auswahlfelder und nicht-flache Felder. Jede Korrektur per Mutation gegengeprüft.
  • tests/test-shortcode.php — Helfer der Karte inkl. Kontaktzeile.
  • tests/e2e/catalog.spec.js (8 Tests) samt Saat und eigenem CI-Schritt.

Lokal grün: PHPUnit (336 Tests), PHPCS, PHPStan, Übersetzungsprüfung, Paketprüfung des 2.43.0-ZIPs; E2E in der CI.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JB1xUQM892bVZ4Yv3MZjvq

…2.43.0)

Neben der Download-Card für einen einzelnen Datensatz gibt es jetzt eine
Übersicht aller veröffentlichten Datensätze auf einer Seite.

- ODW_Catalog (includes/class-catalog.php): Liste mit Titel, Datum, Auszug,
  Badges (Thema, Format, Größe, Lizenz, eingeschränkter Zugang) und direktem
  Datei-/Datenangebots-Link; Attribute per_page, orderby, theme, title,
  excerpt, show_demo; Filter odw_catalog_query_args.
- Detailansicht auf derselben Seite über ?odw_ds=<ID> mit der bestehenden
  Karte, weil der CPT bewusst keine öffentlichen Einzelseiten hat. Eigene
  Paginierung über ?odw_page=<n> statt page/paged.
- Die Liste liest Roh-Meta aus dem Cache, den WP_Query vorlädt, statt die
  Karte je Eintrag zu rendern (Carbon Fields: 29–32 Abfragen pro Karte).
- Block odw/catalog (blocks/catalog/) ohne Build-Schritt, dynamisch.
- ODW_Shortcode: license_label(), file_info(), download_target() und
  format_bytes() als öffentliche Helfer für Karte und Katalog; Ausgabe der
  Karte unverändert bis auf die per antispambot() verschleierte E-Mail.
- Entwürfe, private, geplante und passwortgeschützte Datensätze erscheinen
  weder in der Liste noch in der Detailansicht.
- Tests: tests/test-catalog.php (38 Tests), Helfer-Tests in
  test-shortcode.php, E2E tests/e2e/catalog.spec.js samt Saat und CI-Schritt.
- Übersetzungen, verify-package, README/DOCUMENTATION/CLAUDE.md, CHANGELOG.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JB1xUQM892bVZ4Yv3MZjvq
Bei ?odw_page=999 erschien „Keine Datensätze gefunden." statt „Diese Seite
gibt es nicht." samt Link zur ersten Seite. WP_Query zählt die Treffer nur,
wenn die angefragte Seite welche enthält (set_found_posts() bricht bei leerem
Ergebnis ab); found_posts ist dann immer 0. Eine leere Seite hinter Seite 1
gilt jetzt unabhängig davon als „jenseits des Endes".

Aufgefallen am E2E-Test catalog.spec.js; der lokale Prüfstand bildete das
Core-Verhalten nicht nach.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JB1xUQM892bVZ4Yv3MZjvq
Ein Mehrlinsen-Review mit Gegenprüfung je Befund fand 19 bestätigte
Punkte (teils doppelt aus mehreren Linsen). Behoben:

- Liste = Karte bei Auswahlfeldern: Format, Lizenz und Zugriffsrecht
  werden wie in Carbon Fields ausgewertet (ungültiger Wert → erste
  Option, fehlende Meta → Standardwert). Der Wächter-Test verlangt das
  jetzt für jedes Auswahlfeld (select_meta()).
- Trefferzeile, aktuelle Seite und „jenseits des Endes" rechnen aus der
  tatsächlich gelaufenen Abfrage (odw_catalog_query_args/pre_get_posts),
  first_position() nach den Regeln von WP_Query (offset, nopaging).
- base_url(): Links bleiben auf der eigenen Website (same_site_url() gegen
  //fremde-domain im REQUEST_URI); Unterseiten (<!--nextpage-->) und
  Vorschau behalten ihre Adresse; Feeds und REST-Antworten verlinken den
  Beitrag statt des Feeds/Endpunkts.
- Kontakt-E-Mail nur bei reinem ASCII per antispambot() verschleiert —
  bei einer Umlaut-Domain blieb die Kontaktzeile sonst leer
  (ODW_Shortcode::contact_line()).
- Ein Katalog pro Seite: "multiple": false im Block, in README/CHANGELOG.
- Beispieldatensatz nur ausgeblendet, solange er unverändert ist.
- _odw_modified aus post_modified statt „heute": Ein geplanter Datensatz
  behält beim Veröffentlichen durch den Cron sein Datum; Sortierung
  „zuletzt aktualisiert" und Anzeige stimmen überein.
- Blocktitel, -beschreibung und -schlagworte (Katalog und Datensatz-
  Karte) über register_block_type()-Argumente übersetzt.
- CSS: Grid-Spur minmax(0, 1fr) und Umbruch langer Wörter (Reflow bei
  320 px); sichtbarer Fokus auch für den Karten-Button im Katalog.
- Verwaiste Anhang-Verweise kosten keine Einzelabfrage mehr.
- CI: eigener Playwright-Berichtsordner je E2E-Schritt.
- Tests: Unit-Tests für alle Punkte (per Mutation geprüft: jede der neun
  Mutationen lässt einen Test fehlschlagen); E2E-Test zum Stylesheet
  ehrlich beschrieben, das frühe Einbinden sichern jetzt Unit-Tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JB1xUQM892bVZ4Yv3MZjvq
Eine Gegenprüfung des Korrektur-Commits fand drei neue Fehler darin:

- Reihenfolge in der Basisadresse: esc_url_raw() lief vor
  remove_query_arg() und strich dadurch Zeichen wie ^ { } ` aus fremden
  Query-Parametern (Suchbegriff a^b wurde beim Blättern zu ab). Jetzt erst
  remove_query_arg() (kodiert neu), dann esc_url_raw(), zuletzt genau ein
  führender Schrägstrich — request_base().
- Wurzelrelativ statt Schema und Host aus home_url(): Bei Sprachen auf
  eigenen (Sub-)Domains (Polylang) sprangen die Links sonst auf die
  Hauptdomain. Der Schutz gegen //fremde-domain bleibt (genau ein /).
- Negativ-Cache für gelöschte Anhänge nicht bei ausgesetzter
  Cache-Aufnahme (Widgets in der Customizer-Vorschau): Dort fehlen auch
  vorhandene Anhänge im Cache, die Datei-Links wären verschwunden.

Dazu: Der Wächter-Test erkennt jetzt auch einen zusätzlichen Rohzugriff
auf ein Auswahlfeld; README/CHANGELOG sagen genau, was „ein Katalog pro
Seite" heißt (auch nicht zusätzlich als Widget) und dass das neue
Änderungsdatum ab dem nächsten Speichern gilt.

Per Mutation geprüft: vertauschte Reihenfolge, fehlender
Schrägstrich-Schutz und zusätzlicher Rohzugriff lassen je einen Test
fehlschlagen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JB1xUQM892bVZ4Yv3MZjvq
@daimpad
daimpad merged commit cf9b28e into main Oct 27, 2026
22 checks passed
@daimpad
daimpad deleted the claude/fix-data-prep-errors-kJYpl branch October 27, 2026 17:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants