英文:
ACF - WP_Query - Order Results by value, then by a different one
问题
我有以下内容:
$args = array(
'post_type' => 'events',
'posts_per_page'=> 6,
'post_status'=> 'publish',
'meta_query' => array(
'relation' => 'OR',
'event_passport' => array(
'key' => 'event_product',
'value' => 'featured',
'compare' => '=',
),
'event_dates' => array(
'key' => 'event_dates',
'type' => 'DATETIME',
)
),
'orderby' => array(
'event_passport' => 'DESC',
'event_dates' => 'DESC',
),
);
例如,假设我有3个event_product
为featured
的事件。
我想要的是首先显示这3个特色事件,然后显示其余的事件。
目前这个功能不起作用,我不确定需要做什么来实现这一点。
非常感谢任何帮助,谢谢!
英文:
I have the following:
$args = array(
'post_type' => 'events',
'posts_per_page'=> 6,
'post_status'=> 'publish',
'meta_query' => array(
'relation' => 'OR',
'event_passport' => array(
'key' => 'event_product',
'value' => 'featured',
'compare' => '=',
),
'event_dates' => array(
'key' => 'event_dates',
'type' => 'DATETIME',
)
),
'orderby' => array(
'event_passport' => 'DESC',
'event_dates' => 'DESC',
),
);
Say for example I have 3 events where the event_product
is featured
.
What I want to do is display these 3 featured events first, then show the rest of the events.
At the moment this is not working and I'm not sure what I need to do to achieve this.
Any help is much appreciated, thank you!
答案1
得分: 2
你需要分别获取两个帖子列表,然后合并它们成为一个数组,并在前端使用循环来显示帖子。
// 特色帖子查询
$args_featured = array(
'post_type' => 'events',
'posts_per_page' => 6,
'meta_query' => array(
array(
'key' => 'event_product',
'compare' => '=',
'value' => 'featured'
)
)
);
$featured_query = new WP_Query($args_featured);
$featured_count = $featured_query->post_count;
if ($featured_count < $posts_to_show) {
// 非特色帖子查询
$args_notfeatured = array(
'post_type' => 'my_cpt',
'posts_per_page' => $posts_to_show - $featured_count,
'meta_query' => array(
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'event_product',
'value' => 'featured',
'compare' => '='
),
array(
'key' => 'event_product',
'compare' => 'NOT EXISTS'
)
)
)
);
$notfeatured_query = new WP_Query($args_notfeatured);
$full_query = new WP_Query();
$full_query->posts = array_merge($featured_query->posts, $notfeatured_query->posts);
$full_query->post_count = count($full_query->posts);
} else {
$full_query = $featured_query;
}
if ($full_query->have_posts()) {
while ($full_query->have_posts()) {
$full_query->the_post();
// 输出你的帖子 HTML
}
}
wp_reset_postdata();
英文:
You have to get both posts list separately and merge them into one array and use that loop for display post in frontend.
// Featured posts query
$args_featured = array(
'post_type' => 'events',
'posts_per_page' => 6,
'meta_query' => array(
array(
'key' => 'event_product',
'compare' => '=',
'value' => 'featured'
)
)
);
$featured_query = new WP_Query($args_featured);
$featured_count = $featured_query->post_count;
if ($featured_count < $posts_to_show) {
// non-featured posts query
$args_notfeatured = array(
'post_type' => 'my_cpt',
'posts_per_page' => $posts_to_show - $featured_count,
'meta_query' => array(
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'event_product',
'value' => 'featured',
'compare' => '='
),
array(
'key' => 'event_product',
'compare' => 'NOT EXISTS'
)
)
)
);
$notfeatured_query = new WP_Query($args_notfeatured);
$full_query = new WP_Query();
$full_query->posts = array_merge( $featured_query->posts, $notfeatured_query->posts );
$full_query->post_count = count( $full_query->posts );
} else {
$full_query = $featured_query;
}
if ( $full_query->have_posts() ) {
while ( $full_query->have_posts() ) {
$full_query->the_post();
// Output your post HTML
}
}
wp_reset_postdata();
答案2
得分: 1
尝试直接使用 posts_clauses 过滤器修改查询。
下面的代码未经测试,但思路是根据其元数据键值连接各个单独的表,然后根据该元数据键值的值修改排序子句。
add_filter('posts_clauses', function ($clauses, \WP_Query $q) {
// 如果帖子类型不是事件、是管理员、不是主查询或不是存档页面,则退出
if ($q->get('post_type') != 'events' || is_admin() || !$q->is_main_query() || !is_archive())
return $clauses;
// 左连接事件产品(ep)和事件日期(ed)的元数据表
$clauses['join'] = "
LEFT JOIN wp_postmeta as ep ON (wp_posts.ID = ep.post_id)
AND ep.meta_key = 'event_product'
LEFT JOIN wp_postmeta as ed ON (wp_posts.ID = ed.post_id)
AND ed.meta_key = 'event_dates'
// 如果事件产品值不为空,则首先对它们排序,以便排序为非空 = 0,空 = 1
// 然后按事件日期降序排序
$clauses['orderby'] = 'CASE WHEN ep.meta_value IS NULL THEN 1 ELSE 0 END, CAST(ed.meta_value AS DATE) DESC";
return $clauses;
}, 1, 2 );
英文:
try modifying the query directly using posts_clauses filter.
The code below is untested, but the idea is to join individual table based on its meta key, then modify the order clause based on the value of that meta key.
add_filter( 'posts_clauses', function ($clauses, \WP_Query $q) {
// exit if post type is not event
if ( $q->get('post_type') != 'events' || is_admin() || !$q->is_main_query() || !is_archive() )
return $clauses;
// left join the meta table for event_product (ep) and event_dates (ed)
$clauses['join'] = "
LEFT JOIN wp_postmeta as ep ON (wp_posts.ID = ep.post_id)
AND ep.meta_key = 'event_product'
LEFT JOIN wp_postmeta as ed ON (wp_posts.ID = ed.post_id)
AND ed.meta_key = 'event_dates'
//order them first if the event_product value is NOT NULL, so the order is NOT NULL = 0 and NULL = 1
//followed by event_dates descending order
$clauses['orderby'] = 'CASE WHEN ep.meta_value IS NULL THEN 1 ELSE 0 END, CAST(ed.meta_value AS DATE) DESC";
return $clauses;
}, 1, 2 );
答案3
得分: -1
你正在尝试按照 'event_passport' 进行排序,但它是一个元数据查询(meta query),而不是一个元数据键(meta key)。你想要按照 'event_product' 进行排序。
其次,在 'event_product' 数组中,'compare' 参数应该是 'EXISTS' 或 'NOT EXISTS',如果你想要检查键是否存在或不存在。如果你想要检查键是否等于特定值,你应该使用 'compare' => '=',但你需要确保 'value' 设置为你想要比较的正确值。
$args = array(
'post_type' => 'events',
'posts_per_page' => 6,
'post_status' => 'publish',
'meta_query' => array(
'relation' => 'OR',
'event_product' => array(
'key' => 'event_product',
'value' => 'featured',
'compare' => '=',
),
'event_dates' => array(
'key' => 'event_dates',
'type' => 'DATETIME',
)
),
'orderby' => array(
'event_product' => 'DESC',
'event_dates' => 'DESC',
),
);
英文:
you're trying to order by 'event_passport' which is a meta query, not a meta key. 'event_product' is the actual meta key you want to order by.
Secondly, the 'compare' parameter in the 'event_product' array should be 'EXISTS' or 'NOT EXISTS' if you want to check if the key is present or not. If you want to check if the key equals a certain value, you should use 'compare' => '=', but you need to make sure 'value' is set to the correct value you want to compare with.
$args = array(
'post_type' => 'events',
'posts_per_page'=> 6,
'post_status'=> 'publish',
'meta_query' => array(
'relation' => 'OR',
'event_product' => array(
'key' => 'event_product',
'value' => 'featured',
'compare' => '=',
),
'event_dates' => array(
'key' => 'event_dates',
'type' => 'DATETIME',
)
),
'orderby' => array(
'event_product' => 'DESC',
'event_dates' => 'DESC',
),
);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论