如何根据帖子id在循环中首先列出一些帖子

时间:2016-01-24 作者:Ron

我有一个查询,用于显示一些帖子。

$args = array(
    \'post_type\' =>\'products\'
    \'posts_per_page\'=> 12,
    \'orderby\'       => \'meta_value_num\',
    \'meta_key\'  => \'_price\',
    \'order\' => \'asc\',
);
$loop=new WP_Query($args); 
while($loop->have_posts()) : $loop->the_post();
    the_content();
endwhile;
在这个循环中,我得到了产品,但我需要在这个循环中首先出现一些产品。12,13,14,34 这些是我的帖子id,我需要首先出现在循环中。

如何首先显示此帖子,然后显示其他帖子。有没有办法做到这一点。$args中是否有任何变量支持这种功能?

3 个回复
最合适的回答,由SO网友:Pieter Goosen 整理而成

如果需要:

查询页面

每页保留12篇文章,而不是将所需的文章“粘贴”在所需的12篇文章之上

只需在首页显示这些帖子

您可以尝试以下方法

$ids_args = [
    \'post_type\'      => \'products\'
    \'posts_per_page\' => -1,
    \'orderby\'        => \'meta_value_num\',
    \'meta_key\'       => \'_price\',
    \'order\'          => \'ASC\',
    \'fields\'         => \'ids\'
];
$all_posts_ids = get_posts( $ids_args );

// Make sure we have posts before continuing
if ( $all_posts_ids ) {
    // Set all our posts that should move to the front 
    $move_to_front   = [12,13,14,34];
    // Add the array of posts to the front of our $all_posts_ids array
    $post_ids_merged = array_merge( $move_to_front, $all_posts_ids );
    // Make sure that we remove the ID\'s from their original positions
    $reordered_ids   = array_unique( $post_ids_merged );

    // Now we can run our normal query to display 12 posts per page
    $args = [
        \'post_type\'      => \'products\'
        \'posts_per_page\' => 12,
        \'post__in\'       => $reordered_ids,
        \'orderby\'        => \'post__in\',
        \'order\'          => \'ASC\',
        \'paged\'          => get_query_var( \'paged\', 1 ),
    ];
    $loop = new WP_Query( $args ); 
    while( $loop->have_posts() ) {
        $loop->the_post();
            the_content();
    }
    wp_reset_postdata();
}
如果你需要这些帖子

贴在每页12篇帖子的顶部

在分页查询中

您可以运行以下两个查询

// Set an array of id\'s to display in front
$move_to_front   = [12,13,14,34];
// Run the query to display the posts you need in front
$args_front = [
    \'post_type\'      => \'products\'
    \'posts_per_page\' => count( $move_to_front ),
    \'post__in\'       => $move_to_front,
    \'orderby\'        => \'meta_value_num\',
    \'meta_key\'       => \'_price\',
    \'order\'          => \'ASC\',
];
$loop_front = new WP_Query( $args_front );
if( $loop_front->have_posts() ) {
    while( $loop_front->have_posts() ) {
        $loop_front->the_post();
            the_content();
    }
    wp_reset_postdata();
}

// Now we can run our major loop to display the other posts
$args = [
    \'post_type\'      => \'products\'
    \'posts_per_page\' => 12,
    \'post__not_in\'   => $move_to_front,
    \'orderby\'        => \'meta_value_num\',
    \'meta_key\'       => \'_price\',
    \'order\'          => \'ASC\',
    \'paged\'          => get_query_var( \'paged\', 1 ),
];
$loop = new WP_Query( $args );
if( $loop->have_posts() ) {
    while( $loop->have_posts() ) {
        $loop->the_post();
            the_content();
    }
    wp_reset_postdata();
}
如果你只需要一页前面有这些帖子,那么@birgire的解决方案就可以很好地完成这项工作

SO网友:birgire

我们可以通过两个查询来实现这一点:

首先,我们通过第一个查询获取所需的帖子ID,然后将其与粘性帖子ID合并,并使用post__in 过滤和排序参数:

$args = [
    \'post_type\'           => \'products\'
    \'posts_per_page\'      => 12,
    \'orderby\'             => \'meta_value_num\',
    \'meta_key\'            => \'_price\',
    \'order\'               => \'asc\',
    \'ignore_sticky_posts\' => true,
    \'fields\'              => \'ids\',
];
$ids = get_posts( $args );
if( ! empty( $ids ) )
{
    $stickies = [12,13,14,34];
    $post__in = array_unique( array_merge(  $stickies, $ids ) );
    $args = [
        \'post__in\'            => $post__in,
        \'orderby\'             => \'post__in\',
        \'ignore_sticky_posts\' => true,
    ];
    $loop = new WP_Query( $args ); 
    // ... etc
}
我们调整$stickies 用于自定义粘滞贴子。

SO网友:Alex Standiford

Birgire的解决方案对我来说并不太奏效。我需要指定post_type‍ 排序后在我的参数中。

这里是我的修改,构建为一个类。

class locations{

  public function __construct(){
    $this->args = [
      \'post_type\'           => \'location\',
      \'posts_per_page\'      => -1,
      \'orderby\'             => \'title\',
      \'order\'               => \'asc\',
      \'fields\'              => \'ids\',
      \'ignore_sticky_posts\' => true,
    ];
    $this->ids = get_posts($this->args);
    $this->get = new WP_Query($this->sort_ids());
  }

  //Sorts the locations by specified criteria
  private function sort_ids(){
    $stickies = [2071,2080,2069,1823];
    $post__in = array_unique(array_merge($stickies, $this->ids));
    $args = [
        \'post_type\'           => \'location\',
        \'post__in\'            => $post__in,
        \'orderby\'             => \'post__in\',
        \'order\'               => \'asc\',
        \'posts_per_page\'      => -1,
        \'ignore_sticky_posts\' => true,
    ];
    return $args;
  }
}