Hexo Fluid 实现文章过期提示(非侵入式方案)
在维护博客时,经常会遇到一个问题:一些早期文章在搜索引擎或首页依然能被访问,但其中的内容已经不完全适用于当前环境。
于是决定给这些文章一个 「过期提示」
本文记录一种 完全非侵入式 的实现方案
一、实现效果
当文章满足条件时,在正文顶部显示提示:
这是一篇发布于
x 年 x 天
前的文章,部分信息可能已发生改变,请注意甄别。
x 年 x 天
前的文章,部分信息可能已发生改变,请注意甄别。
特性包括:
- 不到 1 年显示:
X 天, 超过 1 年显示:X 年 X 天 - 可手动或按日期自动触发
- 不影响 Fluid 升级
- 单篇文章控制
二、方案说明
Fluid 提供了官方的 主题注入(theme_inject)机制,允许在不修改主题文件的前提下,将自定义内容插入到指定位置。
整体思路如下:
- 使用
scripts/注册注入位置 - 将过期提示写成独立的 EJS 模板
- 从文章 front-matter 中读取
date / expired / expire_date - 构建时自动计算并渲染
整个过程 不接触 themes/fluid 目录,升级安全。
三、文章 Front-matter 用法
在需要控制的文章中添加字段:
---
title: 示例文章
date: 2023-02-10 12:28:33
expired: true (可选,默认为false)
expire_date: 2024-01-01 (可选)
---
字段说明
date:文章发布时间(Hexo 默认字段),用于计算“距今多久”。expired: true:强制显示过期提示,不受日期影响。expire_date:指定一个过期时间,当当前时间晚于该日期时自动显示提示。
使用策略示例
| 写法 | 行为 |
|---|---|
| 什么都不写 | 永不显示 |
expired: true |
强制显示 |
仅写 expire_date |
到期后显示 |
四、实现
在根目录下,新建scripts目录(如果尚不存在)。
在该目录中创建一个用于注册注入的脚本文件inject-expired.js,内容如下:
hexo.extend.filter.register('theme_inject', injects => {
injects.postMarkdownBegin.file(
'expired-warning',
'source/_inject/expired-warning.ejs'
);
});
真正显示提示的内容放在一个独立的 EJS 模板中,位于source/_inject目录。
新建文件expired-warning.ejs内容如下:
<%
// 当前时间
const now = new Date();
// 文章发布时间(来自 front-matter 的 date)
const postDate = new Date(page.date);
// 相差毫秒
const diffTime = now - postDate;
// 相差天数
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
// 年 / 天拆分
const years = Math.floor(diffDays / 365);
const days = diffDays % 365;
// 显示用文本
let ageText = '';
if (years > 0) {
ageText = `${years} 年 ${days} 天`;
} else {
ageText = `${diffDays} 天`;
}
// 是否显示过期提示
const expireDate = page.expire_date ? new Date(page.expire_date) : null;
const showExpired =
diffDays > 0 &&
(page.expired || (expireDate && now > expireDate));
%>
<% if (showExpired) { %>
<div class="post-expired-warning">
这是一篇发布于
<strong><%= ageText %></strong>
前的文章,部分信息可能已发生改变,请注意甄别。
</div>
<% } %>
这个模板主要做了几件事:
- 从 page.date 读取文章发布时间
- 获取当前构建时间
- 计算两者之间相差的天数
- 将天数拆分为「年 + 天」的形式
- 根据 expired 或 expire_date 判断是否需要显示
当文章发布时间不足一天时,不显示提示,避免出现「0 天前」这种无意义信息。
发表评论