You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用WP_Query按CMB2日期字段排序Workshop自定义文章失败求助

Fixing Workshop CPT Sorting by Event Date (d-m-Y Format)

我明白你遇到的问题——其他自定义字段排序都正常,唯独日期字段不行,这大概率是因为你存储的日期格式是d-m-Y(日-月-年),这种字符串格式在MySQL里按常规字符串排序会逻辑混乱(比如10-01-2024会被认为比09-12-2024大,因为字符串比较是从左到右,第一个字符1>0)。下面给你两种可行的解决方案:

方案1:修改CMB2字段的存储格式(推荐)

CMB2的text_date字段默认会存储为Y-m-d(MySQL友好的日期格式),但你设置了date_format为d-m-Y,这会同时影响显示和存储。我们可以让字段存储为Y-m-d,但前端显示保持d-m-Y,这样排序逻辑就正常了:

修改你的CMB2字段代码:

$cmb_data->add_field( array(
    'name'         => __( 'Event Date', 'workshops' ),
    'desc'         => __( 'Event Date', 'workshops' ),
    'id'           => $prefix . 'event_date',
    'type'         => 'text_date',
    'date_format'  => 'd-m-Y', // 前端显示的格式
    'save_format'  => 'Y-m-d', // 数据库存储的格式,这行是关键!
) );

然后调整WP_Query的参数,用专门针对日期类型的排序规则:

$args = array(
    'post_type'      => 'workshops',
    'posts_per_page' => 10,
    'meta_key'       => 'workshop_data_event_date',
    'orderby'        => 'meta_value_date', // 替换原来的meta_value
    'order'          => 'DESC'
);

这样修改后,数据库里存的是标准年-月-日格式,MySQL能正确识别为日期排序,前端显示依然是你需要的日-月-年格式。

方案2:不修改存储格式,用自定义SQL排序

如果因为历史数据原因不能修改存储格式,可以通过posts_orderby过滤器强制转换日期格式后排序:

在主题functions.php中添加这段代码:

add_filter( 'posts_orderby', 'custom_workshop_date_orderby', 10, 2 );
function custom_workshop_date_orderby( $orderby, $query ) {
    // 只针对Workshops自定义类型的查询生效
    if ( isset( $query->query_vars['post_type'] ) && $query->query_vars['post_type'] === 'workshops' 
         && isset( $query->query_vars['meta_key'] ) && $query->query_vars['meta_key'] === 'workshop_data_event_date' ) {
        // 把d-m-Y格式的字符串转换为MySQL可识别的日期
        $orderby = "STR_TO_DATE(meta_value, '%d-%m-%Y') " . $query->get('order');
    }
    return $orderby;
}

你的WP_Query参数可以保持原样,确保meta_key正确即可:

$args = array(
    'post_type'      => 'workshops',
    'posts_per_page' => 10,
    'meta_key'       => 'workshop_data_event_date',
    'orderby'        => 'meta_value',
    'order'          => 'DESC'
);

这个方法通过STR_TO_DATE函数把存储的字符串转换成MySQL日期类型,再进行排序,就能得到正确的日期顺序了。

额外小优化

你的模板循环写法有点冗余(先用了$articles->the_post();又循环$articles->posts),推荐改成WordPress标准循环写法,避免潜在问题:

if ( $articles->have_posts() ) :
    echo '<div class="cptul-stripe-2 article-post__stats">';
    while ( $articles->have_posts() ) : $articles->the_post();
        echo '<div class="cptli-stripe-2__wrap">
            <div class="cptli-stripe-2--header">
                <div><span class="name">' . get_post_meta( get_the_ID(), 'workshop_data_leader', true ) . '</span>
                <span class="nameWhat"> povede workshop</span>
                </div>
                <a class="stripe-title-mid" href="' . get_permalink() . '">' . get_the_title() . '</a>
                <ul>
                    <li id="event-date" class="article-post__event-date"><span class="article-post__stats-icon">' . webovkar_get_svg( array( 'icon' => 'calendar' ) ) . '</span>' . get_post_meta( get_the_ID(), 'workshop_data_event_date', true ) . '</li>
                    <li class="article-post__event-town"><span class="article-post__stats-icon"> ' . webovkar_get_svg( array( 'icon' => 'mmarker' ) ) . '</span>' . get_post_meta( get_the_ID(), 'workshop_data_town', true ) . ' | ' . get_post_meta( get_the_ID(), 'workshop_data_country', true ) . '</li>
                </ul>
            </div>
            <div class="cptli-stripe-2--data">' . apply_filters( 'the_content', get_post_meta( get_the_ID(), 'workshop_data_excerpt', true ) ) . '</div>
        </div>';
    endwhile;
    echo '</div>';
endif;

内容的提问来源于stack exchange,提问作者Stan Skrivanek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:51:06