# 引言
为 Shoka
主题添加文章实效性提示 —— 文章发表时间过久,部分内容实际上可能以及过时,需要在显眼处给出浏览者实效性提示。
# 主题集成
需要修改的文件列表如下,相对于 Shoka
主题根目录
# theme/shoka shoka 主题目录 | |
├── _config.yml | |
├── languages | |
│ ├── en.yml | |
│ ├── ja.yml | |
│ ├── zh-CN.yml | |
│ ├── zh-HK.yml | |
│ └── zh-TW.yml | |
├── layout | |
│ └── _partials | |
│ └── layout.njk | |
├── scripts | |
│ └── generaters | |
│ └── script.js | |
└── source | |
└── js | |
└── _app | |
├── global.js | |
└── pjax.js |
# 修改 _config.yml
添加相关控制变量
# 文章是否失效 | |
isOutdated: | |
# 是否启用文章实效性提示 | |
enable: true | |
# 实效性天数,默认 30 天 | |
days: 30 |
# 修改多语言字段信息
添加实效性对应文本串,引入格式串文本,多语言适配
isOutdated: | |
format_year_as_prefix: '{{year}}年' | |
format_month_as_prefix: '{{month}}个月' | |
format_month_as_suffix: '零{{month}}个月' | |
format_day_as_prefix: '{{day}}天' | |
format_day_as_suffix: '零{{day}}天' | |
template: <div class='note warning'><p><span class='label warning'>时效性提示</span><br>这是一篇发布于 <span class='pink'>{{publish}}</span> 前,最后一次更新距今已经 <span class='pink'>{{updated}}</span> 的文章,部分内容可能已经过时,请注意甄别。</p></div> |
isOutdated: | |
format_year_as_prefix: '{{year}}年' | |
format_month_as_prefix: '{{month}}個月' | |
format_month_as_suffix: '零{{month}}個月' | |
format_day_as_prefix: '{{day}}天' | |
format_day_as_suffix: '零{{day}}天' | |
template: <div class='note warning'><p><span class='label warning'>時效性提示</span><br>這是一篇發佈於 <span class='pink'>{{publish}}</span> 前,最後一次更新距今已經 <span class='pink'>{{updated}}</span> 的文章,部分內容可能已經過時,請注意甄別。</p></div> |
isOutdated: | |
format_year_as_prefix: '{{year}}年' | |
format_month_as_prefix: '{{month}}個月' | |
format_month_as_suffix: '零{{month}}個月' | |
format_day_as_prefix: '{{day}}天' | |
format_day_as_suffix: '零{{day}}天' | |
template: <div class='note warning'><p><span class='label warning'>時效性提示</span><br>這是一篇發佈於 <span class='pink'>{{publish}}</span> 前,最後一次更新距今已經 <span class='pink'>{{updated}}</span> 的文章,部分內容可能已經過時,請注意甄別。</p></div> |
isOutdated: | |
format_year_as_prefix: '{{year}}' | |
format_month_as_prefix: '{{month}} month' | |
format_month_as_suffix: 'and {{month}} months' | |
format_day_as_prefix: '{{day}} days' | |
format_day_as_suffix: 'and {{day}} days' | |
template: <div class='note warning'><p><span class='label warning'>Timeliness Alert</span><br>This is an article published <span class='pink'>{{publish}}</span> ago and last updated <span class='pink'>{{updated}}</span> days ago. Some information may be outdated, please pay attention to screening.</p></div> |
isOutdated: | |
format_year_as_prefix: '{{year}}' | |
format_month_as_prefix: '{{month}} 月' | |
format_month_as_suffix: 'ゼロ {{month}} か月' | |
format_day_as_prefix: '{{day}} 日' | |
format_day_as_suffix: 'ゼロ {{day}} 日' | |
template: <div class='note warning'><p><span class='label warning'>適時性の警告</span><br> <span class='pink'>{{publish}}</span> 前に公開され、 <span class='pink'>{{updated}}</span> 前に最終更新された記事です。一部のコンテンツは時代遅れかもしれません、スクリーニングに注意してください。</p></div> |
# source/js/_app/global.js
添加全局处理函数
const isOutdated = function() { | |
if (CONFIG.isOutdated.enable && LOCAL.isOutdated) { | |
var times = document.getElementsByTagName("time"); | |
if (times.length === 0) { | |
return; | |
} | |
var posts = document.getElementsByClassName("body md"); | |
if (posts.length === 0) { | |
return; | |
} | |
var now = Date.now(); // 当前时间戳 | |
var pubTime = new Date(times[0].dateTime); // 文章发布时间戳 | |
if (times.length === 1) { | |
var updateTime = pubTime; // 文章发布时间亦是最后更新时间 | |
} else { | |
var updateTime = new Date(times[1].dateTime); // 文章最后更新时间戳 | |
} | |
var interval = parseInt(now - updateTime); // 时间差 | |
var days = parseInt(CONFIG.isOutdated.days) || 30; // 设置时效,默认硬编码 30 天 | |
// 最后一次更新时间超过 days 天(毫秒) | |
var dayLevelValue = 24 * 60 * 60 * 1000; | |
if (interval > days * dayLevelValue) { | |
var monthLevelValue = 30 * 24 * 60 * 60 * 1000; | |
var yearLevelValue = 365 * 24 * 60 * 60 * 1000; | |
function getDifference(period) { | |
/******* 计算出时间差中的年、月、日 *******/ | |
function getYear(period) { | |
return parseInt(period) / yearLevelValue; | |
} | |
function getMonth(period) { | |
return parseInt(period) / monthLevelValue; | |
} | |
function getDay(period) { | |
return parseInt(period) / dayLevelValue; | |
} | |
function isEmpty(obj){ | |
if(typeof obj == "undefined" || obj == null || obj == ""){ | |
return true; | |
}else{ | |
return false; | |
} | |
} | |
var year = parseInt(getYear(period)); | |
var month = parseInt(getMonth(period - year * yearLevelValue)); | |
var day = parseInt(getDay(period - year * yearLevelValue - month * monthLevelValue)); | |
var result = ""; | |
if (year != 0) { | |
result += LOCAL.format_year_as_prefix.replace("{{year}}", year) | |
} | |
if (month != 0) { | |
if (isEmpty(result)) { | |
result += LOCAL.format_month_as_prefix.replace("{{month}}", month) | |
} else { | |
result += LOCAL.format_month_as_suffix.replace("{{month}}", month) | |
} | |
} | |
if (day != 0) { | |
if (isEmpty(result)) { | |
result += LOCAL.format_day_as_prefix.replace("{{day}}", day) | |
} else { | |
result += LOCAL.format_day_as_suffix.replace("{{day}}", day) | |
} | |
} | |
return result; | |
} | |
var publish = getDifference(now - pubTime); | |
var updated = getDifference(interval); | |
var template = LOCAL.template.replace("{{publish}}", publish).replace("{{updated}}", updated); | |
posts[0].insertAdjacentHTML("afterbegin", template); | |
} | |
} | |
}; |
# source/js/_app/pjax.js
的 siteRefresh
函数的最后一行 调用全局函数处理
cardActive() | |
lazyload.observe() | |
// 新增部分 begin | |
isOutdated() // 判断文章时效性 | |
// 新增部分 end |
# scripts/generaters/script.js
的 siteConfig
添加变量 (随便选一行后面插入就行,案例写在了 valine
的上面)
loader: theme.loader, | |
search : null, | |
// 新增部分 begin | |
isOutdated: theme.isOutdated, | |
// 新增部分 end | |
valine: theme.valine, |
# layout/_partials/layout.njk
的 LOCAL
变量添加实效性相关变量
<script data-config type="text/javascript"> | |
var LOCAL = { | |
// ... | |
// 新增部分 begin | |
{%- if page.isOutdated === false %} | |
isOutdated: false, | |
{%- else %} | |
isOutdated: true, | |
format_year_as_prefix: "{{ __('isOutdated.format_year_as_prefix') }}", | |
format_month_as_prefix: "{{ __('isOutdated.format_month_as_prefix') }}", | |
format_month_as_suffix: "{{ __('isOutdated.format_month_as_suffix') }}", | |
format_day_as_prefix: "{{ __('isOutdated.format_day_as_prefix') }}", | |
format_day_as_suffix: "{{ __('isOutdated.format_day_as_suffix') }}", | |
template: "{{ __('isOutdated.template') }}", | |
{%- endif %} | |
// 新增部分 end | |
// ... | |
ignores: [ | |
function (uri) { | |
return uri.includes('#'); | |
}, | |
function (uri) { | |
return new RegExp(LOCAL.path + "$").test(uri); | |
}{%- if theme.quicklink.ignores %}, | |
{{ theme.quicklink.ignores|safedump }} | |
{%- endif %} | |
] | |
}; | |
</script> |
# Front-matter
控制
默认文章实效性检查是启用的,对于不想启用文章实效性的文章
可以在文章头部的 Front-matter
信息强制指定关闭实效性检测
--- | |
isOutdated: false #关闭检查文章实效性 | |
--- |
# 效果预览
时效性提示
这是一篇发布于 x 天前,最后一次更新距今已经 y 天的文章,部分内容可能已经过时,请注意甄别。
或者您看到本文时,本文正文顶部已经出现了实效性提示。