像@TomJNowell 和@s_ha_dum 您在评论中说,在您的情况下,自定义分类法可能比自定义字段更好,因为很容易获得没有分类法术语的帖子。
也就是说,我理解,如果您已经编写了很多代码,或者正在使用第三方代码,那么转向自定义分类法可能很难/不可能。
Aswer由提供@elleeott 然而,works并不灵活,因为您不能更改每页的帖子、元值等。。
我将为您提供类似的解决方案,但要灵活一点,您可以根据需要对其进行微调。
本质上只是一个扩展WP_Query
并对请求应用筛选器以执行所需的
class MyMetaQuery extends WP_Query {
protected $do_posts_request_filter = TRUE;
function get_posts() {
$this->query_vars[\'suppress_filters\'] = FALSE; // force do filters
add_action( \'posts_request\', array( $this, \'filter_request\' ), 999 );
parent::get_posts();
$this->do_posts_request_filter = FALSE; // run only once
}
/* build the sql request */
function filter_request( $request ) {
if ( ! $this->do_posts_request_filter ) return $request;
$q = $this->get(\'meta_query\');
if ( empty($q) || ! is_array($q) || ! isset($q[0][\'key\']) ) return $request;
global $wpdb;
$k = $q[0][\'key\'];
$v = isset( $q[0][\'value\'] ) ? $q[0][\'value\'] : \'\';
if ( is_array( $v ) ) $v = implode( \',\', $v );
$mcompare = isset( $q[0][\'compare\'] ) ? $q[0][\'compare\'] : \'IN\';
if ( ! in_array( $mcompare, array(\'IN\', \'NOT IN\', \'=\', \'!=\') ) ) {
$mcompare = \'IN\';
}
if ( $mcompare === \'!=\' ) $mcompare = \'NOT IN\';
if ( $mcompare === \'=\' ) $mcompare = \'IN\';
$ppage = $this->get(\'posts_per_page\') ? : get_option(\'posts_per_page\');
$limit = $wpdb->prepare(\' LIMIT %d\', $ppage);
if ( substr_count( $limit, \'-1\' ) ) $limit = \'\';
if ( $limit && $this->get(\'nopaging\') ) $limit = \'\';
$type_compare = \'IN\';
$type = $this->get(\'post_type\') ? : \'post\';
if ( is_array( $type ) ) $type = implode(\',\', $type );
if ( $type === \'any\' ) {
$type_compare = \'NOT IN\';
$status = \'-1\';
}
$status_compare = \'IN\';
$status = $this->get(\'post_status\') ? : \'publish\';
if ( is_array($status) ) $type = implode(\',\', $status);
if ( $status === \'any\' ) {
$status_compare = \'NOT IN\';
$status = \'-1\';
}
$query = "
SELECT SQL_CALC_FOUND_ROWS $wpdb->posts.* FROM $wpdb->posts
INNER JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id
WHERE post_type $type_compare (%s)
AND post_status $status_compare (%s)
AND $wpdb->postmeta.meta_key = %s
AND ID NOT IN (
SELECT DISTINCT post_id FROM $wpdb->postmeta
WHERE meta_key = %s and CAST(meta_value AS CHAR) $mcompare (%s)
)
";
return $wpdb->prepare( $query, $type, $status, $k, $k, $v ) . $limit;
}
}
之后,不用
WP_Query
你必须使用
MyMetaQuery
类别:
$args = array(
\'posts_per_page\' => -1,
\'post_type\' => \'page\',
\'meta_query\' => array(
array( \'key\' => \'my_custom_field\', \'value\' => 2, \'compare\' => \'!=\' )
)
);
$query = new MyMetaQuery( $args );
if ( $query->have_posts() ) {
while( $query->have_posts() ) {
$query->the_post();
// do what you want here
}
wp_reset_postdata();
}
请注意,自定义类只接受以下参数:
\'post_type\'
, 可以是单个类型、逗号分隔的字符串或类型数组或“任意”\'post_status\'
可以是单个状态、逗号分隔的字符串或状态数组或“任意”\'posts_per_page\'
可以是一个posistive数字或“-1”\'nopaging\'
可以是TRUE
或FALSE
. 设置为TRUE将返回覆盖“每页帖子”的所有帖子\'meta_query\'
接受多维数组,就像WP_Query
. 请注意,您只能传递一个查询数组,任何其他查询都将被忽略。查询数组接受以下作为数组键:\'key\'
, \'value\'
和\'compare\'
. \'value\'
可以是单个值、逗号分隔的字符串或值数组。\'compare\'
可以是“”IN“”、“”NOT IN“”、“”、“”和“”!=”如果需要其他参数(类别、标记、分类法、日期等),则必须扩展类功能,或者更可能使用其他方法。