JPKCom Post Filter — Anleitung & Tipps

Facettierte Taxonomie-Filter für Beiträge, Seiten und Custom Post Types mit JPKCom Post Filter — SEO-freundliche URLs, AJAX, Shortcodes, Blocks und Page-Builder-Support.

JPKCom Post Filter ergänzt jede WordPress-Archivseite um facettierte Taxonomie-Filter — für Beiträge, Seiten und beliebige Custom Post Types. Jeder Filterzustand steckt in einer SEO-freundlichen URL wie /blog/filter/web-design+marketing/wordpress/, ist also teilbar und bookmarkbar; gefiltert wird per AJAX, mit vollwertigem Fallback ohne JavaScript.

Anleitung

Voraussetzungen

  • WordPress 7.0 oder neuer (getestet bis WordPress 7.1)
  • PHP 8.3 oder neuer
  • Keine Abhängigkeiten: kein ACF, kein Bootstrap, kein jQuery nötig

Page-Builder-Unterstützung ist optional — die Gutenberg-Blocks, Elementor-Widgets und Oxygen-Elemente werden nur geladen, wenn der jeweilige Builder aktiv ist.

Installation

  1. Lade das Verzeichnis jpkcom-post-filter nach /wp-content/plugins/ hoch (oder installiere die ZIP via Plugins → Installieren → Plugin hochladen).
  2. Aktiviere das Plugin unter Plugins → Installierte Plugins.
  3. Wähle unter Post Filter → General die Post-Types, die gefiltert werden sollen.
  4. Lege unter Post Filter → Filter Groups die Taxonomien als Filter-Dimensionen an.
  5. Öffne Einstellungen → Permalinks und klicke auf Änderungen speichern, um die Rewrite-Regeln neu zu schreiben.

Filter-Gruppen konfigurieren

Jede Filter-Gruppe ordnet eine Taxonomie einer URL-Position zu; die Reihenfolge der Gruppen bestimmt die Reihenfolge der URL-Segmente. Pro Gruppe legst du Taxonomie, Label, betroffene Post-Types, numerische Sortierung (Order) und einen Ein/Aus-Schalter (Enabled) fest.

