From a262fa064b29e8cae0c5966e785b8650bcb28abb Mon Sep 17 00:00:00 2001 From: Scott Poulin Date: Sun, 17 Aug 2025 12:32:15 -0400 Subject: [PATCH] Taxonomy filter to respect query loop settings --- build/taxonomy/render.php | 43 +++++++++++++++++++++++++++++-- src/taxonomy/render.php | 53 +++++++++++++++++++++++++++++++++------ 2 files changed, 87 insertions(+), 9 deletions(-) diff --git a/build/taxonomy/render.php b/build/taxonomy/render.php index 01d9800..6768950 100644 --- a/build/taxonomy/render.php +++ b/build/taxonomy/render.php @@ -18,11 +18,50 @@ $base_url = remove_query_arg( [ $query_var, $page_var ] ); } -$terms = get_terms( [ +// 2025.08 - add support for both basic and Advanced Query Loop tax filtering +// get_terms doesn't support all possibilities from AQL, limit to include/exclude +// users could specify nonsense queries, ie same terms in include/exclude, but get_terms only supports one or the other, and include takes priority +$args = [ 'hide_empty' => true, 'taxonomy' => $attributes['taxonomy'], 'number' => 100, -] ); + 'include' => [], + 'exclude' => [], + 'exclude_tree' => [], +]; + +// AQL first, it has priority. AND not supported for more than one query. +if ( isset( $block->context['query']['tax_query']['queries'] ) and is_array( $block->context['query']['tax_query']['queries'] ) and count( $block->context['query']['tax_query']['queries'] ) > 0 and ( $block->context['query']['tax_query']['relation'] == 'OR' or count( $block->context['query']['tax_query']['queries'] ) == 1 ) ) { + foreach( $block->context['query']['tax_query']['queries'] as $qry ) { + // ignore unsupported queries + if ( $qry['taxonomy'] != $attributes['taxonomy'] or count( $qry['terms'] ) < 1 or ! in_array( $qry['operator'], ['IN', 'NOT IN'] ) ) { + continue; + } + // which array are we going to add to? + $add_to = 'include'; + if ( $qry['operator'] == 'NOT IN' ) { + if ( $qry['include_children'] ) { + $add_to = 'exclude_tree'; + } else { + $add_to = 'exclude'; + } + } + // AQL uses term names, not IDs + foreach( $qry['terms'] as $term ) { + $t = get_term_by('name', $term, $attributes['taxonomy']); + if ( $t ) { + $args[ $add_to ][] = $t->term_id; + } + } + } + + +} elseif ( isset( $block->context['query']['taxQuery'][ $attributes['taxonomy'] ] ) and is_array( $block->context['query']['taxQuery'][ $attributes['taxonomy'] ] ) and count( $block->context['query']['taxQuery'][ $attributes['taxonomy'] ] ) > 0 ) { + // much simpler + $args['include'] = $block->context['query']['taxQuery'][ $attributes['taxonomy'] ]; +} + +$terms = get_terms( $args ); if ( is_wp_error( $terms ) || empty( $terms ) ) { return; diff --git a/src/taxonomy/render.php b/src/taxonomy/render.php index 97258b4..6768950 100644 --- a/src/taxonomy/render.php +++ b/src/taxonomy/render.php @@ -7,22 +7,61 @@ $taxonomy = get_taxonomy( $attributes['taxonomy'] ); -if ( empty( $block->context['query']['inherit'] ) ) { +if ( $block->context['query']['inherit'] ) { + $query_var = sprintf( 'query-%s', $attributes['taxonomy'] ); + $page_var = 'page'; + $base_url = str_replace( '/page/' . get_query_var( 'paged' ), '', remove_query_arg( [ $query_var, $page_var ] ) ); +} else { $query_id = $block->context['queryId'] ?? 0; $query_var = sprintf( 'query-%d-%s', $query_id, $attributes['taxonomy'] ); $page_var = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page'; $base_url = remove_query_arg( [ $query_var, $page_var ] ); -} else { - $query_var = sprintf( 'query-%s', $attributes['taxonomy'] ); - $page_var = 'page'; - $base_url = str_replace( '/page/' . get_query_var( 'paged' ), '', remove_query_arg( [ $query_var, $page_var ] ) ); } -$terms = get_terms( [ +// 2025.08 - add support for both basic and Advanced Query Loop tax filtering +// get_terms doesn't support all possibilities from AQL, limit to include/exclude +// users could specify nonsense queries, ie same terms in include/exclude, but get_terms only supports one or the other, and include takes priority +$args = [ 'hide_empty' => true, 'taxonomy' => $attributes['taxonomy'], 'number' => 100, -] ); + 'include' => [], + 'exclude' => [], + 'exclude_tree' => [], +]; + +// AQL first, it has priority. AND not supported for more than one query. +if ( isset( $block->context['query']['tax_query']['queries'] ) and is_array( $block->context['query']['tax_query']['queries'] ) and count( $block->context['query']['tax_query']['queries'] ) > 0 and ( $block->context['query']['tax_query']['relation'] == 'OR' or count( $block->context['query']['tax_query']['queries'] ) == 1 ) ) { + foreach( $block->context['query']['tax_query']['queries'] as $qry ) { + // ignore unsupported queries + if ( $qry['taxonomy'] != $attributes['taxonomy'] or count( $qry['terms'] ) < 1 or ! in_array( $qry['operator'], ['IN', 'NOT IN'] ) ) { + continue; + } + // which array are we going to add to? + $add_to = 'include'; + if ( $qry['operator'] == 'NOT IN' ) { + if ( $qry['include_children'] ) { + $add_to = 'exclude_tree'; + } else { + $add_to = 'exclude'; + } + } + // AQL uses term names, not IDs + foreach( $qry['terms'] as $term ) { + $t = get_term_by('name', $term, $attributes['taxonomy']); + if ( $t ) { + $args[ $add_to ][] = $t->term_id; + } + } + } + + +} elseif ( isset( $block->context['query']['taxQuery'][ $attributes['taxonomy'] ] ) and is_array( $block->context['query']['taxQuery'][ $attributes['taxonomy'] ] ) and count( $block->context['query']['taxQuery'][ $attributes['taxonomy'] ] ) > 0 ) { + // much simpler + $args['include'] = $block->context['query']['taxQuery'][ $attributes['taxonomy'] ]; +} + +$terms = get_terms( $args ); if ( is_wp_error( $terms ) || empty( $terms ) ) { return;