【问题标题】:Function to filter posts by 2 taxonomies按 2 个分类法过滤帖子的功能
【发布时间】:2019-01-30 19:57:43
【问题描述】:

我有一个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' );

在此之前,我有其他代码,它运行良好,但没有默认值。默认情况下,页面显示所有帖子,使用此代码,“显示全部”显示 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 专家还很遥远,所以我会尽力回答您的所有问题。

谢谢!

【问题讨论】:

    标签: php wordpress custom-taxonomy


    【解决方案1】:

    在顶部函数中的 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() 设置,并且如果它们返回真值则可以只发送文本价值。

    它最终会看起来像这样:

    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 个必需的 ,其中最后一个是必需的 或 。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-10
      • 2021-06-23
      • 1970-01-01
      相关资源
      最近更新 更多