WordPress自定义文章网格:有值时按自定义字段,否则按创建日期排序
问题描述
我为文章创建了名为updated_date的自定义字段,希望自定义文章网格默认按文章创建日期排序,但当该自定义字段有值时,就使用该字段的值进行排序。
目前我已定义如下变量(用于前端显示日期,逻辑正常):
$fields['customDate'] = get_field('updated_date', $post->ID); if (!empty($fields['customDate'])) { $fields['orderDate'] = $fields['customDate']; } else { $fields['orderDate'] = get_the_date('Ymd', $post); }
页面显示日期的代码:
<?php echo date('F j, Y', strtotime($fields['orderDate']));?>
但我的查询代码无法实现预期排序(因为部分文章没有该自定义字段值):
$posts = get_posts(array( 'post_type' => 'post', 'numberposts' => $numberposts, 'tax_query' => $taxQueries, 'post__not_in' => $exclusions, 'orderby' => array( 'orderDate' => 'DESC' ) ));
请问是否有办法结合两个字段(创建日期和自定义字段)实现排序:当自定义字段有值时用它排序,否则用文章创建日期?
解决方案
直接使用orderDate无法生效,因为它不是数据库中存在的字段,需要基于数据库原生的updated_date(自定义字段)和post_date(文章创建日期)来构建排序逻辑,以下两种方法均可实现需求:
方法一:使用WP_Query原生参数配置
通过meta_query确保所有文章(无论是否有自定义字段)都被纳入查询,再通过orderby数组设置优先级排序:
$args = array( 'post_type' => 'post', 'posts_per_page' => $numberposts, 'tax_query' => $taxQueries, 'post__not_in' => $exclusions, // 同时包含有/无updated_date字段的文章 'meta_query' => array( 'relation' => 'OR', array( 'key' => 'updated_date', 'compare' => 'EXISTS' ), array( 'key' => 'updated_date', 'compare' => 'NOT EXISTS' ) ), // 排序优先级:先按updated_date降序,无值则用post_date降序 'orderby' => array( 'meta_value' => 'DESC', 'post_date' => 'DESC' ), // 若你的updated_date是Ymd格式的日期字符串,指定meta_type为DATE更准确 'meta_type' => 'DATE' ); // 执行查询 $query = new WP_Query($args); $posts = $query->posts;
注意:如果
updated_date字段存储的是时间戳,可将meta_value改为meta_value_num,meta_type改为NUMERIC。
方法二:使用posts_orderby过滤器自定义SQL排序
通过过滤器直接修改查询的排序SQL语句,灵活性更高:
// 先添加过滤器 add_filter('posts_orderby', 'custom_post_date_sort', 10, 2); function custom_post_date_sort($orderby, $query) { // 仅针对目标查询生效(避免影响全局),可添加自定义标识判断 if (!is_admin() && $query->get('post_type') === 'post' && $query->get('custom_sort_flag')) { global $wpdb; // COALESCE函数会优先取第一个非空值,即有updated_date用它,否则用post_date $orderby = "COALESCE($wpdb->postmeta.meta_value, $wpdb->posts.post_date) DESC"; } return $orderby; } // 构建查询参数,添加自定义标识 $args = array( 'post_type' => 'post', 'posts_per_page' => $numberposts, 'tax_query' => $taxQueries, 'post__not_in' => $exclusions, 'custom_sort_flag' => true, // 自定义标识,用于过滤器判断 'meta_query' => array( 'relation' => 'OR', array('key' => 'updated_date', 'compare' => 'EXISTS'), array('key' => 'updated_date', 'compare' => 'NOT EXISTS') ) ); $posts = get_posts($args); // 用完过滤器后移除,避免影响后续查询 remove_filter('posts_orderby', 'custom_post_date_sort', 10);
内容的提问来源于stack exchange,提问作者frankbraga
相关产品推荐
相关产品推荐

