我正在尝试对管理区域中的自定义帖子类型列进行排序。我发现有两种方法可以做到这一点:
起初这是我的方式,但我有一些奇怪的行为。如果未设置元值,过滤器将从列表中删除帖子,而不是对其排序。
add_filter(\'request\', array($this, \'sort_columns\') );
public function sort_columns( $vars ) {
if ( isset( $vars[\'orderby\'] ) && \'startdate\' == $vars[\'orderby\'] ) {
$vars = array_merge( $vars, array(
\'meta_key\' => \'_start_event_datetime\',
\'orderby\' => \'meta_value_num\'
) );
}
}
为了解决这种奇怪的行为,我遇到了另一种方法,但我也有同样的行为。
add_action(\'pre_get_posts\', array($this, \'sort_columns\') );
public function sort_columns( $query ) {
$orderby = $query->get( \'orderby\');
if( \'startdate\' == $orderby ) {
$query->set(\'meta_key\' , \'_start_event_datetime\');
$query->set(\'orderby\' , \'meta_value_num\');
}
}
如何对没有元数据集的帖子进行排序而不是删除?
最合适的回答,由SO网友:kittsville 整理而成
问题是通过设置要排序的职位_start_event_datetime
您创建了一个隐含的假设,即帖子将包含该元。这意味着WordPress生成的SQL查询将仅获取具有该元数据的自定义帖子类型的帖子。
有两种可能的解决方案:
将当前查询替换为稍微复杂一点的元查询修改SQL查询以使用外部连接而不是内部连接,我将向您展示如何执行第一个操作,因为这是最明智的方法。第二个选项适用于更高级的排序,如按多个元键或分类法排序,我建议使用posts_clauses
钩住并观察this blog post.
使用元查询:
$query->set(\'meta_query\',array(
\'relation\' => \'OR\',
array(
\'key\' => \'_start_event_datetime\',
\'compare\' => \'EXISTS\'
),
array(
\'key\' => \'_start_event_datetime\',
\'compare\' => \'NOT EXISTS\',
\'value\' => \'bug #23268\' // Allows WP-Librarian to run on pre-3.9 WP installs
)
));
$query->set(\'orderby\', \'meta_value_num\');
此查询获取所有包含或不包含元键的帖子。请注意
NOT EXISTS
情况完全不正常,只是因为
a bug 在3.9之前的WordPress中。