非VIP会员,可以从这里()查看完整文章
搭建好Hexo博客后,接下来经常要做的就是写博客,使用 hexo new post title
可以自动创建文件,而且也支持模板,但是你仍然需要使用一种 markdown 编辑器打开这个文件进行编辑,如果你需要在文章中插入图片,你可能要单独把图片放到资源目录中,然后在博客中引用图片,仅仅这一点不方便就能把我劝退。Hexo很方便进行扩展,同时我经常使用的markdown编辑器Obsidian也支持扩展,两者一结合就能很方便的写博客。
除了博客内容的图片这一个问题外,还有就是默认创建的博客文件都在 _posts
目录下面,如果写的内容很多,这种一个目录的管理方式就会很乱,将文章按类别放到不同目录中会更方便易用。配合几个插件就能实现这些。
需要这么多插件会不会很麻烦?除了Obsidian因为网络原因不方便访问外,Hexo直接通过npm i xxxx --save
就能安装。接下来说一下整个配置过程。
1. Obsidian 打开 _posts
目录
使用 Obsidian 管理博客的时候,我们不需要从博客的根目录打开,只需要打开 _posts
目录即可,后续的所有操作都是在该目录进行的,和 Obsidian 有关的配置和插件都会安装到该目录下面的 .obsidian
中,Hexo 默认忽略 .
开头的隐藏文件,不会对 Hexo 产生影响,这个配置目录是可以直接提交到 git 上面的,在任何位置从 git clone 后,用 Obsidian 打开后都不需要重新配置,使用起来很方便。
Obsidian 想方便的使用,这一步很关键,记得打开 _posts
目录,范围小了,事就少。
2. 博客内插入图片
2.1 配置 Hexo 插件
先解决插入图片的问题,首先配置 Hexo 的配置文件 _config.yml
,启用下面的配置:
post_asset_folder: true
- 1
官方文档对这个属性有 详细介绍 ,使用 hexo new post title
时会自动创建和文章同名的目录,可以将图片放到这个目录中,在博客中使用相对目录的资源地址即可。
如果文章改名了,目录可不会自动改名,但是可以通过 Obsidian 来方便的改名和自动处理图片。
Hexo 中插入图片都推荐用的 tag 方式,例如: {% asset_path slug %}
,这种方式在 markdown 中不通用,我们肯定要用 markdown 格式的图片: ![]()
,官方虽然有一定的支持,但是不好用,针对这个问题,我们使用 hexo-image-link 插件,通过 npm install hexo-image-link --save
安装插件即可,不需要额外配置。
2.2 配置 Obsidian 插件
接下来在 Obsidian 中配置 Custom Attachment location 插件,有两种安装方式:
1 插件市场
在插件市场搜索 Custom Attachment location,安装并激活即可
2 手动安装
从 latest release 下载 ,
,放到
_posts/.obsidian/plugins/obsidian-custom-attachment-location/.
目录中,在 Obsidian 中启用插件。
按照下图配置该插件。
图中第一个 Location 是上传附件(粘贴图片到文章)时,自动创建一个目录,目录的名字设置为 ../${filename}
和当前文章同名,第二个图片格式可以随意,日期也随意。第四个 自动重命名附件文件夹 要开启,当我们从 Obsidian 修改文件名的时候,附件的目录可以自动同步修改,这就解决了 Hexo 中还需要手动改名的问题 (文章内的相对目录名也需要改)。
做到这一步,写博客时就可以随意的往文章内粘贴图片了,截图、网页复制的图片,本地的图片,随便往里面粘贴,都会自动将图片放到指定的目录中,这种顺畅的操作才令人舒心。
3. 目录和类别管理
我们不仅需要流畅的书写,还要方便的管理,通过插件 hexo-auto-category 可以支持创建多级目录存放博客文章,并且根据多级目录创建分层的类别信息,多级类别效果如下:
对应生成的类别结构
在 hexo-auto-category 插件中,作者只针对 post
类型的内容进行处理,不支持其他格式,而且没法配置支持其他类型,所以我使用的时候直接把代码复制修改了,如果你只需要处理 post
类型,通过命令 npm install hexo-auto-category --save
安装即可,如果你也想修改,可以参考下面代码修改:
'use strict';
var front = require('hexo-front-matter');
var fs = require('hexo-fs');
hexo.extend.filter.register('before_post_render', function(data) {
var log = this.log;
log.i("Auto Category, Title: %s, Layout: %s", data.title, data.layout);
//这里在原来基础上增加了page和gallery类型
if (['post','page','gallery'].indexOf(data.layout) === -1)
return data;
if (!this.config.render_drafts && data.source.startsWith("_drafts/"))
return data;
if (this.config.auto_category.enable) {
let postStr;
var tmpPost = front.parse(data.raw);
var categories = data.source.split('/');
var depth = this.config.auto_category.depth || categories.length-2;
if (depth==0) {
return data;
}
var newCategories = categories.slice(1, 1 + Math.min(depth, categories.length - 2));
if (tmpPost.categories) {
let postCategories = tmpPost.categories;
if (typeof(tmpPost.categories) === "object"){
postCategories = tmpPost.categories.join("_");
}
if (postCategories == newCategories.join("_")) return data;
}
tmpPost.categories = newCategories
if(this.config.auto_category.multiple)
tmpPost.categories = tmpPost.categories.map(category => [category]);
postStr = front.stringify(tmpPost);
postStr = '---\n' + postStr;
fs.writeFile(data.full_source, postStr, 'utf-8');
log.i("Generated: categories [%s] for post [%s]", tmpPost.categories, categories[categories.length-1]);
}
return data
}, 15);
- 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
我是基于 fluid 主题做的修改,直接将 fluid 主题的所有内容放在了 themes 文件夹,按照 fluid 的目录规范放在了 themes/fluid/scripts/filters 目录中。
这个插件需要在 _config.yml
中配置:
# Generate categories from directory-tree
# Dependencies: /xu-song/hexo-auto-category
# depth: the depth of directory-tree you want to generate, should > 0
auto_category:
enable: true
depth:
- 1
- 2
- 3
- 4
- 5
- 6
配置这个后就能用目录结构来管理博客文章。
4. 文章模板
除了上面的配置外,我还试了 hexo-abbrlink 插件,这个插件直接包含了上面的目录类别管理,我没有使用这个插件,但是使用了这里的短链接方式,短链接通过 Obsidian 模板的方式自动生成。
模板使用 Templater 插件,也是两种安装方式,参考前面的 Custom Attachment location。
我们在 _posts
下面创建一个 template
目录存放模板文件,为了避免模板被 hexo 当成文章处理,需要先配置 _config.yml
忽略该目录:
exclude:
- template/**/*
- 1
- 2
创建一个 模板,模板内容示例如下:
---
title: '<% %>'
description:
abbrlink: <%* date = ("YYYYMMDDhhmmss"); %><% .hash_8c_2(date) %>
layout: post
date: <% ("YYYY-MM-DD HH:mm:ss") %>
updated: <% ("YYYY-MM-DD HH:mm:ss") %>
banner_img: /cover/01/
index_img: /cover/01/
hide: false
archive: false
categories:
tags:
---
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
具体有哪些属性需要看你选择的主题,这里需要特别说明的是 abbrlink
短链接属性,这里会使用 Templater 模板调用函数生成一个短链接,如果你不需要随机值,还可以考虑直接用日期+时分秒生成一个字符串,只要唯一不冲突即可。
这里调用的 hash_8c_2
是一个自定义方法,在 template
下面创建 scripts 目录,添加 hash_8c_2.js 文件,内容如下:
/*
hash_8c_2.js
code by tree_fly,
2023-02-27
*/
function hash_8c_2(message) {
try {
let crypto = require('node:crypto');
var hash = crypto.createHash("md5").update(message).digest("hex");
return hash.substring(2, 10); //equal to 'cut -c 3-10'
} catch (err) {
return "";
}
}
module.exports = hash_8c_2;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
参考来源: /posts/
接下来配置 Templater 插件:
这里主要就是配置了两个路径,第一个 template 是模板路径,第二个 template/scripts
是脚本路径,配置脚本点下面的刷新就会出现可用的自定义方法。
当我们创建一篇新的博客时,按下图操作就可以选择模板插入到当前博客中:
插入内容如下:
由于想要使用短链接,使用 abbrlink 生成的值作为URL,还需要配置 _config.yml
:
permalink: ':layout/:'
- 1
我在地址中还增加了 :layout
部分,示例地址如下:
- /post/
- /gallery/
5. 总结
整个操作起来挺麻烦的,写到一半我都写不下去了,如果有人喜欢这种方式,或者喜欢我改造的这个博客主题,可以留言给我,我可以把主题以及整个博客整理出一个框架开源出来方便大家使用。直接基于现成环境写的时候,上面所有这些操作都是配置好的,你可以把重点放在内容创作上。
博客地址: /
大家还可以说说你们打开博客的速度怎么样,当我第一篇发出去后,首批打开博客的人说加载速度很慢,图片很多,而且都比较大,打开慢就避免不了。为了解决慢的问题,我后续采用了下面几种方式来加速访问:
- 文章内容的图片自动转换为 webp 格式,这种格式的压缩率很高,图片瘦身效果很好。
- 首页索引图自动生成webp格式的缩略图,变的更小,加载更快
- 给博客加多个域名,让资源从不同域名加载,增加并发,加快整体速度
上面这些优化方式都是通过插件实现的,实现的过程也不是一帆风顺,第一种想了两天才实现,第二个想了好几天才实现,最后一个简单,直接上手配合 Copilot 写,包含测试用了不到两个小时。后续会把这3个优化方式也写出来简单讲讲。