首先按元键对列表进行排序的查询(如果存在),并按标题显示没有元键的剩余帖子

时间:2013-12-17 作者:CSSgirl

我正在开发一个自定义分类术语页面模板,我们希望连接到术语的项目按发布日期(自定义日期字段)排序,如果同一天有多个项目(格式为YYYY-MM-DD),则按标题排序,如果自定义字段未填写,则按标题排序(旧项目)。

因此,我用WP\\u查询尝试了100种不同的方法,它确实会按我的需要返回大多数结果,但在本例中,它只返回具有publication\\u date的meta\\u键的项目。所有其他项目将被忽略且不显示。我尝试了一个使用“or”关系的meta\\u查询,并将publication\\u日期比较为EXISTS和NOT EXISTS,但这为我返回了0个结果。

此外,该网站仍在运行3.5.2,他们不想升级。

以下是我最近的一次查询,它可以获取按正确顺序显示publication\\u date自定义字段的帖子:

$term = get_queried_object(); // find the term of the taxonomy page we are on
$wp_query = new WP_Query( array(
\'post_type\' => \'resource\',
\'tax_query\' => array(
    array(
        \'taxonomy\' => \'resource_types\',
        \'field\' => \'slug\',
        \'terms\' => $term->name,
    )), 

\'meta_key\' => \'publication_date\',
\'orderby\' => \'meta_value_num\',
\'order\' => \'DESC\',
\'paged\' => $paged,
\'posts_per_page\' => \'10\',
));
我还尝试使用wpdb并运行SQL查询,但我真的不知道如何实现我想要的。如果有人能帮我,那就太棒了!

提前谢谢。

5 个回复
最合适的回答,由SO网友:CSSgirl 整理而成

谢谢大家的帮助!

最后,下面的查询得到了我想要的结果,即首先按“publication\\u date”自定义字段显示和排序帖子,然后按日期排序,如果有多个相同的日期(例如,2013年6月4日),它会按标题排序。然后,在它遍历了所有填写了发布日期的帖子之后,它将按照标题的字母顺序再次遍历其余的帖子。

这将获取同一查询中的结果集,并保持分页:

$term = get_queried_object();
the_post();
$wp_query = new WP_Query( array(
\'post_type\' => \'resource\',
    \'tax_query\' => array(
        array(
            \'taxonomy\' => \'resource_types\',
            \'field\' => \'slug\',
            \'terms\' => $term->name,
        )),
 \'meta_query\' => array(
       \'relation\' => \'OR\',
        array( //check to see if date has been filled out
                \'key\' => \'publication_date\',
                \'compare\' => \'=\',
                \'value\' => date(\'Y-m-d\')
            ),
          array( //if no date has been added show these posts too
                \'key\' => \'publication_date\',
                \'value\' => date(\'Y-m-d\'),
                \'compare\' => \'NOT EXISTS\'
            )
        ),
\'meta_key\' => \'publication_date\',
\'orderby\' => \'meta_value title\',
\'order\' => \'ASC\',
\'paged\' => $paged,
\'posts_per_page\' => \'10\',
));

SO网友:Ciprian Tepes

几年后,CSSGirl发布的代码对我不起作用,因为有些帖子没有meta键,或者meta键为空,所以我必须这样做,才能按日期排序所有帖子,并首先显示带有meta键值的帖子:

$args          = array(
\'post_type\'   => $type,
\'post_status\' => \'publish\',
\'nopaging\'    => TRUE,
\'meta_query\'  => array(
    \'relation\' => \'OR\',
    array(
        \'key\'     => $meta_key,
        \'compare\' => \'NOT EXISTS\',
    ),
    array(
        \'relation\' => \'OR\',
        array(
            \'key\'   => $meta_key,
            \'value\' => \'on\',
        ),
        array(
            \'key\'     => $meta_key,
            \'value\'   => \'on\',
            \'compare\' => \'!=\',
        ),
    ),
),
\'orderby\'     => array( \'meta_value\' => \'DESC\', \'date\' => \'DESC\' ),
);

SO网友:GhostToast

我想你需要做两个独立的循环。您可以捕获在第一个循环中找到的所有帖子,并将其从第二个循环中排除:

$found_posts = array();
while($loop->have_posts()): $loop->the_post();
    // loop stuff
    $found_posts[] = get_the_id();
endwhile;

wp_reset_query();

$args = array(
    // other args
    \'post__not_in\' => $found_posts,
);
然后运行第二个循环。

SO网友:sanchothefat

