WordPress:判断指定日期/月份是否有文章及优化归档页跳转按钮
嘿,这两个WordPress的问题我之前都遇到过,尤其是归档页的上下月按钮,踩过不少坑,给你分享下我的解决方案~
问题1:如何查看WordPress中未来日期是否存在文章?
WordPress里未来日期的文章一般分为两种:一种是**定时发布(状态为future)**的文章,另一种是不小心把发布日期设为未来但状态是publish的文章。要判断是否存在这类文章,用WP_Query就能轻松实现,不用折腾复杂的数据库查询。
直接上代码,你可以把这段逻辑放在主题的functions.php里,或者需要判断的模板文件中:
// 查询所有未来日期的文章 $future_posts = new WP_Query(array( 'post_type' => 'post', // 如果是自定义文章类型,替换成你自己的slug 'post_status' => array('future', 'publish'), // 包含定时发布+已发布但日期在未来的文章 'date_query' => array( array( 'after' => date('Y-m-d H:i:s'), // 筛选当前时间之后的文章 'inclusive' => false, // 不包含刚好当前时间发布的文章 ), ), 'posts_per_page' => 1, // 只要找到1篇就够,优化性能 'no_found_rows' => true, // 关闭分页计数,提升性能 )); // 判断结果 if ($future_posts->have_posts()) { echo '存在未来日期的文章'; } else { echo '没有未来日期的文章'; } wp_reset_postdata(); // 重置查询,避免影响后续的WordPress循环
如果只是需要判断“是否存在”,把posts_per_page改成1会更高效,因为只要找到一篇就可以停止查询了。
问题2:归档页上下月按钮的跳转优化(避免无文章月份崩溃)
这个需求的核心是先验证目标月份是否有文章,没有的话就自动往前/往后找最近的有文章的月份,彻底解决跳转到无内容页面导致的404(也就是你说的“网站崩溃”)问题。
我把这个逻辑拆成了几个可复用的函数,方便你直接用:
第一步:写一个判断指定年月是否有文章的工具函数
/** * 判断指定年月是否存在已发布的文章 * @param int $year 年份(比如2024) * @param int $month 月份(1-12) * @return bool 有文章返回true,否则false */ function has_posts_in_month($year, $month) { $posts = new WP_Query(array( 'post_type' => 'post', // 自定义文章类型的话,改成你的类型slug 'post_status' => 'publish', // 只查已发布的文章 'date_query' => array( array( 'year' => $year, 'month' => $month, ), ), 'posts_per_page' => 1, // 只要找到1篇就够,优化性能 'no_found_rows' => true, // 关闭分页计数 'fields' => 'ids', // 只查询文章ID,减少数据库返回的数据量 )); return $posts->have_posts(); }
第二步:写寻找上/下一个有效月份的函数
这两个函数会自动遍历附近的月份,直到找到有文章的那个:
/** * 寻找下一个有文章的月份 * @param int $current_year 当前归档的年份 * @param int $current_month 当前归档的月份 * @return array|null 返回包含year和month的数组,找不到则返回null */ function get_next_valid_month($current_year, $current_month) { $next_month = $current_month + 1; $next_year = $current_year; // 最多遍历12个月,避免无限循环(可根据你的博客情况调整数值) $max_tries = 12; $tries = 0; while ($tries < $max_tries) { // 处理月份跨年的情况(比如12月的下一个月是1月) if ($next_month > 12) { $next_month = 1; $next_year++; } // 如果这个月份有文章,直接返回 if (has_posts_in_month($next_year, $next_month)) { return array( 'year' => $next_year, 'month' => $next_month, ); } $next_month++; $tries++; } return null; // 遍历完没找到,可根据需求处理(比如返回最后一个有文章的月份) } /** * 寻找上一个有文章的月份 * @param int $current_year 当前归档的年份 * @param int $current_month 当前归档的月份 * @return array|null */ function get_prev_valid_month($current_year, $current_month) { $prev_month = $current_month - 1; $prev_year = $current_year; $max_tries = 12; $tries = 0; while ($tries < $max_tries) { // 处理月份跨年的情况(比如1月的上一个月是12月) if ($prev_month < 1) { $prev_month = 12; $prev_year--; } if (has_posts_in_month($prev_year, $prev_month)) { return array( 'year' => $prev_year, 'month' => $prev_month, ); } $prev_month--; $tries++; } return null; }
第三步:在归档模板中调用函数生成按钮
打开你的归档模板(比如archive.php或者专门的月份归档模板archive-month.php),替换原来的上下月按钮代码:
// 获取当前归档页的年月参数 $current_year = get_query_var('year'); $current_month = get_query_var('monthnum'); // 获取上一个/下一个有效月份 $prev_valid_month = get_prev_valid_month($current_year, $current_month); $next_valid_month = get_next_valid_month($current_year, $current_month); // 生成上月按钮 if ($prev_valid_month) { $prev_link = get_month_link($prev_valid_month['year'], $prev_valid_month['month']); echo '<a href="' . esc_url($prev_link) . '" class="prev-month-btn">上一月</a>'; } else { // 如果没有上一个月份,隐藏按钮或者添加禁用样式 echo '<span class="prev-month-btn disabled">上一月</span>'; } // 生成下月按钮 if ($next_valid_month) { $next_link = get_month_link($next_valid_month['year'], $next_valid_month['month']); echo '<a href="' . esc_url($next_link) . '" class="next-month-btn">下一月</a>'; } else { echo '<span class="next-month-btn disabled">下一月</span>'; }
额外说明:
- 如果你的博客有自定义文章类型,记得在
has_posts_in_month函数里把post_type改成array('post', '你的自定义类型slug') - 可以调整
$max_tries的数值,如果你的文章间隔可能超过12个月,就调大一点,但别太大,避免影响性能 - 这个逻辑完全基于WordPress原生函数,不用依赖任何插件,兼容性拉满
内容的提问来源于stack exchange,提问作者CupOfSalt
相关产品推荐
相关产品推荐