Du kannst direkt aus der Filter-Groups-Seite neue Taxonomien registrieren (Option „Register as new WordPress taxonomy"): Slug, Rewrite-Slug, hierarchisch/flach, öffentlich, Admin-Spalte und REST-API-Sichtbarkeit (für Gutenberg nötig) sind einstellbar.

Achtung: Löschst du eine Filter-Gruppe, die eine eigene Taxonomie registriert hat, wird diese Taxonomie deregistriert — alle Term-Zuweisungen an Beiträge gehen dabei unwiderruflich verloren.

Ausgabe: Auto-Inject, Shortcodes, Blocks

Es gibt drei Wege, Filter und Liste auszugeben:

  • Auto-Inject (General → Auto-Inject Filter): Das Plugin umschließt die Archiv-Schleife des Themes automatisch mit der Filter-UI — ohne Shortcode oder Template-Eingriff. Es hängt sich dafür an loop_start/loop_end auf Archiv-/Blog-Seiten (nicht auf Einzelbeiträgen, Suche oder Seiten).
  • Shortcodes: [jpkcom_postfilter_filter], [jpkcom_postfilter_list] und [jpkcom_postfilter_pagination]. Der interaktive Shortcode-Builder unter Post Filter → Shortcodes erzeugt fertige Snippets.
  • Builder: je drei Gutenberg-Blocks, Elementor-Widgets und Oxygen-Elemente (Post Filter, Post List, Post Pagination).
[jpkcom_postfilter_filter post_type="portfolio" layout="dropdown"]
[jpkcom_postfilter_list post_type="portfolio" layout="cards" limit="12"]
[jpkcom_postfilter_pagination post_type="portfolio"]

Wichtig: Shortcodes (und Blocks/Widgets/Elemente) hängen immer am Archiv des konfigurierten Post-Types. Sie funktionieren nur auf einer Archiv-Template-Seite oder auf der unter Einstellungen → Lesen als „Beitragsseite" gesetzten Seite. Auf einer beliebigen Seite (z. B. /test/) springen Filter-Klicks und AJAX zur Archiv-URL zurück — nutze dort lieber Auto-Inject.

Layout & Design

Unter Post Filter → Layout & Design stehen sechs Tabs bereit (Global, Filter, Posts, Pagination, Color Schemes, Advanced). Du wählst aus vier Filter-Layouts (Bar, Columns, Sidebar, Dropdown), drei Listen-Layouts (Cards, Rows, Minimal) und vier Farbschemata (Default, Dark, Contrast, Monochrome). Im Tab Advanced legst du u. a. den Stylesheet-Modus (Full / Variables only / Disabled), den Plus/Minus-Modus, die Sichtbarkeit des Reset-Buttons sowie eigenes Custom CSS fest.

Beiträge als Daten: die Abilities API

Seit Version 1.3.0 registriert das Plugin zwei nur lesende Abilities. Die Abilities API ist ein WordPress-Kernregister maschinenlesbarer Fähigkeiten — KI-Assistenten, MCP-Clients und REST-Automatisierung können damit Fragen zu deinen Beiträgen beantworten, ohne das Frontend auszulesen:

Ability Antwort
jpkcom-post-filter/list-filters nach welchen Taxonomien und Termen ein Post-Type gefiltert werden kann, mit Beitragszahl je Term
jpkcom-post-filter/query-posts eine gefilterte, seitenweise Query samt Treffern und teilbarer Filter-URL

Der Sinn des Paares: Die erste Ability nimmt der zweiten das Raten ab. Ein Assistent schlägt die echten Taxonomie-Schlüssel und Term-Slugs nach und filtert dann mit Werten, die es gibt. Ein Filter, der eine Taxonomie nennt, die deine Site nicht hat, wird mit einer Fehlermeldung samt Liste der gültigen abgewiesen — er liefert nie still das komplette Archiv zurück.

Beide sind unter /wp-json/wp-abilities/v1/ erreichbar und antworten auf GET:

GET /wp-json/wp-abilities/v1/abilities/jpkcom-post-filter/query-posts/run
      ?input[post_type]=post&input[filters][category][]=allgemein&input[per_page]=3

query-posts nimmt post_type, filters, page, per_page (1–50) und search an. Terme innerhalb einer Taxonomie werden mit ODER verknüpft, verschiedene Taxonomien mit UND — dieselbe Logik wie die Filterleiste auf deiner Site. Ein Term-Slug, der auf nichts passt, ist kein Fehler: Die Query läuft, und der Slug erscheint unter unknown_terms, sodass ein Aufrufer einen Tippfehler von einem leeren Ergebnis unterscheiden kann.

Wichtig für die Interpretation: filter_url kommt leer zurück, sobald keine Frontend-Adresse genau die Beiträge zeigen würde, die daneben stehen. Das sind fünf Fälle: ein Post-Type ohne Archivseite; eine Filter-Kombination jenseits deiner konfigurierten Limits; eine Seite nach der ersten mit einer anderen Seitengröße als der Site-eigenen „Beiträge pro Seite"; eine Seite hinter der letzten; und — seit 1.3.1 — ein angewendeter search-Begriff, denn eine Filter-URL kann keinen Suchbegriff tragen und würde eine größere, andere Liste zeigen. Die Ergebnisse sind in allen diesen Fällen vollständig; nur der Link fehlt.

Was ausgegeben wird und an wen:

  • Als Grundregel ausschließlich veröffentlichte Beiträge: Der Beitragsstatus steht fest im Code, ein Aufrufer kann ihn nicht als Parameter setzen. Das ist aber keine Garantie, und die Entwickler-Doku des Plugins sagt das seit 1.3.1 ausdrücklich: post_status ist eine gewöhnliche Query-Var, und wer die Query vorher anfasst — ein anderes Plugin über pre_get_posts ohne is_main_query()-Schutz oder der dokumentierte Filter jpkcom_postfilter_query_args — verändert, was zurückkommt. Ein zweites Lese-Gate hinter der Query gibt es hier nicht (das Schwester-Plugin jpkcom-acf-jobs hat eines). Auf einer Site mit solchen Eingriffen also nicht darauf verlassen, dass Entwürfe unerreichbar sind.
  • Nur Post-Types, die du fürs Filtern freigeschaltet hast, und nur Taxonomien, die du als Filter-Gruppen konfiguriert hast.
  • Ausführen erfordert einen angemeldeten Benutzer mit der Fähigkeit read. Die bloße Liste der Abilities samt Beschreibungen und Parameter-Schemata sieht dagegen jeder angemeldete Benutzer, auch ein Abonnent — so schirmt WordPress jede Ability ab, das ist nichts Plugin-Spezifisches.

Abschalten in der wp-config.php:

define( 'JPKCOM_POSTFILTER_ABILITIES', false );

Fähigkeit anheben, Abilities aber behalten:

add_filter( 'jpkcom_postfilter_ability_capability', static fn(): string => 'edit_posts' );

Willst du sie aus MCP-Clients heraushalten, die REST-Route aber behalten (oder umgekehrt), ist jpkcom_postfilter_ability_meta der richtige Hebel.

Tipps & Tricks

  • Cache-Leerung wirkte nicht vollständig — behoben in 1.3.1: Das Leeren des Caches räumte die schnellste Schicht nie mit ab. Speichern eines Beitrags, Bearbeiten eines Terms, Speichern der Einstellungen und beide „Clear cache"-Buttons im Admin meldeten Erfolg und ließen veraltete Query-Ergebnisse trotzdem stehen — bis sie von selbst abliefen, standardmäßig bis zu einer Stunde. Das betrifft jede Site mit APCu, unabhängig davon, ob du die Abilities nutzt — die tote Lösch-Schleife lag in genau diesem Zweig.
  • URL-Endpunkt ändern: Standardmäßig steckt der Filter unter /filter/. Den Pfad-Bestandteil änderst du unter General → URL Endpoint und klickst danach auf Flush Rewrite Rules (oder speicherst die Permalinks neu).
  • Verhalten ohne Filter-Terme: Über Bare Endpoint Behaviour stellst du ein, was bei Aufruf von /filter/ ohne Terme passiert — 404, Redirect zur Blog-Startseite oder eine eigene URL.
  • Mehrere Filter-Instanzen pro Seite: Jeder Satz aus Filter/Liste/Pagination wird über das post_type-Attribut gepaart (data-jpkpf-post-type). So lassen sich verschiedene Post-Types auf einer Seite unabhängig filtern.
  • Fragment-Antworten statt ganzer Seiten: Seit Version 1.2.0 beantwortet das Plugin einen Filter-Klick nur noch mit den austauschbaren Zonen — Theme-Header, Navigationsmenüs, Sidebar-Widgets und die komplette Asset-Pipeline entfallen (auf einer Testinstallation 60–72 % weniger Transfer und 5–19 % weniger Serverzeit). Die Anfrage läuft über ein eigenes URL-Segment /jpkpf-fragment/ statt über einen Query-Parameter, damit ein Page-Cache, der unbekannte Parameter abschneidet, keinem normalen Besucher ein nacktes Fragment ausliefern kann. Die dafür nötigen Rewrite-Regeln werden nach einem Versionswechsel einmalig automatisch neu geschrieben — ein manuelles Permalink-Speichern ist nach dem Update also nicht nötig.
  • HTML-Minifier und Fragmente — behoben in 1.4.4: Mit einem HTML-minifizierenden Optimierungs-Plugin lieferte jeder Filter-Klick eine leere Antwort, und die Liste meldete „Keine Beiträge gefunden." — auf einer Site, auf der weiterhin alle Beiträge passten. Das Fragment wurde an HTML-Kommentar-Markern aus der gerenderten Seite geschnitten, und genau die entfernt ein Minifier; Autoptimize tut das in seinen Werkseinstellungen, und sein Output-Buffer läuft vor dem des Plugins. Auf der Prüfinstallation gemessen: 18 300 Bytes ohne Autoptimize, 0 Bytes mit, wieder 18 300 mit abgeschalteter HTML-Optimierung. Seit 1.4.4 sind die Marker leere <template>-Elemente — Elemente entfernt kein Minifier, und in den Browser gelangen die Marker so oder so nicht. Zusätzlich bitten Fragment-Anfragen die bekannten Optimierer, sie in Ruhe zu lassen: über Autoptimizes eigenen Filter und die anbieterübergreifende DONOTMINIFY-Konvention. Weitere Anbieter trägst du aus einem mu-Plugin über jpkcom_postfilter_fragment_noptimize_filters nach — die Registrierung passiert schon beim Laden des Plugins, ein reguläres Plugin käme zu spät. Und falls eine Fragment-Antwort doch einmal unbrauchbar ankommt, lädt das Skript die Seite jetzt vollständig neu, statt fälschlich „keine Beiträge" zu melden.
  • Vier Cache-Schichten: Object-Cache, Transients, APCu und ein PHP-Datei-Cache für Einstellungen halten die Ausgabe schnell. Caches werden bei save_post/deleted_post bzw. Term-Änderungen automatisch invalidiert; manuell leerst du sie unter Post Filter → Cache.
  • CSS sauber überschreiben: Alle Styles nutzen CSS-Custom-Properties mit Präfix --jpkpf-. Setze sie im Theme-Stylesheet, in den Variablen-Feldern unter Layout & Design oder über das Custom-CSS-Feld. Für volle Kontrolle den Stylesheet-Modus auf „Disabled" stellen.
  • Templates pro Theme überschreiben: Der Loader prüft Child-Theme → Parent-Theme → mu-plugins/jpkcom-post-filter-overrides/templates/ → Plugin-templates/. Kopiere z. B. templates/partials/list/list-cards.php nach themes/dein-theme/jpkcom-post-filter/partials/list/list-cards.php.
  • Einstellungen migrieren: Unter Post Filter → Import / Export exportierst du alle Einstellungen (general, layout, cache, filter_groups) als JSON und spielst sie auf einer anderen Umgebung wieder ein.
  • Konstanten in wp-config.php: u. a. JPKCOM_POSTFILTER_URL_ENDPOINT, JPKCOM_POSTFILTER_CACHE_ENABLED, JPKCOM_POSTFILTER_DEBUG und JPKCOM_POSTFILTER_MAX_FILTER_COMBOS lassen sich überschreiben.
  • Gutenberg-Blocks aus Quellcode bauen: Die Block-Editor-Skripte brauchen einen Build (npm install && npm run build, Ausgabe nach blocks/build/). Fehlt das Build-Verzeichnis, überspringt das Plugin die Block-Registrierung.
  • Deutsche Übersetzung: Der Übersetzungs-Katalog war zuletzt bei 1.1.2 erzeugt worden und lief danach zwölf Releases lang hinter dem Code her, sodass alles seither Hinzugekommene auf einer deutschen Site englisch erschien. Seit 1.4.1 deckt er wieder das ganze Plugin ab, seit 1.4.2 sind 46 fehlende deutsche Übersetzungen ergänzt — Block-Titel samt Beschreibungen und Suchbegriffen, die Elementor- und Oxygen-Widget-Labels, mehrere Einstellungs-Hinweise und die Sicherheitsmeldungen des Updaters. Die Texte der Abilities bleiben bewusst englisch: Sie werden von KI-Clients und Automatisierung gelesen, nicht im Admin-Bereich, und ihr genauer Wortlaut ist das, woran ein Aufrufer eine falsche Anfrage in einem Anlauf korrigiert.
  • Barrierefrei & SEO-tauglich: Filter-Terme sind echte <a>-Links (Reload ohne JS), die Ergebnis-Zone nutzt aria-live, Toggle-Buttons aria-pressed. Jede Filter-Kombination hat eine crawlbare URL mit gesetztem Canonical gegen Duplicate Content.

Weiterführende Informationen