按 2 个分类过滤帖子的功能

Function to filter posts by 2 taxonomies

我有一个 page of cruises,我可以在其中按 2 种不同的分类法进行过滤(抱歉,该页面是西班牙语,英文版不完整)。 我遇到的问题是我不能让过滤器一直工作。例如,如果我使双重过滤器起作用,则过滤一种它不起作用的分类法。如果简单过滤器有效,双重过滤器则无效。

这是当前代码,它可以完美地按 2 个分类法进行过滤,但如果我只使用一个分类法进行过滤则不会。

    function belmondo_modify_cruise_archive_query( $query ) {
    if( is_archive() && is_post_type_archive('cruise') && $query->is_main_query() && isset($_GET['ct']) && isset($_GET['co'])) {
        $taxquery = array(
            'relation' => 'AND',
            array(
                'taxonomy' => 'cruise_type',
                'field' => 'slug',
                'terms' => array($_GET['ct']),
                'operator'=> 'AND',
            ),
            array(
                'taxonomy' => 'cruise_country',
                'field' => 'slug',
                'terms' => array($_GET['co']),
                'operator'=> 'AND',
            ),
        );
        $query->set( 'tax_query', $taxquery );
    } 
}
add_filter( 'pre_get_posts', 'belmondo_modify_cruise_archive_query' );

在此之前,我有另一个代码,它工作得很好,但没有默认值。默认情况下,该页面显示所有帖子,使用此代码,'Show All' 显示 0 个结果,但恢复工作完美。

function belmondo_modify_cruise_archive_query( $query ) {
if( is_archive() && is_post_type_archive('cruise') && $query->is_main_query() && isset($_GET['ct']) && isset($_GET['co'])) {
    $taxquery = array(
        'relation' => 'AND',
        array(
            'taxonomy' => 'cruise_type',
            'field' => 'slug',
            'terms' => array($_GET['ct']),
            'operator'=> 'AND',
        ),
        array(
            'taxonomy' => 'cruise_country',
            'field' => 'slug',
            'terms' => array($_GET['co']),
            'operator'=> 'IN',
        ),
    );
    $query->set( 'tax_query', $taxquery );
} elseif( is_archive() && is_post_type_archive('cruise') && $query->is_main_query() ) {
    $taxquery = array(
        'relation' => 'OR',
        array(
            'taxonomy' => 'cruise_type',
            'field' => 'slug',
            'terms' => array($_GET['ct']),
            'operator'=> 'IN',
        ),
        array(
            'taxonomy' => 'cruise_country',
            'field' => 'slug',
            'terms' => array($_GET['co']),
            'operator'=> 'IN',
        ),
        );
        $query->set( 'tax_query', $taxquery );
    }
}
add_filter( 'pre_get_posts', 'belmondo_modify_cruise_archive_query' );

我对此进行了很多研究,并尝试了很多不同的方法,比如使用 OR 和 AND 代替 IN,诸如此类。 我认为我真的很接近解决它,但有些东西我没有看到。我距离成为 PHP 方面的专家还有很长的路要走,所以我会尽力回答您的所有问题。

谢谢!

在 top 函数的 if 语句中,只有 运行 如果同时设置了 $_GET['ct']$_GET['co'],因为您正在检查两者是否符合逻辑使用 && 运算符设置。您应该使用逻辑 OR 运算符将其拆分:||。然而,这会让您将空值传递给 tax_query。因此,无需重组您拥有的一切,您只需执行以下操作:

1) 将 if 语句逻辑组合在一起,确保当前请求是 Cruise Archive 的主查询,并且至少 ct co 已设置。

2) 开始一个空数组并添加 ctco 如果它们被设置。

3) 如果 coct 均已设置,则将 tax_query 的关系运算符设置为 AND

4) 您似乎将关系运算符放在了错误的位置,应该将其设置为处理每个查询如何在数组外 关联。

5) 与其不断处理 $_GET 变量,不如将它们命名为单独的变量,这样就无需继续检查它们是否设置为 isset()他们 return 真实值。

它最终看起来像这样:

function belmondo_modify_cruise_archive_query( $query ) {
    // Make sure this is a Cruise Archive's Main query - AND - at at least 'ct' or 'co' are passed via GET.
    if( (is_archive() && is_post_type_archive('cruise') && $query->is_main_query()) && (isset($_GET['ct']) || isset($_GET['co'])) ){
        $tax_query = array(); // Tax Query starts empty (it's an array of arrays)

        // Define variables for ease of use
        $cruise_type   = ( isset($_GET['ct']) ) ? $_GET['ct'] : null;
        $cruise_county = ( isset($_GET['co']) ) ? $_GET['co'] : null;

        // If Type is set, add it to the query
        if( $cruise_type ){
            $tax_query[] = array(
                'taxonomy' => 'cruise_type',
                'field'    => 'slug',
                'terms'    => array( $cruise_type ),
            );
        }

        // If Country is set, add it to the query
        if( $cruise_county ){
            $tax_query[] = array(
                'taxonomy' => 'cruise_country',
                'field'    => 'slug',
                'terms'    => array( $cruise_county ),
            );
        }

        // If BOTH are set, set the relation, otherwise it's not needed
        if( $cruise_type && $cruise_county ){
            $tax_query['relation'] = 'AND';
        }

        $query->set( 'tax_query', $tax_query );
    } 
}
add_filter( 'pre_get_posts', 'belmondo_modify_cruise_archive_query' );

编辑:为清楚起见,我在您的 if 语句中添加了一些分组括号,因为它有 4 个必需的 ,最后一个是必需 .