Du baust in Bricks einen Query-Loop, trägst unter Query → Taxonomie einen Term ein, speicherst — und im Frontend erscheinen trotzdem alle Beiträge. Im Builder sieht die Vorschau oft sogar richtig aus, was die Fehlersuche zusätzlich verzögert.
Das Verhalten ist kein Bug im engeren Sinn, sondern eine Folge davon, wie Bricks die Query-Argumente zusammensetzt. Der Ausweg ist ein anderer als erwartet.
Getestet mit
- WordPress 6.8
- Bricks 2.3.7
- PHP 8.3
- Eigene Taxonomie
projekt_kategoriean einem CPTprojekt
Das Problem im Detail
Gesetzt war die Bedingung direkt am Loop-Element:
{
"post_type": ["projekt"],
"tax_query": [
{
"taxonomy": "projekt_kategorie",
"field": "slug",
"terms": ["webshop"]
}
]
}
Ergebnis im Frontend: alle Projekte, ungefiltert. Der tax_query-Block wird beim Zusammenbauen der finalen Query verworfen.
Die Lösung: Query-Variable durchreichen
Statt den Filter statisch in den Loop zu schreiben, gibst du ihn als Query-Variable an die Seite und lässt den Loop die Hauptabfrage verwenden.
Schritt 1: Die Variable registrieren
In die functions.php des Child-Themes:
add_filter( 'query_vars', function ( $vars ) {
$vars[] = 'projekt_kategorie';
return $vars;
} );
Schritt 2: Den Loop auf die Hauptabfrage stellen
Am Loop-Element in den Query-Einstellungen kein tax_query setzen, sondern nur:
{
"post_type": ["projekt"],
"posts_per_page": 12
}
Schritt 3: Die Query vor dem Lauf anpassen
add_action( 'pre_get_posts', function ( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
$slug = get_query_var( 'projekt_kategorie' );
if ( ! $slug ) {
return;
}
$query->set( 'tax_query', [
[
'taxonomy' => 'projekt_kategorie',
'field' => 'slug',
'terms' => sanitize_title( $slug ),
],
] );
} );
Aufgerufen wird die Seite dann als /projekte/?projekt_kategorie=webshop. Wenn du saubere URLs willst, kommt noch eine Rewrite-Regel dazu — aber prüf zuerst, ob der Filter überhaupt greift, bevor du dir das antust.
Ich habe am falschen Ende gesucht
Weil die Builder-Vorschau richtig gefiltert hat, war ich überzeugt: Die Query stimmt, irgendein Cache verfälscht das Frontend. Also Objekt-Cache geleert. Dann Seiten-Cache. Dann CSS neu generiert. Nichts änderte sich.
Klick gemacht hat es erst beim Blick auf die tatsächlich ausgeführte SQL-Abfrage:
add_action( 'wp_footer', function () {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
global $wp_query;
echo '<pre>' . esc_html( $wp_query->request ) . '</pre>';
} );
In der Ausgabe fehlte jeder JOIN auf wp_term_relationships. Der Filter kam gar nicht erst bei der Datenbank an — damit war jede Cache-Theorie erledigt.
Woran ich seitdem bei Query-Problemen zuerst denke: erst das erzeugte SQL ansehen, dann alles andere. Es beantwortet in fünf Sekunden, ob der Filter überhaupt ankommt, und die Antwort entscheidet, in welche Richtung du weitersuchst.
Kontrolle
Ruf die Seite mit und ohne Parameter auf und vergleiche die Trefferzahl:
curl -s "https://DEINE-DOMAIN.AT/projekte/" | grep -c 'class="projekt-card'
curl -s "https://DEINE-DOMAIN.AT/projekte/?projekt_kategorie=webshop" | grep -c 'class="projekt-card'
Die zweite Zahl muss kleiner sein. Ist sie gleich, greift der Filter nicht — dann prüf mit dem SQL-Schnipsel oben, ob der JOIN vorhanden ist.
Häufige Fehler
Der Filter greift, aber die Seitennummerierung ist kaputt.
Du musst den Parameter in den Pagination-Links mitschleifen. Bricks hängt ihn nicht automatisch an.
Kann ich mehrere Kategorien gleichzeitig filtern?
Ja, übergib sie kommagetrennt und zerlege den Wert mit explode, bevor du ihn als terms-Array setzt. Sanitize dabei jeden Wert einzeln.
Warum nicht einfach das Archiv der Taxonomie verwenden?
Wenn dir /projekt_kategorie/webshop/ reicht, ist das der bessere Weg — weniger Code, saubere URLs. Die Query-Variable brauchst du erst, wenn der Filter auf einer bestehenden Seite sitzen soll, die noch anderen Inhalt trägt.