hexo tag 标签添加拦截功能

hexo 引用文章引用资源 有这几种引用方式 post_link, post_path, asset_path, asset_link, asset_img 。这几种 tag 标签在文章中出现次数不少。

但是有个问题,如果不小心改了文章的 permalink 或者 资源文件夹 下的文件名,导致文章或者资源找不到了, hexo 并不会给我们任何提示,直接返回空字符串渲染,这就蛋疼了,总有百密一疏的时候。

作为程序员,怎么能资源找不到的情况!!

在官方没相关的中间件、拦截器的情况下。一波源码阅读之后,骚操作一把,为这几个 tag 标签添加了拦截功能,如果出现找不到资源情况,控制台打印提示信息。

添加脚本

运用 hexo 官方的 插件系统,在主题目录下的 scripts 目录新建文件,以 landscape 为例:

  1. 新建文件 themes/landscape/scripts/tag_interceptor.js
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
const Post = hexo.model('Post');
const PostAsset = hexo.model('PostAsset');

let tagRenderError = [];

hexo.on('ready', function(){
// 让 scripts 目录中自定义的 tag 先执行,比如说:添加的自定义 tag demo_link
[ 'post_link', 'post_path', 'asset_path', 'asset_link', 'asset_img', 'demo_link' ].forEach((name) => {
let extension = null;

try {
// https://github.com/hexojs/hexo/blob/master/lib/extend/tag.js
// http://mozilla.github.io/nunjucks/cn/api.html#getextension
extension = hexo.extend.tag.env.getExtension(name);
} catch (e) {
console.log(`tag_interceptor.js文件中 hexo.extend.tag.env.getExtension('${name}') 执行出错:`);
console.log(`原因可能为 hexo 版本升级,找不到 env 属性,详细错误如下:`);
console.error(e);
return;
}

if (!extension) {
console.log(`未找到注册名称为 ${name} 的 tag`);
return;
}

// 保存原函数
const original = extension.fn;

// 重写函数
extension.fn = function (args) {
const [ slug ] = args;
const res = original.call(this, args);
if (!res) {
tagRenderError.push({
tag: name,
info: `引用不存在: ${slug}`,
title: this.title,
source: this.source,
});
}
// 返回执行结果
return res;
};
});
});

// 打印错误
const printError = ()=> {
// 添加 setTimeout 是为了让 错误信息打印在最后
if (tagRenderError.length > 0) {
console.log('');
for (let i = 0; i < tagRenderError.length; i++) {
console.log(JSON.stringify(tagRenderError[i], null, 2));
}
console.log('');
tagRenderError = [];
}
};

if (JSON.parse(process.env.npm_config_argv).original[1] === 'server') {
// 如果执行的是 npm run server ,需要将错误信息打印在每次编译之后
hexo.extend.filter.register('after_generate', function(){
printError();
});
} else {
// 如果执行的是 npm run build 或者其他命令,错误信息打印在最后
hexo.extend.filter.register('before_exit', function(){
printError();
});
}
  1. 效果如下,如果已经生成过静态文件,需要清空缓存 npm run clean

根据以上效果,也可以添加其他 tag 标签的拦截功能,前提是 hexo.extend.tag.env.getExtension 还能使用!!

欢迎提出更好的方式

本文由 linx(544819896@qq.com) 创作,采用 CC BY 4.0 CN协议 进行许可。 可自由转载、引用,但需署名作者且注明文章出处。本文链接为: https://blog.jijian.link/2020-02-29/hexo-tag-interceptor/

如果您觉得文章不错,可以点击文章中的广告支持一下!