点击查看更新记录

更新记录

2022-06-24 整理分享

1. 整理分享正式方案

2022-05-24 方案落地

1. 编写自定义 hexo 辅助函数,生成是自动重定向图片路径

2022-05-23 需求整理

1. 本地 Markdown 相对路径引用,Hexo 发布路径正确转码

2. 全自动生成,主题集成

# 引言

Hexo 资源文件夹 启用后, Markdown 采取相对路径引用图片以便于本地预览 和 Hexo 发布时资源路径重定向冲突。

本文主要解决两者之间的冲突,使得二者能够兼得.

# 需求整理

# Hexo 资源文件夹

如果你的 Hexo 项目中只有少量图片,那最简单的方法就是将它们放在 source/images 文件夹中。然后通过类似于 ![](/images/image.jpg) 的方法访问它们。

但是这样不利于 维护 也不够 优雅Hexo 资源文件夹就主要解决了这个痛点,资源( Asset )代表 source 文件夹中除了文章以外的所有文件,例如图片、 CSSJS 文件等。

这样就可以引用 资源文件夹 的图片资源来书写文章了

# 冲突

在启用资源文件夹后,一篇名为 test-post 的文章在 hexo new test-post 创建时 会生成同名文件夹 test-post .

一般来说 hexo 用户,都是在本地使用 VS Code 之类的编辑器,本地编写预览文章,那么文章的引用很自然的采取 [相对路径]{.blue} 的方式 ![desc](./test-post/imagename.png) 来引用图片,以便于本地能快速预览。

不幸的是,这样在生成时, hexo 不会进行路径重定向,会粗暴的在相对路径前面添加 rooturl/posts/ 无法正确重定向

imagepatherror

官方给出的解决方案如下

  1. 使用相对路径引用标签
{% asset_path slug %}
{% asset_img slug [title] %}
{% asset_link slug [title] %}
  1. 安装 hexo-renderer-marked 插件,使用 ![desc](imagename.xxx) 方式引用

两种方式都断了本地相对路径引用预览的路,遂两者不可兼得,冲突现。

# 解决方案

Hexo 框架预留了很多接口供主题编写者扩展,用于在不同时机和场景下,对文章渲染进行自定义修改,其中 过滤器(Filter) 给了我们处理 img 标签的一个绝佳机会。

我们可以通过如下流程,注册一个处理 img 的自定义 filter

  1. 注册 filter 函数,执行时间选择 after_post_render
hexo.extend.filter.register('after_post_render', function (data){
    // do something
})
  1. 编写函数逻辑对 img 标签的 data-src 属性进行修改,重定向到文章对应资源文件夹

# 代码实现

  1. 在主题文件夹 themes/shoka/scripts/helpers/ 下新增脚本 image_path_wrap.js (名字随意叫啥都行)

  2. 贴入完整代码,代码文件无需在其他地方引入,内部函数注册了即可

'use strict';
var cheerio = require('cheerio');
// http://stackoverflow.com/questions/14480345/how-to-get-the-nth-occurrence-in-a-string
function getPosition(str, m, i) {
    return str.split(m, i).join(m).length;
}
hexo.extend.filter.register('after_post_render', function (data) {
    var config = hexo.config;
    if (config.post_asset_folder) {
        var link = data.permalink;
        var beginPos = getPosition(link, '/', 3) + 1;
        var appendLink = '';
        if (/.*\/index\.html$/.test(link)) {
            appendLink = 'index/';
            var endPos = link.lastIndexOf('/');
        }
        else {
            var endPos = link.lastIndexOf('.');
        }
        link = link.substring(beginPos, endPos) + '/' + appendLink;
        var toprocess = ['excerpt', 'more', 'content'];
        for (var i = 0; i < toprocess.length; i++) {
            var key = toprocess[i];
            var $ = cheerio.load(data[key], {
                ignoreWhitespace: false,
                xmlMode: false,
                lowerCaseTags: false,
                decodeEntities: false
            });
            $('img').each(function () {
                if ($(this).attr('data-src')) {
                    var src = $(this).attr('data-src').replace('\\', '/');
                    if (!(/http[s]*.*|\/\/.*/.test(src)
                        || /^\s+\//.test(src)
                        || /^\s*\/uploads|images\//.test(src))) {
                        var srcArray = src.split('/').filter(function (elem) {
                            return elem != '' && elem != '.';
                        });
                        if (srcArray.length > 1)
                            srcArray.shift();
                        src = srcArray.join('/');
                        $(this).attr('data-src', config.root + link + src);
                        console.info && console.info("update link as:-->" + config.root + link + src);
                    }
                }
                else {
                    console.info && console.info("no src attr, skipped...");
                    console.info && console.info($(this));
                }
            });
            data[key] = $.html();
        }
    }
});
  1. 重新 Hexo 三连

# 结语

以上就是 资源文件夹 图片相对路径引用的修复过程,完美兼容本地预览和生成发布路径重定向问题。

更新于 阅读次数