2026年2月18日 · 3 分钟 · Fluid · 教程

Hexo Fluid 实现文章过期提示(非侵入式方案)

在维护博客时,经常会遇到一个问题:一些早期文章在搜索引擎或首页依然能被访问,但其中的内容已经不完全适用于当前环境。

于是决定给这些文章一个 「过期提示」

本文记录一种 完全非侵入式 的实现方案

一、实现效果

当文章满足条件时,在正文顶部显示提示:

这是一篇发布于
x 年 x 天
前的文章,部分信息可能已发生改变,请注意甄别。

特性包括:

  • 不到 1 年显示:X 天, 超过 1 年显示:X 年 X 天
  • 可手动或按日期自动触发
  • 不影响 Fluid 升级
  • 单篇文章控制

二、方案说明

Fluid 提供了官方的 主题注入(theme_inject)机制,允许在不修改主题文件的前提下,将自定义内容插入到指定位置。

整体思路如下:

  1. 使用 scripts/ 注册注入位置
  2. 将过期提示写成独立的 EJS 模板
  3. 从文章 front-matter 中读取 date / expired / expire_date
  4. 构建时自动计算并渲染

整个过程 不接触 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 天前」这种无意义信息。