当前位置: 首页 > 知识库问答 >
问题:

结合分类法的WP_查询ajax过滤

宓文斌
2023-03-14

我在Wordpress中有作为CPT的产品,并尝试使用复选框根据分类法筛选帖子。我有两种分类法,品牌和尺寸。它们在索引中是这样输出的。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_查询采用tax查询参数数组(它采用数组数组)。此构造允许您通过使用第一个(外部)数组中的关系参数来描述分类数组之间的布尔关系来查询多个分类。

所以我猜这两个分类法应该是tax_查询数组中的两个独立数组,但这能与foreach循环结合起来吗?

    foreach( $brands as $brand ) {
    if( isset( $_POST['brand_' . $brand->term_id ] ) && $_POST['brand_' . $brand->term_id] == 'on' )
         $all_terms[] = $brand->slug;
}

非常感谢

共有2个答案

诸葛文博
2023-03-14

这是我如何让它工作的

功能。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>

主要的事情是将税务查询数组放在一个有关系的地方=

呼延靖
2023-03-14

奥斯卡解决方案的补充如果有人想确定分类法“与”或“或”之间的关系,基于一个分类法,选择了多少分类法:以下是我的小调整:

if (empty($brands_terms) || empty($sizes_terms)) {
 $relation = 'OR';
}else{
 $relation = 'AND';
}

在查询arg中这样写;

'relation' => $relation,
 类似资料:
  • 为自定义分类法和相关自定义帖子类型构建Wordpress页面模板。在一个新的WP_查询中,我需要从(2)不同的ACF post对象字段中获取字段;列表人员和列表代表代码在wp_reset_postdata()之前按预期工作;返回正确数量的结果,每个帖子中的数据在重置点之前是唯一的。重置后,每个帖子中的所有数据都相同。代码如下,我确信有一个更优雅的解决方案:

  • 我正在开发一个插件,它将放在我的woocommerce产品侧栏中。我需要的是,给定产品id/对象,它将找到2个具有我以前创建的相同自定义分类法的产品。 通过这段代码,我得到了产品中使用的术语列表,其中“colline”是自定义分类法: 问题是我不知道如何获取自定义分类id,以及如何根据自定义分类对其进行过滤。 我已经使用WP_Query查找同一类别的产品,代码如下: 如何更改代码以获得所需的分类i

  • 我想让下面的代码对我的自定义posttype(产品类型)进行排序。因此,我的活动页面将只显示“油”一词的帖子,而不是“燃料”和“轮胎”。 //编辑,作为对以下3个答案的回复 我假设foreach循环是WP_查询方法的替代,但是tax_查询对我来说是新的,现在我知道它存在,我在codex中查找了它,但是它仍然不起作用。我诚实地认为,这就像我在tax_查询中错误地命名一样简单,因此我将在这里显示我的分

  • 我想得到两种不同分类法的帖子。 我只想列出那些带有标签或为type的帖子。 我尝试了以下代码,但不起作用:

  • 我的查询没有使用参数对我的帖子进行排序。 一点背景: 我在foreach语句中,该语句循环遍历“category”id的自定义分类法。在该foreach语句中,我试图调用一个新的WP_查询,从该foreach循环的每个“类别”获取帖子。我的args数组如下所示: 和都是此post\u类型中我的自定义分类中的数组。 和根本不起作用,我想不出原因。

  • 我有一个复杂的组查询。 数据如下: 汇总如下: null