WordPress:首先按标签关联的X个帖子的税务查询,如果标签相关

时间:2016-03-03 09:12:02

标签: php wordpress taxonomy

问题

如何首先输出标签相关帖子,然后如果标签相关帖子少于4个,则填写剩下的4个点与类别相关的帖子?

方案

有时,帖子的标签很少,或标有标签的标签很少。当按标签输出“相关帖子”时,该区域要么非常稀疏,要么有1个或2个帖子,要么完全为空。

要解决这个问题,如果没有足够的标记相关帖子来满足posts_per_page => X,最好显示相关类别的帖子。

所以,像这样:

场景A - 如果存在超过4个与标签相关的帖子,则:

Related Posts:

Show the below posts:

1. tag-related post #1
2. tag-related post #2
3. tag-related post #3
4. tag-related post #4

Do Not show the below posts:

5. tag-related post #5
6. tag-related post #6
7. tag-related post #7
...

场景B - 如果仅存在2个与标签相关的帖子,则:

Related Posts:

Show the below posts:

1. tag-related post #1
2. tag-related post #2  
3. category-related post #1
4. category-related post #2

Do Not show the below posts:

5. category-related post #3
6. category-related post #4
7. category-related post #5
...

我尝试了什么

我正在使用的税务查询:

// start of the tax_query arguments
$args = array( 'posts_per_page'=>4, 'post__not_in' => array($post->ID), 'tax_query' => array( 'relation' => 'OR' ) );

// get current post tags
$tags = wp_get_object_terms( $post->ID, 'post_tag', array( 'fields' => 'ids' ) );

if ( !empty( $tags ) ) {
    $args['tax_query'][] = array(
        'taxonomy' => 'post_tag',
        'field'    => 'id',
        'terms'    => $tags
    );
}

// get current post categories
$categories = wp_get_object_terms( $post->ID, 'category', array( 'fields' => 'ids' ) );

if ( !empty( $categories ) ) {
    $args['tax_query'][] = array(
        'taxonomy' => 'category',
        'field'    => 'id',
        'terms'    => $categories
    );
}

// the query
$related_query = new WP_Query( $args );

根据我的理解,该税务查询说“获取属于相同类别的帖子,然后获取相同标签中的帖子,然后输出帖子直到屏幕上显示4个。”

然而,它一直在输出类别帖子(其中有许多)满足屏幕上的4个帖子规则并且遗漏了最重要的与标签相关的帖子。我尝试使用AND代替OR来移动代码,这对我来说没有用,对我来说毫无意义。

我也看过这些帖子:WordPress - producing a list of posts filtered by tag and then categoryWordpress query posts by tag and category,但它们是关于输出按标签和类别过滤的帖子列表。我需要首先通过标签关联的帖子,如果是4或更多,那么只输出那些前4名。如果小于4,则输出尽可能多的类别相关帖子以满足4个帖子标准。

显然我误解了查询和/或问题,所以任何帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:1)

我终于完成了所有工作。以下功能将显示最多4个相关帖子,首先按标签,然后是类别,然后是自定义帖子类型,如果前3个条件中没有一个匹配任何帖子,则任何帖子。

