如何使用wp_get_archives仅展示含特定meta key的文章归档月份?
按ACF自定义字段筛选文章月份归档的实现方案
wp_get_archives() 原生不支持meta查询参数,无法直接传入meta_key/meta_value实现筛选,以下两种方案都可以匹配你的业务需求,和已有的wp_get_recent_posts筛选逻辑完全对齐。
方案一:通过过滤器注入筛选条件(改动最小)
用WordPress原生的getarchives_where过滤器,直接修改归档查询的SQL语句,注入meta筛选规则,你原有wp_get_archives的输出结构、参数配置基本不用调整。
注意过滤器要在调用归档函数前挂载,调用完成后立刻移除,避免影响站点其他位置的归档查询。
客户博客侧边栏的实现代码如下:
// 定义客户博客的归档筛选逻辑 $customer_archive_filter = function( $where ) { global $wpdb; // 关联postmeta表,仅统计blog_type为Customer Blog的已发布文章 $where .= $wpdb->prepare( " AND EXISTS ( SELECT 1 FROM {$wpdb->postmeta} pm WHERE pm.post_id = {$wpdb->posts}.ID AND pm.meta_key = 'blog_type' AND pm.meta_value = %s )", 'Customer Blog' ); return $where; }; // 挂载筛选过滤器 add_filter( 'getarchives_where', $customer_archive_filter, 10 ); // 原有wp_get_archives调用,补充%link%占位符实现跳转 wp_get_archives(array( 'format' => 'custom', 'before' => ' <div class="post-list"><div class="text-1-1 fontawesome5free-solid-normal-grenadier-20px"></div> <div class="january-2021 small-paragraph"><a href="%link%">', 'after' => '</a></div></div>', 'limit' => 4, )); // 移除过滤器,避免污染其他位置的归档查询 remove_filter( 'getarchives_where', $customer_archive_filter, 10 );
如果是员工博客侧边栏,只需要把代码里meta_value对应的Customer Blog替换成你给员工文章设置的blog_type字段值即可。
提示:你之前的
wp_get_archives参数里没有加链接占位符,输出的是纯文本,上面代码已经补了%link%的占位符,生成的月份会自动带上对应归档页的跳转链接,不需要额外处理。
方案二:自定义查询生成归档(逻辑更可控)
如果不想用过滤器,怕出现全局查询污染,可以直接写数据库查询取符合条件的归档月份,自己循环拼接HTML,输出结构和你原有设计完全一致:
global $wpdb; // 查询符合blog_type条件的近4个归档月份 $archives = $wpdb->get_results( $wpdb->prepare( " SELECT DISTINCT YEAR(p.post_date) AS post_year, MONTH(p.post_date) AS post_month, MONTHNAME(p.post_date) AS post_month_name FROM {$wpdb->posts} p INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id WHERE p.post_status = 'publish' AND p.post_type = 'post' AND pm.meta_key = 'blog_type' AND pm.meta_value = %s ORDER BY p.post_date DESC LIMIT 4 ", 'Customer Blog' ) ); // 循环输出归档项 if ( !empty( $archives ) ) { foreach ( $archives as $item ) { $archive_link = get_month_link( $item->post_year, $item->post_month ); echo '<div class="post-list">'; echo '<div class="text-1-1 fontawesome5free-solid-normal-grenadier-20px"></div>'; echo '<div class="january-2021 small-paragraph">'; echo '<a href="' . esc_url( $archive_link ) . '">' . esc_html( $item->post_month_name . ' ' . $item->post_year ) . '</a>'; echo '</div></div>'; } }
同样,员工博客只需要替换meta_value的取值即可。
注意事项
- 两种方案的筛选逻辑和你之前用
wp_get_recent_posts取最新文章的逻辑完全一致,只会统计对应类型的文章,不会出现混合归档的问题 - 如果你配置的ACF
blog_type字段是多选(存储为序列化值),需要把SQL里的等值判断改成LIKE匹配,从你之前wp_get_recent_posts直接传meta_value就能生效的情况看,当前是单值存储,不需要调整 - 方案一的匿名函数写法要求PHP版本≥5.3,目前WordPress官方推荐的运行环境都满足这个要求
内容的提问来源于stack exchange,提问作者SRussell
相关产品推荐
相关产品推荐