是否有任何原因导致您无法强制每个帖子都存在publication\\u date meta键,而只存在一个空值?

所以在你的save_post 您将添加/更新元键的操作$_POST 值是否为空。

您必须运行一个更新脚本来循环您以前的帖子,并添加一个空值的键,例如:

add_action( \'admin_init\', \'update_old_posts\' );
function update_old_posts() {
    if ( ! isset( $_GET[ \'update_old_posts\' ] ) )
         return;

    foreach( get_posts() as $post ) {
        if ( false === get_post_meta( $post->ID, \'publication_date\', true ) ) {
             update_post_meta( $post->ID, \'publication_date\', \'\' );
             echo "Updated {$post->post_title} <br />";
        }
    }

    die;
}
通过浏览来运行它http://example.com/wp-admin/?update_old_posts

然后,您可以使用与之前相同的查询。您可能想添加一个额外的过滤器,使您能够按不同方向的不同列进行排序,我认为按日期降序排序和按标题升序排序是有意义的。

add_filter( \'posts_orderby\', \'multicolumn_orderby\', 10, 2 );
function multicolumn_orderby( $orderby, $query ) {
    global $wpdb;

    // check it\'s the right query
    if ( $query->get( \'meta_key\' ) == \'publication_date\' ) {
         $orderby = "$wpdb->postmeta.meta_value+0 DESC, $wpdb->posts.post_title ASC";
    }

    return $orderby;
}

SO网友:Ryan Taylor

我创建了一个自定义where子句。我用$wp_query->request 就在我的主循环之前,我对SQL真的不太了解,但这似乎可以让事情正常运行。

add_action(\'pre_get_posts\', \'add_trending_sort\', 11, 1);
function add_trending_sort($query){
  if(!$query->is_main_query())
    return;

  //Overwrite query arguments
  $query->set(\'meta_query\', array(
    array(
      \'key\' => \'TRENDING\',
      //\'value\' => \'asdfasdf\',//may need a value for older versions of WordPress
      \'compare\' => \'NOT EXISTS\',
    )
  ));
  $query->set(\'orderby\', \'meta_value_num date\');
  $query->set(\'order\', \'DESC\');
}

add_filter(\'posts_where\', \'add_trending_where\');
function add_trending_where($where = \'\'){
  global $wpdb, $wp_query;
  if(!$wp_query->is_main_query())//Not sure if this really works.  Should be OK
    return $where;

  $where .= " OR ( $wpdb->postmeta.meta_key = \'TRENDING\' )";

  // Don\'t run this twice
  remove_filter(\'posts_where\', \'add_trending_where\');

  return $where;
}
或者,您可以设置compare\'EXISTS\' 并更改add\\u trending\\u where to中的行$where .= " OR ($wpdb->postmeta.post_id IS NULL)";. 然后只需在一个位置更改键的值。再一次,echo$wp_query->request 如果你想更好地理解这一点或对其进行调整,可以尝试一下。

编辑:我刚刚注意到,如果meta_key 在查询上设置。你可以使用$query->set(\'meta_key\', NULL); 如果必须的话。

编辑2:我用上面的方法得到了这个。出于某种原因,一开始并不是这样(可能设置了meta\\u键……我不知道)。

add_action(\'pre_get_posts\', \'add_trending_sort\', 11, 1);
function add_trending_sort($query){
  // Bail if not the main "hidden" query, as opposed to a \'new WP_Query()\' call
  if(!$query->is_main_query())
    return;

  // Set meta_query to get shares for orderby, and also get non-shared content.
  $query->set(\'meta_query\', array(
    \'relation\' => \'OR\',
    array(
      \'key\' => \'TRENDING\',
      \'compare\' => \'NOT EXISTS\',
    ),
    array(
      \'key\' => \'TRENDING\',
      \'compare\' => \'EXISTS\',
    )
  ));
  //$query->set(\'meta_key\', NULL);
  $query->set(\'orderby\', array(\'meta_value_num\' => \'DESC\', \'date\' => \'DESC\'));
}

结束

相关推荐

我可以使用wpdb将查询结果插入帖子吗?

我的网站目前包含从数据库查询中提取的内容,用php显示。具体来说,有4个模块,每个模块查询不同的数据库,以获取与当前日期匹配的所有记录,并按顺序显示它们。有没有一种方法可以使用wpdb进行类似的查询,并将它们拉到单独的帖子中?我正在寻找的结果与我当前的配置类似:一个只有4篇帖子的WordPress网站,但帖子中的内容会根据日期而变化。