前言
相信很多朋友肯定碰到过这样的情况,花了大量的时间在网上搜索了一篇技术方面的教程, 在一番折腾之后发现频繁报错甚至完全不能用。最后既浪费了精力,也让人感到懊恼,挫败感满满。这是由于互联网技术的不断发展,文章会随着时间的推移出现信息与当下环境不符或者直接失效的情景,因此为一篇文章添加过期提醒功能十分的有必要。在文章的醒目位置用不同的颜色添加过期提示,不但能够提醒读者甄别文章信息,不要按部就班,适时地查找最新的相关资料,也能直观的展示文章的最后修订日期,从而让读者确定文章的适用性。
需求分析
为了能够自主控制文章是否过期,再加上我有点懒,我对文章过期提醒的需求如下:
- 文章过期提醒主要包含最后更新时间和距离现在的天数,然后根据距离现在的天数,用相应的颜色提醒读者文章过期时间的长短。
- 尽可能的不用去修改文章(例如:主要是不想或者漏写了更新时间),在经过一定天数后,文章页面依旧会出现过期提醒。
- 可以自由控制文章是否过期(例如:技术类文章存在过期的情况,日常类的文章不存在过期的情况),对指定了不过期的文章用相应的形式提醒读者文章没有时效性限制。
实现方式
实现以上需求有两种方式,分别为:
-
Hexo官方提供的注入器injector函数。只需在Hexo根目录下新建一个
scripts的文件夹,新建一个js文件,Hexo便可以将文章过期提醒的代码片段注入到生成的 HTML 的<head>和/或<body>标签中。优点是不用修改主题的模板,缺点是有局限性,适合简单代码的注入。 -
修改主题的网页模板,优点是没有局限性,缺点则是对于非开发者而言上手难度较高。
经过多次尝试,由于我使用的Melody主题只将文章的建立日期page.date变量渲染到了页面的<time>标签内,而没有添加文章的更新日期page.updated变量,导致使用Hexo注入器的时候JavaScript只能获取渲染页面<time>标签内的内容,从而无法实现我的需求,更何况我们还要添加控制文章过期的expire参数,因此我决定采用第二种方法。
注意:这个取决于你使用的主题,有的主题自带文章过期提示功能,在主题内可以直接开启。如果你的主题没有文章过期提功能,但将
page.date和page.updated变量渲染到页面中且不需要控制文章是否过期,那么你就可以使用第一种方式。
添加文章过期提示功能
作为主要目标,我们先编写文章过期提醒功能,测试没有问题后,在下一章节再编写文章过期的开关。
注意:由于我使用的主题是用pug语言写的,如果你的主题使用的是其他语言,如:swig,那么请参照相关语言的语法。另外不同主题的模板目录有所差异,本文仅适用于Melody主题,其他主题请参考主题的文档。
-
打开Hexo根目录下的
_config.yml,找到其中的updated_option:选项,将值设置为'date',意思是当你的文章的 Front Matter中没有明确的指定updated时,以你文章的建立日期date为准。 -
打开主题目录中的
/layout/includes文件夹,新建一个名为post-expire的文件夹。 -
在
post-expire文件夹中新建两个文件,分别为:post-expire.pug和no-expire.pug,文件名称可自己决定。 -
打开
post-expire.pug,在文件内填入以下代码后保存:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18script(src='https://gcore.jsdelivr.net/npm/dayjs/dayjs.min.js') //引入dayjs
script.
const updateDate = dayjs(!{page.updated}) //获取文章的updated值
const diffDays = dayjs().diff(updateDate, 'day') //让updated值与当前时间作比较。
//设置过期提醒时间,可自定义。
if(diffDays >= 720) {
document.write(
'<div class="post-expire-danger">' + '本文最后更新于' + diffDays + '天前(' + updateDate.format('YYYY-MM-DD') + '),其中的信息可能已经失效或与当前技术严重不符,强烈建议进行甄别。' + '</div>')
}
else if (diffDays >= 360) {
document.write(
'<div class="post-expire-warning">' + '本文最后更新于' + diffDays + '天前(' + updateDate.format('YYYY-MM-DD') + '),其中的信息与现阶段相比出现偏差,建议进行甄别。' + '</div>')
}
else if (diffDays >= 180) {
document.write(
'<div class="post-expire-info">' + '本文最后更新于' + diffDays + '天前(' + updateDate.format('YYYY-MM-DD') + '),其中的信息可能已经有所发展,请谨慎参考。' + '</div>')
} -
打开
no-expire.pug,在文件内填入以下代码后保存:1
2
3
4
5
6
7
8
9
10//与上面相同
script(src='https://gcore.jsdelivr.net/npm/dayjs/dayjs.min.js')
script.
const updateDate = dayjs(!{page.updated})
const diffDays = dayjs().diff(updateDate, 'day')
//设置过去多少天后出现不过期的提醒,可以自定义
if (diffDays >= 180)
document.write (
'<div class="post-no-warning ">' + '本文最后更新于' + diffDays + '天前(' + updateDate.format('YYYY-MM-DD') + '),但文章时效性不受影响。' + '</div>')
两个文件一个是文章过期功能开启时所执行的代码,这样如果文章的Front Matter中在没有明确的写出更新日期(不写或者忘了写),即updated时,你文章的发布时间和更新时间是一致的。当出现更新时间updated时,以这个时间为准,提示读者你对文章曾经进行过修订,在文章相修订的N天后进行过期提醒。一个是文章提醒功能关闭时(即文章不过期)所执行的代码,在文章发布日期或更新日期的N天后向读者表明无论过去多长时间,文章都不过期。
添加文章过期提醒开关代码
其实这一部分非常简单,我们的思路是默认文章过期功能是打开的,只有文章的 Front Matter中明确的出现expire: false时,文章才关闭过期提醒,在达到一定的时间后,提示读者文章时效性不受影响。具体步骤如下:
-
打开主题的
/layout/post.pug模板文件。 -
打开浏览器,随便进入一篇文章,点击右键的“检查”,找到文章正文之前的标签,比如我的主题正文之前的标签是
<div id="post-meta">,在模板文件中就是#post-meta` -
在
#post-meta代码块之后插入expire的判断代码,然后保存。1
2
3
4if (page.expire !== false)
include ./includes/post-expire/post-expire.pug
else
include ./includes/post-expire/no-expire.pug
注意:请确保if代码和post-meta在同一层级,是并列关系,这样浏览器才会正确计算这个div标签的宽度。
为文章提醒编写css文件
我们已经为不同时间的过期提醒设置了不同的类,只需要进入你自己主题的css文件中,设置样式即可,下面以Melody主题为例:
-
在
/source/css/_layout文件夹下建立一个名为postexpire.styl文件 -
添加css样式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30//post-expire css 设置
.post-expire-danger
margin: 1rem 0;
margin-left: 0 ;
padding: 1.5rem 0.5rem;
background-color: rgba(230,15,15,0.15);
border-left: 0.25rem solid rgba(230,15,15,0.8);
.post-expire-warning
margin: 1rem 0;
margin-left: 0 ;
padding: 1.5rem 0.5rem;
background-color: rgba(255,195,0,0.15);
border-left: 0.25rem solid rgba(255,195,0,0.8);
.post-expire-info
margin: 1rem 0;
margin-left: 0 ;
padding: 1.5rem 0.5rem;
background-color: rgba(52,152,219,0.15);
border-left: 0.25rem solid rgba(52,152,219,0.8);
.post-no-warning
margin: 1rem 0;
margin-left: 0 ;
padding: 1.5rem 0.5rem;
background-color: rgba(40,180,99,0.15);
border-left: 0.25rem solid rgba(40,180,99,0.8); -
主css文件已经引用了这个文件夹下的所有文件,故不用修改,如果你的主题不是,请引用这个文件。
Front Matter示例
为了防止个别用户不知道如何使用,我举一个示例,当你新建文章后,文章内需要填写以下内容,其中title和date是必须的,其他是可选的。
1 | title: your title |
当达到你设置的时间后,如30天后。最终显示内容如下:
本文最后更新于XX天前(2026-02-02),但文章时效性不受影响。
后记
由于本文使用的是方法二,最后要将这些修改应用到你自定义的主题中,毕竟是自己额外添加的,原主题没有,方法可参考这里,后续主题修改后,可以使用npm install git+https://github.com/yourusername/your-repo.git --save命令进行更新,具体的展示效果可以浏览我博客的其他页面。由于本人水平有限,其中的一些内容可能表达不清或者容易引起歧义,但是我已经尽自己最大的努力去调整了,希望能给你带来帮助。