function get_max_related_posts( $recent_posts = array(), $taxonomy_1 = 'post_tag', $taxonomy_2 = 'category', $total_posts = 4 ) {
    // First, make sure we are on a single page, if not, bail
    if ( !is_single() )
        return false;

    // Sanitize and vaidate our incoming data
    if ( 'post_tag' !== $taxonomy_1 ) {
        $taxonomy_1 = filter_var( $taxonomy_1, FILTER_SANITIZE_STRING );
        if ( !taxonomy_exists( $taxonomy_1 ) )
            return false;
    }

    if ( 'category' !== $taxonomy_2 ) {
        $taxonomy_2 = filter_var( $taxonomy_2, FILTER_SANITIZE_STRING );
        if ( !taxonomy_exists( $taxonomy_2 ) )
            return false;
    }

    if ( 4 !== $total_posts ) {
        $total_posts = filter_var( $total_posts, FILTER_VALIDATE_INT );
            if ( !$total_posts )
                return false;
    }

    // Everything checks out and is sanitized, lets get the current post
    $current_post = sanitize_post( $GLOBALS['wp_the_query']->get_queried_object() );

    // Lets get the first taxonomy's terms belonging to the post
    $terms_1 = get_the_terms( $current_post, $taxonomy_1 );

    // Set a varaible to hold the post count from first query
    $count = 0;
    // Set a variable to hold the results from query 1
    $q_1   = [];
    // Set a variable to hold the exclusions
    $sticky = get_option( 'sticky_posts' );
    $exclude = array_merge( [$current_post->ID], $sticky );
    $exclude = array_merge( $exclude, $recent_posts );

    // Make sure we have terms
    if ( $terms_1 ) {
        // Lets get the term ID's
        $term_1_ids = wp_list_pluck( $terms_1, 'term_id' );

        // Lets build the query to get related posts
        $args_1 = [
            'post_type'      => $current_post->post_type,
            'post__not_in'   => $exclude,
            'posts_per_page' => $total_posts,
            'fields'         => 'ids',
            'tax_query'      => [
                [
                    'taxonomy'         => $taxonomy_1,
                    'terms'            => $term_1_ids,
                    'include_children' => false
                ]
            ],
        ];
        $q_1 = get_posts( $args_1 );

        // Update our counter
        $count = count( $q_1 );
        // Update our counter
        $exclude = array_merge( $exclude, $q_1 );
    }

    // We will now run the second query if $count is less than $total_posts
    if ( $count < $total_posts ) {
        $terms_2 = get_the_terms( $current_post, $taxonomy_2 );
        // Make sure we have terms
        if ( $terms_2 ) {
            // Lets get the term ID's
            $term_2_ids = wp_list_pluck( $terms_2, 'term_id' );

            // Calculate the amount of post to get
            $diff = $total_posts - $count;

            $args_2 = [
                'post_type'      => $current_post->post_type,
                'post__not_in'   => $exclude,
                'posts_per_page' => $diff,
                'fields'         => 'ids',
                'tax_query'      => [
                    [
                        'taxonomy'         => $taxonomy_2,
                        'terms'            => $term_2_ids,
                        'include_children' => false
                    ]
                ],
            ];
            $q_2 = get_posts( $args_2 );

            if ( $q_2 ) {
                // Merge the two results into one array of ID's
                $q_1 = array_merge( $q_1, $q_2 );

                // Update our post counter
                $count = count( $q_1 );

                // Update our counter
                $exclude = array_merge( $exclude, $q_2 );
            }
        }
    }

    // We will now run the third query if $count is less than $total_posts
    if ( $count < $total_posts ) {
        // Calculate the amount of post to get
        $diff = $total_posts - $count;

        $args_3 = [
            'post_type'      => $current_post->post_type,
            'post__not_in'   => $exclude,
            'posts_per_page' => $diff,
            'fields'         => 'ids',
        ];
        $q_3 = get_posts( $args_3 );

        if ( $q_3 ) {
            // Merge the two results into one array of ID's
            $q_1 = array_merge( $q_1, $q_3 );
        } else {
            $args_4 = [
                'post_type'      => 'any',
                'post__not_in'   => $exclude,
                'posts_per_page' => $diff,
                'fields'         => 'ids',
            ];
            $q_4 = get_posts( $args_4 );

            if ( $q_4 ) {
                // Merge the two results into one array of ID's
                $q_1 = array_merge( $q_1, $q_4 );
            }
        }
    }

    // Make sure we have an array of ID's
    if ( !$q_1 )
        return false;

    // Run our last query, and output the results
    $final_args = [
        'ignore_sticky_posts' => 1,
        'post_type'           => 'any',
        'posts_per_page'      => count( $q_1 ),
        'post__in'            => $q_1,
        'order'               => 'ASC',
        'orderby'             => 'post__in',
        'suppress_filters'    => true,
        'no_found_rows'       => true
    ];
    $final_query = new WP_Query( $final_args );

    return $final_query;
}
相关问题