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();
    });
    }
  2. 效果如下,如果已经生成过静态文件,需要清空缓存 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/

如果您觉得文章不错,可以请我喝一杯咖啡!