# 引言
Hexo 资源文件夹 启用后,Markdown 采取相对路径引用图片以便于本地预览 和 Hexo 发布时资源路径重定向冲突。
本文主要解决两者之间的冲突,使得二者能够兼得.
# 需求整理
# Hexo资源文件夹
如果你的 Hexo 项目中只有少量图片,那最简单的方法就是将它们放在 source/images 文件夹中。然后通过类似于  的方法访问它们。
但是这样不利于 维护 也不够 优雅,Hexo 资源文件夹就主要解决了这个痛点, 资源(Asset)代表 source 文件夹中除了文章以外的所有文件,例如图片、CSS、JS 文件等。
这样就可以引用 资源文件夹 的图片资源来书写文章了
# 冲突
在启用资源文件夹后,一篇名为 test-post 的文章在 hexo new test-post 创建时 会生成同名文件夹 test-post.
一般来说 hexo 用户,都是在本地使用 VS Code 之类的编辑器,本地编写预览文章,那么文章的引用很自然的采取 相对路径 的方式  来引用图片,以便于本地能快速预览。
不幸的是,这样在生成时,hexo 不会进行路径重定向,会粗暴的在相对路径前面添加 rooturl/posts/ 无法正确重定向

官方给出的解决方案如下
- 使用相对路径引用标签
{% asset_path slug %}
{% asset_img slug [title] %}
{% asset_link slug [title] %}- 安装
hexo-renderer-marked插件,使用方式引用
两种方式都断了本地相对路径引用预览的路,遂两者不可兼得,冲突现。
# 解决方案
Hexo 框架预留了很多接口供主题编写者扩展,用于在不同时机和场景下,对文章渲染进行自定义修改,其中 过滤器(Filter) 给了我们处理 img 标签的一个绝佳机会。
我们可以通过如下流程,注册一个处理 img 的自定义 filter
- 注册
filter函数,执行时间选择after_post_render
hexo.extend.filter.register('after_post_render', function (data){
// do something
})- 编写函数逻辑对
img标签的data-src属性进行修改,重定向到文章对应资源文件夹
# 代码实现
在主题文件夹
themes/shoka/scripts/helpers/下新增脚本image_path_wrap.js(名字随意叫啥都行)贴入完整代码,代码文件无需在其他地方引入,内部函数注册了即可
'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();
}
}
});- 重新
Hexo三连
# 结语
以上就是 资源文件夹 图片相对路径引用的修复过程,完美兼容本地预览和生成发布路径重定向问题。

有什么想法,欢迎留下评论。