WP_query ajax 使用组合分类进行过滤
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 Codex,
tax_query takes an array of tax query arguments arrays (it takes an array of arrays). This construct allows you to query multiple taxonomies by using the relation parameter in the first (outer) array to describe the boolean relationship between the taxonomy arrays.
所以我猜这两个分类法应该是 tax_query 数组中的两个单独的数组,但它能以某种方式与 foreach 循环结合吗?
foreach( $brands as $brand ) {
if( isset( $_POST['brand_' . $brand->term_id ] ) && $_POST['brand_' . $brand->term_id] == 'on' )
$all_terms[] = $brand->slug;
}
非常感谢
这是我如何让它工作的
Functions.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。应该注意的是,如果没有选中任何框,则此代码不会 "display all"。
添加到 Oscar 的解决方案
如果有人想根据选择了多少分类法来确定分类法 "AND" 或 "OR" 之间的关系:
这是我的小调整:
if (empty($brands_terms) || empty($sizes_terms)) {
$relation = 'OR';
}else{
$relation = 'AND';
}
在查询arg中这样写;
'relation' => $relation,
我在 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 Codex,
tax_query takes an array of tax query arguments arrays (it takes an array of arrays). This construct allows you to query multiple taxonomies by using the relation parameter in the first (outer) array to describe the boolean relationship between the taxonomy arrays.
所以我猜这两个分类法应该是 tax_query 数组中的两个单独的数组,但它能以某种方式与 foreach 循环结合吗?
foreach( $brands as $brand ) {
if( isset( $_POST['brand_' . $brand->term_id ] ) && $_POST['brand_' . $brand->term_id] == 'on' )
$all_terms[] = $brand->slug;
}
非常感谢
这是我如何让它工作的
Functions.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。应该注意的是,如果没有选中任何框,则此代码不会 "display all"。
添加到 Oscar 的解决方案 如果有人想根据选择了多少分类法来确定分类法 "AND" 或 "OR" 之间的关系: 这是我的小调整:
if (empty($brands_terms) || empty($sizes_terms)) {
$relation = 'OR';
}else{
$relation = 'AND';
}
在查询arg中这样写;
'relation' => $relation,