Wordpress查询 - 如果少于3个帖子,随机选帖

时间:2013-04-07 18:52:55

标签: wordpress

我有一个查询,它会返回自定义字段“featured”的帖子。代码看起来

<?php
$args = array( 
    'post_type' => 'koncert', 
    'posts_per_page' => 3, 
    'meta_query' => array(
        array(
            'key' => 'featured', // name of custom field
            'value' => '1', 
            'compare' => 'LIKE'
        ),
    ), 
    'meta_key' => 'datum', 
    'orderby' => 'meta_value', 
    'order' => ASC
);

$loop = new WP_Query( $args );
$countposts = $loop->post_count;
$count = 1;
// START OF THE LOOP
while ( $loop->have_posts() ) : $loop->the_post();
    /* do something */
    $count++;
endwhile;
wp_reset_postdata();
?>

问题是我需要查询总是返回至少三个“精选”帖子,但情况并非总是如此。

那么,在查询中检查帖子数量的最简单方法是什么,如果少于3个,则从这个自定义帖子类型中随机选择另一个帖子(并且仍然按{{1}排序查询}?

感谢您的帮助

2 个答案:

答案 0 :(得分:0)

您需要进行初始提取,查看您获得了多少结果,然后“随机”获取一些您缺少总数的帖子,然后根据基准元值对它们进行排序。循环集是不同的,因为它使用get_posts()而不是WP_Query来使其更容易作为数组使用。

请注意,我没有运行下面的代码,这是一个概念验证和未经测试的

// The total posts to display
$total_count = 3;

// The query args
$args = array( 
    'post_type' => 'koncert', 
    'posts_per_page' => $total_count, 
    'meta_query' => array(
        array(
            'key' => 'featured', // name of custom field
            'value' => '1', 
            'compare' => '='
        ),
    ), 
    'meta_key' => 'datum', 
    'orderby' => 'meta_value', 
    'order' => ASC
);

// Get the posts that are "featured"
$featured = get_posts( $args );

// Figure out if we need to fetch "random" posts to get to the $total_count
$rnd_count = $total_count - count( $featured );

if ( $rnd_count > 0 ) {
    // Make sure we don't get the same posts
    $post__not_in = array();
    for ( $featured as $f ){
        $post__not_in[] = $f->ID;
    }

    // Set up the args for a random post
    $args = array( 
        'post_type' => 'koncert', 
        'posts_per_page' => $rnd_count, 
        'post__not_in' => $post__not_in, 
        'orderby' => 'rand', // http://codex.wordpress.org/Template_Tags/get_posts#Random_posts
    );

    // Get the "random" posts now that we remove the meta filter and excluding the ones we already fetched
    $random = get_posts( $args );

    // Merge into a single array
    $featured = array_merge( $featured, $random );

    // Get the datum meta for each post so we can sort on it
    $sort = array();
    $post_by_id = array();
    for ( $featured as $f ){
        $sort[ $f->ID ] = get_post_meta( $f->ID, 'datum', true );
        $post_by_id[ $f->ID ] = $f;
    }
    // Sort and maintain key since it's the post
    asort( $sort, SORT_STRING ); // use SORT_NUMERIC for numbers, see http://www.php.net/manual/en/function.sort.php

    $i = 0;
    for ( $sort as $key => $s ){
        $featured[$i++] = $post_by_id[ $key ];
    }
}

// since we used get_posts() and not WP_Query, use the following to create the loop.
for ( $featured as $f ){
    global $post;
    $post = $f;
    setup_postdata( $post );
    // use the_content() etc
}

答案 1 :(得分:0)

第二个选项是使用SQL查询来获取此信息,而不是内置的WordPress函数。获取已发布的'koncert'类型的所有帖子,然后将post元表连接两次,并根据不同获取的元值进行排序,使用LIMIT仅返回3个结果。

global $wpdb;
$sql = <<<SQL
    SELECT p.ID, p.post_content, p.post_title, datum.meta_value as datum, featured.meta_value as featured
    FROM {$wpdb->posts} p
    LEFT JOIN {$wpdb->postmeta} featured 
        ON featured.post_id = p.ID 
        AND featured.meta_key = 'featured'
    LEFT JOIN {$wpdb->postmeta} datum 
        ON datum.post_id = p.ID 
        AND datum.meta_key = 'datum'
    WHERE 
        p.post_type = 'koncert' 
        AND p.post_status = 'publish'
    ORDER BY featured DESC, datum DESC, RAND()
    LIMIT 3
SQL;
$posts = $wpdb->get_results( $sql );