厌倦了 WordPress 默认的静态文章发布时间格式吗?想让你的网站显示“几分钟前”、“几小时前”或“几天前”这样的相对时间,以增强内容的时效感和互动性吗?本文将为你提供一个完整、标准且易于集成的解决方案。
实现原理
WordPress 通过 the_time() 或 get_the_date() 等函数输出文章发布时间。我们可以通过 WordPress 的过滤器(Filter)机制,在时间输出前对其进行处理,计算发布时间与当前时间的差值,并将其转换为易于理解的相对时间格式。
核心功能代码
将以下代码添加到你的子主题的 functions.php 文件末尾,或通过“代码片段”插件添加。
/**
* 将文章发布时间转换为相对时间格式(如“3分钟前”)
*
* @param string $time 原始时间字符串。
* @return string 转换后的相对时间或原始日期。
*/
function wp_custom_relative_time($time) {
// 仅在主循环中处理文章发布时间
if (!is_single() && !is_page() && !in_the_loop()) {
return $time;
}
$post_time = get_post_time('U', true); // 获取文章发布时间的 Unix 时间戳
$current_time = current_time('timestamp'); // 获取当前时间的 Unix 时间戳
$time_diff = $current_time - $post_time; // 计算时间差(秒)
// 如果文章发布时间在未来(可能由于定时发布),则返回原始时间
if ($time_diff < 0) {
return $time;
}
// 定义时间单位(秒)
$minute = 60;
$hour = 60 * $minute;
$day = 24 * $hour;
$week = 7 * $day;
$month = 30 * $day; // 近似值
$year = 365 * $day; // 近似值
// 根据时间差返回相应的相对时间字符串
if ($time_diff < $minute) {
return __('刚刚', 'your-text-domain');
} elseif ($time_diff < $hour) {
$mins = round($time_diff / $minute);
return sprintf(_n('%s分钟前', '%s分钟前', $mins, 'your-text-domain'), $mins);
} elseif ($time_diff < $day) {
$hours = round($time_diff / $hour);
return sprintf(_n('%s小时前', '%s小时前', $hours, 'your-text-domain'), $hours);
} elseif ($time_diff < $week) {
$days = round($time_diff / $day);
return sprintf(_n('%s天前', '%s天前', $days, 'your-text-domain'), $days);
} elseif ($time_diff < $month) {
$weeks = round($time_diff / $week);
return sprintf(_n('%s周前', '%s周前', $weeks, 'your-text-domain'), $weeks);
} elseif ($time_diff < $year) {
$months = round($time_diff / $month);
return sprintf(_n('%s个月前', '%s个月前', $months, 'your-text-domain'), $months);
} else {
// 超过一年,返回原始格式化日期,保持一致性
return get_the_date(get_option('date_format'));
}
}
// 将过滤器应用到 the_time 和 get_the_date
add_filter('the_time', 'wp_custom_relative_time');
add_filter('get_the_date', 'wp_custom_relative_time');
代码说明与优化
- 健壮性检查:代码增加了对是否在主循环内的判断,避免影响其他地方的日期显示(如小工具)。
- 时间范围更完整:覆盖了从“刚刚”到“几年前”的完整范围,并增加了“周”和“月”的单位,使表达更自然。
- 国际化支持:使用
__(),_n()和sprintf()函数,并指定了文本域(‘your-text-domain’),便于主题或插件翻译。请将其替换为你主题的实际文本域。 - 未来时间处理:处理了定时发布文章导致发布时间在未来时的边界情况。
- 双过滤器应用:同时过滤
the_time和get_the_date,确保通过不同函数调用时间都能生效。
使用方法
添加上述代码后,无需额外操作。你的主题中所有通过 the_time() 或 get_the_date() 输出的发布时间,将自动转换为相对时间格式。
例如,在主题的 single.php 或 content.php 模板文件中,通常会有如下代码:
<?php the_time('F j, Y'); ?>
添加我们的过滤器后,它将不再显示“April 15, 2023”,而是根据当前时间显示为“2天前”或“1个月前”。
高级自定义与注意事项
1. 控制显示范围
如果你希望仅在特定时间范围内(如30天内)显示相对时间,超过则显示绝对日期,可以修改代码最后的 else 分支条件。例如,将判断“一年”改为“30天”:
// ... 省略前面的判断 ...
} elseif ($time_diff < (30 * $day)) { // 30天内
$days = round($time_diff / $day);
return sprintf(_n('%s天前', '%s天前', $days, 'your-text-domain'), $days);
} else {
// 超过30天,返回标准日期格式
return get_the_date(get_option('date_format'));
}
2. 排除特定页面
如果你不想在首页或分类页面应用此效果,可以使用条件标签:
function wp_custom_relative_time_conditional($time) {
// 不在首页、归档页应用此效果
if (is_home() || is_archive() || is_search()) {
return $time;
}
// 否则,调用原来的相对时间函数
return wp_custom_relative_time($time);
}
// 替换原来的过滤器
remove_filter('the_time', 'wp_custom_relative_time');
remove_filter('get_the_date', 'wp_custom_relative_time');
add_filter('the_time', 'wp_custom_relative_time_conditional');
add_filter('get_the_date', 'wp_custom_relative_time_conditional');
3. 清除缓存插件的影响
如果你使用了静态缓存插件(如 W3 Total Cache, WP Super Cache),相对时间可能会被缓存并固定显示。解决方法有两种:
- 通过缓存插件的“排除规则”设置,不缓存包含日期的部分。
- 考虑使用 JavaScript 客户端方案来实现相对时间,但这会牺牲一些SEO友好性。
总结
通过以上步骤,你可以轻松地为你的 WordPress 网站添加友好且动态的相对时间显示功能。这不仅提升了用户体验,也让内容显得更加鲜活。记得在修改主题文件前做好备份,或优先使用子主题进行操作。