注意:这篇文章上次更新于158天前,文章内容可能已经过时。
前段时间写的一个基于 Cloudflare Workers 搭建 Vless 节点访问 ChatGPT 的文章部分内容失效了,节点还是可以正常翻墙,但是由于代码中的 ProxyIP 失效了,所以无法访问 ChatGPT 的网站了,其实是所有托管在 Cloudflare 的网站都访问不了了。这周末更新了一下那篇文章中的代码,算是短暂修复了。
这个问题不是本文要讨论的内容,但是它让我想到我需要对文章内容的时效性加个必要的“免责声明”。
其实文章过期提醒这个 Feature 在很多博客主题中都有,但是我使用的 hexo-theme-yun 已经进入了维护阶段。
所以我需要自己动手实现这个功能。
在这篇博客中,我将会介绍如何在 hexo-theme-yun 主题中添加文章过期提醒功能。
效果如下:
实现原理
实现原理本身很简单,就是在渲染文章的时候获取到文章的更新时间,然后根据这个时间判断文章是否需要过时提醒。
再加上现在有 AI 的加持,即使是我这种没学过前端的人也能在一天内实现这个功能。
其实,30 分钟就够了,但是我用了一天的时间。其中 80% 的时间用来调试 CSS,这东西真是太恶心了。
我对 yun 主题的架构不是很了解,不过在摸索了一番后,我觉得所有文章以及页面的渲染都会在 post-content.pug 中进行。
所以我把代码加在这个文件里,但请注意这可能不是最好的解法。
实现步骤
总体的设计参考了 butterfly 主题的文章过期提醒功能。
- 所以,首先在主题的配置文件中加入下面的配置。
# 文章过期提醒
expire_notice:
enable: true
days: 90
text_before: 注意:这篇文章上次更新于
text_after: 天前,文章内容可能已经过时。
except_tags:
- 结绳记事
enable
:是否启用文章过期提醒功能。days
:文章过期提醒的天数。text_before
:文章过期提醒的前缀。text_after
:文章过期提醒的后缀。except_tags
:不需要过期提醒的标签。
我的博客中没有使用分类功能,我觉得分类和标签的区别不大,两个都用的话会显得有些多余,所以我只使用了标签功能。
于是我就想到实际上不是所有的文章都需要加入过期提醒功能,所以我加入了 except_tags
这个配置项。
- 然后修改
post-content.pug
为下面的代码。
section.post-body(itemprop='articleBody')
//- Outdated notice
- var isExceptTag = false;
- if (post && post.tags) {
- isExceptTag = post.tags.some(tag => theme.expire_notice.except_tags.includes(tag.name));
- }
- var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
- var firstDate = post && post.updated ? new Date(post.updated) : new Date();
- var secondDate = new Date();
- var diffDays = Math.round(Math.abs((firstDate - secondDate) / oneDay));
if theme.expire_notice.enable && !isExceptTag && diffDays > theme.expire_notice.days
div.expire_notice
p.expire_notice_p #{theme.expire_notice.text_before}
span.diff-days #{diffDays}
span.text-after #{theme.expire_notice.text_after}
//- body include reward, content is only post content
.post-content.markdown-body!= page.content
这段代码首先拿到了一些配置项,比如文章的标签是否在 except_tags
中,文章的更新时间,然后计算了文章更新时间和当前时间的差值。
然后根据这些值判断是否需要显示过期提醒。
- 最后,加入 CSS 样式。
我选择自己为这个功能写一个 CSS 文件,然后在主题的配置文件中引入这个 CSS 文件。
.expire_notice {
position: relative;
margin: 20px 0 20px 0;
padding: 15px;
border-radius: 3px;
font-size: 16px;
background: #f5f5f5; /* 灰色系列的背景颜色 */
color: #616161; /* 灰色系列的文字颜色 */
display: flex;
flex-wrap: wrap;
align-items: flex-start;
border-left: 5px solid #9e9e9e; /* 灰色系列的左边框 */
}
.expire_notice::before {
content: ""; /* 清空 content 属性 */
display: inline-block;
width: 1.25em;
height: 1.25em;
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxZW0iIGhlaWdodD0iMWVtIiB2aWV3Qm94PSIwIDAgMTI4IDEyOCI+PHBhdGggZmlsbD0iI2YyYTYwMCIgZD0ibTU3LjE2IDguNDJsLTUyIDEwNGMtMS45NCA0LjAyLS4yNiA4Ljg1IDMuNzUgMTAuNzljMS4wOC41MiAyLjI1LjggMy40NS44MWgxMDRjNC40Ni0uMDQgOC4wNS0zLjY5IDguMDEtOC4xNWE4LjEyMyA4LjEyMyAwIDAgMC0uODEtMy40NWwtNTItMTA0YTguMDY3IDguMDY3IDAgMCAwLTE0LjQgMCIvPjxwYXRoIGZpbGw9IiNmZmNjMzIiIGQ9Im01My41NiAxNS43MmwtNDguOCA5Ny40Yy0xLjgzIDMuNzctLjI1IDguMzEgMy41MiAxMC4xNGMuOTkuNDggMi4wOC43NCAzLjE4Ljc2aDk3LjVhNy41NSA3LjU1IDAgMCAwIDcuNDgtNy42MmE3LjYwNSA3LjYwNSAwIDAgMC0uNzgtMy4yOGwtNDguNy05Ny40YTcuNDQzIDcuNDQzIDAgMCAwLTkuOTMtMy40N2E3LjQ4NCA3LjQ4NCAwIDAgMC0zLjQ3IDMuNDciLz48cGF0aCBmaWxsPSIjNDI0MjQyIiBkPSJNNjQuMzYgMzQuMDJjNC42IDAgOC4zIDMuNyA4IDhsLTMuNCA0OGMtLjM4IDIuNTQtMi43NCA0LjMtNS4yOCAzLjkyYTQuNjQ2IDQuNjQ2IDAgMCAxLTMuOTItMy45MmwtMy40LTQ4Yy0uMy00LjMgMy40LTggOC04bTAgNjRjMy4zMSAwIDYgMi42OSA2IDZzLTIuNjkgNi02IDZzLTYtMi42OS02LTZzMi42OS02IDYtNiIgb3BhY2l0eT0iMC4yIi8+PGxpbmVhckdyYWRpZW50IGlkPSJub3RvV2FybmluZzAiIHgxPSI2OCIgeDI9IjY4IiB5MT0iLTE4MDguMzYiIHkyPSItMTg4Ny4wNSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgxIDAgMCAtMSAtMy42NCAtMTc3Ni4wOSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiM0MjQyNDIiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMyMTIxMjEiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGZpbGw9InVybCgjbm90b1dhcm5pbmcwKSIgZD0iTTY0LjM2IDM0LjAyYzQuNiAwIDguMyAzLjcgOCA4bC0zLjQgNDhjLS4zOCAyLjU0LTIuNzQgNC4zLTUuMjggMy45MmE0LjY0NiA0LjY0NiAwIDAgMS0zLjkyLTMuOTJsLTMuNC00OGMtLjMtNC4zIDMuNC04IDgtOCIvPjxsaW5lYXJHcmFkaWVudCBpZD0ibm90b1dhcm5pbmcxIiB4MT0iNjQuMzYiIHgyPSI2NC4zNiIgeTE9Ii0xODA4LjM2IiB5Mj0iLTE4ODcuMDUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMSAwIDAgLTEgMCAtMTc3Mi4xMSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiM0MjQyNDIiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMyMTIxMjEiLz48L2xpbmVhckdyYWRpZW50PjxjaXJjbGUgY3g9IjY0LjM2IiBjeT0iMTA0LjAyIiByPSI2IiBmaWxsPSJ1cmwoI25vdG9XYXJuaW5nMSkiLz48cGF0aCBmaWxsPSIjZmZmMTcwIiBkPSJNNTMuNTYgMjMuMDJjLTEuMiAxLjUtMjEuNCA0MS0yMS40IDQxcy0xLjggMyAuNyA0LjdjMi4zIDEuNiA0LjQtLjMgNS4zLTEuOHMxOS4yLTM2LjkgMTkuOS0zOC42Yy42LTEuODcuMTgtMy45MS0xLjEtNS40Yy0xLjMtMS4yLTIuNi0xLTMuNC4xIi8+PGNpcmNsZSBjeD0iMzEuMzYiIGN5PSI3NS4zMyIgcj0iMy4zIiBmaWxsPSIjZmZmMTcwIi8+PC9zdmc+"); /* 设置图标 */
background-size: contain; /* 调整图标的大小 */
background-repeat: no-repeat; /* 防止图标重复 */
background-position: center; /* 调整图标的位置 */
align-self: center;
}
.expire_notice_p {
margin: 0 5px; /* 移除默认的段落边距 */
color: #616161; /* 灰色系列的文字颜色 */
flex: 1;
}
.diff-days {
color: #d81e06; /* 红色文字 */
font-weight: bold;
font-size: 20px; /* 更大的字体大小 */
margin: 0 5px 0 5px;
}
.text-after {
flex: 1; /* 这将使元素占据剩余的空间 */
}
然后在主题的配置文件中引入这段 CSS 就 OK 了。
# custom your assets in head
head:
css:
myCss: /css/my.css
至此,这个小功能就实现完成了。效果如开篇图所示。
还是前端好,所见即所得,自己学了什么就能立马写出来看到效果。
不像我现在,干了一年的 WLAN Driver,WLAN 也不懂,Driver 也不会。😅