使用Obsidian写Hexo博客

时间:2024-10-30 15:44:33

非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. 总结

整个操作起来挺麻烦的,写到一半我都写不下去了,如果有人喜欢这种方式,或者喜欢我改造的这个博客主题,可以留言给我,我可以把主题以及整个博客整理出一个框架开源出来方便大家使用。直接基于现成环境写的时候,上面所有这些操作都是配置好的,你可以把重点放在内容创作上。

博客地址: /

大家还可以说说你们打开博客的速度怎么样,当我第一篇发出去后,首批打开博客的人说加载速度很慢,图片很多,而且都比较大,打开慢就避免不了。为了解决慢的问题,我后续采用了下面几种方式来加速访问:

  1. 文章内容的图片自动转换为 webp 格式,这种格式的压缩率很高,图片瘦身效果很好。
  2. 首页索引图自动生成webp格式的缩略图,变的更小,加载更快
  3. 给博客加多个域名,让资源从不同域名加载,增加并发,加快整体速度

上面这些优化方式都是通过插件实现的,实现的过程也不是一帆风顺,第一种想了两天才实现,第二个想了好几天才实现,最后一个简单,直接上手配合 Copilot 写,包含测试用了不到两个小时。后续会把这3个优化方式也写出来简单讲讲。