[英]WP_query ajax filtering with combined taxonomies
我在 Wordpress 中有作为 CPT 的产品,我正在尝试使用复选框根据分类法过滤帖子。 我有两个分类法,品牌和尺寸。 它们在 index.php 文件中是这样输出的:
<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter">
<?php
if( $brands = get_terms( array( 'taxonomy' => 'brand' ) ) ) :
foreach( $brands as $brand ) :
echo '<p><input type="checkbox" id="brand_' . $brand->term_id . '" name="brand_' . $brand->term_id . '" /><label for="brand_' . $brand->term_id . '">' . $brand->name . '</label></p>';
endforeach;
endif;
?>
<?php
if( $sizes = get_terms( array( 'taxonomy' => 'sizes' ) ) ) :
foreach( $sizes as $size ) :
echo '<p><input type="checkbox" id="size_' . $size->term_id . '" name="size_' . $size->term_id . '" /><label for="size_' . $size->term_id . '">' . $size->name . '</label></p>';
endforeach;
endif;
?>
<button>Apply filter</button>
<input type="hidden" name="action" value="myfilter">
</form>
在我的 functions.php 文件中,我有以下内容来构建 WP_query 并包含分类法:
function misha_filter_function(){
$args = array(
'orderby' => 'date',
'post_type' => 'clothing_product',
'posts_per_page' => -1
);
//brand checkboxes
if( $brands = get_terms( array( 'taxonomy' => 'brand' ) ) ) :
$all_terms = array();
foreach( $brands as $brand ) {
if( isset( $_POST['brand_' . $brand->term_id ] ) && $_POST['brand_' . $brand->term_id] == 'on' )
$all_terms[] = $brand->slug;
}
if( count( $all_terms ) > 0 ) {
$args['tax_query'] = array(
array(
'taxonomy' => 'brand',
'field' => 'slug',
'terms'=> $all_terms
)
);
}
endif;
//sizes checkboxes
if( $sizes = get_terms( array( 'taxonomy' => 'sizes' ) ) ) :
$all_terms = array();
foreach( $sizes as $size ) {
if( isset( $_POST['size_' . $size->term_id ] ) && $_POST['size_' . $size->term_id] == 'on' )
$all_terms[] = $size->slug;
}
if( count( $all_terms ) > 0 ) {
$args['tax_query'] = array(
array(
'taxonomy' => 'sizes',
'field' => 'slug',
'terms'=> $all_terms
)
);
}
endif;
$query = new WP_Query( $args );
if( $query->have_posts() ) :
while( $query->have_posts() ): $query->the_post();
echo '<h2>' . $query->post->post_title . '</h2>';
endwhile;
wp_reset_postdata();
else :
echo 'No posts found';
endif;
die();
}
add_action('wp_ajax_myfilter', 'misha_filter_function');
add_action('wp_ajax_nopriv_myfilter', 'misha_filter_function');
这是 scripts.js 中的 AJAX/jQuery:
jQuery(function($){
$('#filter').submit(function(){
var filter = $('#filter');
$.ajax({
url:filter.attr('action'),
data:filter.serialize(), // form data
type:filter.attr('method'), // POST
beforeSend:function(xhr){
filter.find('button').text('Processing...'); // changing the button label
},
success:function(data){
filter.find('button').text('Apply filter'); // changing the button label back
$('#response').html(data); // insert data
}
});
return false;
});
});
我得到的是一个半工作结果,其中为所有可用品牌和尺寸创建了复选框,并且可以进行过滤。 问题是,如果选中 XL 码和 Nike 品牌,它会拉出所有 XL 码的产品,甚至是非 Nike 的品牌,这不是我想要的。
查看 Wordpress 法典,
tax_query 接受一组税务查询参数数组(它接受一组数组)。 此构造允许您通过使用第一个(外部)数组中的关系参数来查询多个分类法,以描述分类法数组之间的布尔关系。
所以我猜这两个分类法应该是 tax_query 数组中的两个单独的数组,但它能以某种方式与 foreach 循环结合吗?
foreach( $brands as $brand ) {
if( isset( $_POST['brand_' . $brand->term_id ] ) && $_POST['brand_' . $brand->term_id] == 'on' )
$all_terms[] = $brand->slug;
}
非常感谢
这是我如何让它工作的
函数.php
function misha_filter_function(){
//brands checkboxes
if( $brands = get_terms( array( 'taxonomy' => 'brand' ) ) ) :
$brands_terms = array();
foreach( $brands as $brand ) {
if( isset( $_POST['brand_' . $brand->term_id ] ) && $_POST['brand_' . $brand->term_id] == 'on' )
$brands_terms[] = $brand->slug;
}
endif;
//sizes checkboxes
if( $sizes = get_terms( array( 'taxonomy' => 'sizes' ) ) ) :
$sizes_terms = array();
foreach( $sizes as $size ) {
if( isset( $_POST['size_' . $size->term_id ] ) && $_POST['size_' . $size->term_id] == 'on' )
$sizes_terms[] = $size->slug;
}
endif;
$args = array(
'orderby' => 'date',
'post_type' => 'clothing_product',
'posts_per_page' => -1,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'brand',
'field' => 'slug',
'terms' => $brands_terms
),
array(
'taxonomy' => 'sizes',
'field' => 'slug',
'terms' => $sizes_terms
)
)
);
$query = new WP_Query( $args );
if( $query->have_posts() ) :
while( $query->have_posts() ): $query->the_post();
echo '<h2>' . $query->post->post_title . '</h2>';
endwhile;
wp_reset_postdata();
else :
echo 'No posts found';
endif;
die();
}
add_action('wp_ajax_myfilter', 'misha_filter_function');
add_action('wp_ajax_nopriv_myfilter', 'misha_filter_function');
形式
<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter">
<div>
<?php
if( $brands = get_terms( array( 'taxonomy' => 'brand' ) ) ) :
echo '<ul class="brands-list">';
foreach( $brands as $brand ) :
echo '<input type="checkbox" class="" id="brand_' . $brand->term_id . '" name="brand_' . $brand->term_id . '" /><label for="brand_' . $brand->term_id . '">' . $brand->name . '</label>';
if ($brand !== end($brands)) { echo '<li class="list-spacer">/</li>'; }
endforeach;
echo '</ul>';
endif;
?>
</div>
<div>
<?php
if( $sizes = get_terms( array( 'taxonomy' => 'sizes' ) ) ) :
echo '<ul class="sizes-list">';
foreach( $sizes as $size ) :
echo '<input type="checkbox" class="" id="size_' . $size->term_id . '" name="size_' . $size->term_id . '" /><label for="size_' . $size->term_id . '">' . $size->name . '</label>';
if ($size !== end($sizes)) { echo '<li class="list-spacer">/</li>'; }
endforeach;
echo '</ul>';
endif;
?>
</div>
<button class="btn btn-primary">Filter</button>
<input type="hidden" name="action" value="myfilter">
</form>
主要是将税务查询数组放在一个地方,关系 => AND。 没有改变 jQuery/AJAX。 应该注意的是,如果没有选中任何框,此代码不会“显示全部”。
除了 Oscar 的解决方案如果有人想根据选择了多少分类法来确定分类法“AND”或“OR”之间的关系:这是我的小调整:
if (empty($brands_terms) || empty($sizes_terms)) {
$relation = 'OR';
}else{
$relation = 'AND';
}
在查询 arg 中这样写;
'relation' => $relation,
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.