Hexo 捣鼓札记
Hexo 简介
Hexo 是一个快速、简洁且强大的静态博客框架,基于 Node.js 开发,允许用户使用 Markdown 语法 编写文章,并将其转换为 HTML 页面,部署后呈现为个人或企业的 web 站点。
建站
- 安装 Node.js:访问 Node.js 官网,下载并安装
- 安装 Hexo:在命令行中,通过 npm 命令安装 hexo
1
npm install -g hexo-cli
- 初始化 Hexo 站点:在命令行中,使用 hexo 命令创建一个博客
1
2
3hexo init blog
cd blog
npm install - 启动 Hexo 站点:使用 hexo 命令启动本地预览,通过 http://localhost:4000 即可访问
1
hexo server
- 新建文章:使用 hexo 命令创建一篇名为 article.md 的文章
1
hexo new post article
- 生成静态文件:使用 hexo 命令生成静态 html 文件
1
hexo generate
- 部署网站:
1
hexo deploy
Hexo 支持的各条指令和使用方法,请参考 Hexo 官网的 命令说明。
配置
当初始化站点执行成功后,进入站点目录,可以看到如下内容:
.
├── _config.yml # 网站配置信息
├── package.json # 程序使用的工具和库文件信息
├── scaffolds # 存放网站使用的模版文件
├── source # 存放用户资源,如文章、图片等
| ├── _drafts # 存放未发布的草稿
| └── _posts # 存放正式发布的博文
└── themes # 博客使用的主题
网站配置项都包含在_config.yml 文件中,各配置项的含义,请参考 Hexo 官网的 配置说明。
常见的个性化定义的配置项包括:
参数 | 含义 | 默认值 |
---|---|---|
title | 网站标题 | |
description | 网站描述。主要用于 SEO | |
keywords | 网站关键词 | |
author | 网站作者 | |
language | 网站语言。中国大陆使用zh-CN |
|
timezone | 网站时区。中国大陆使用Asia/Shanghai |
|
permalink | 文章永久链接格式。为了优化 SEO,建议缩短长度 | :year/:month/:day/:title/ |
theme | 使用的主题名称。为 false 表示禁用主题 | |
deploy | 部署环境配置。常见的有 Github |
Hexo 主题
对于前端零基础、审美也堪忧的人来说,从空白雕出一个漂亮的网页 UI,那是不可能的,好在 Hexo 提供了丰富的 主题。
通过预览找到心仪的主题,记住主题的名称,然后到 github 上用 hexo-theme-$name
搜索,即可找到主题对应的代码仓。为什么 Hexo 主题预览页不直接提供对应的 github 仓库的链接呢,令人费解 o(╯□╰)o。
关于主题挑选,从审美上来说,萝卜青菜,各有所爱;从可用性来说,建议选使用者还算多的,代码仓还有人维护的。不同的主题切换,还是需要一些适配成本的。
我选的tranquilpeak,用的人不算少,但是作者好像已经不怎么维护和更新了。导致有一些功能需要自己开发和改造,过程中免不了踩一些坑,这也是本篇博文诞生的主要原因。
后续改动都是基于 tranquilpeak 主题,其他主题不一定能拿去即用,解决方案仅供参考。
安装
根据 tranquilpeak仓库说明,tranquilpeak 的安装和启用包括以下步骤:
- 下载 最新版的 tranquilpeak
- 解压后,放到 Hexo 博客主目录下
themes
文件夹中 - 修改 Hexo 博客主目录下
_config.yml
文件中theme
参数,设置为tranquilpeak
- 进入 Hexo 博客主目录下
themes\tranquilpeak
文件夹中,执行命令:1
npm install && npm run prod
配置
在themes\tranquilpeak
文件夹中也有一个 _config.yml
,这个文件中的配置项会覆盖 Hexo 博客主目录下_config.yml
的同名配置项。
tranquilpeak 主题的配置方法参考 仓库说明。
本博客站点设置的一些 tranquilpeak 主题配置如下:
配置项 | 含义 | 取值 | 说明 |
---|---|---|---|
location | 位置信息 | 中国 | 中国 |
picture | 个人头像 | photo.jpg | 位于source\assets\images |
github | github 用户名 | ||
sidebar_behavior | 侧边栏的呈现 | 2 | 有 1-6 种方式可以选 |
cover_image | 主题的背景图 | cover.png | 位于source\assets\images |
改造
1. 添加 mermaid 支持
mermaid 是一款使用文本来绘制图表的工具,可以与 markdown 集成,使用标记语言完成流程图、序列图、甘特图等图表绘制。
tranquilpeak 主题不支持 mermaid 渲染,需要自己改造。
- 安装插件
1
npm install hexo-filter-mermaid-diagrams
- 修改配置文件:在
themes/tranquilpeak/_config.yml
中添加如下内容,表示启用 mermaid1
2
3
4
5
6# Mermaid (markdwon to flow chart, seq chart, class chart ...)
mermaid:
enable: true
version: 9.0.0
# Available themes: default | dark | forest | neutral
theme: default - 修改 script.ejs 文件:在
themes/tranquilpeak/layout/_partial/script.ejs
末尾添加如下内容,完成 mermaid 初始化1
2
3
4
5
6
7
8
9
10
11
12<% if (theme.mermaid.enable) { %>
<script src='https://unpkg.com/mermaid@<%= theme.mermaid.version %>/dist/mermaid.min.js'></script>
<script type="text/javascript">
$(document).ready(function() {
var mermaid_config = {
startOnLoad: true,
theme: '<%- theme.mermaid.theme %>'
}
mermaid.initialize(mermaid_config);
});
</script>
<% } %> - 修改_base.scss 文件:在
themes/tranquilpeak/source/_css/base/_base.scss
中,添加如下内容,设置 mermaid 图片样式,避免图片前后出现大片空白的情况。注意设置完后需要执行npm run prod
重新构建主题,才能使得修改生效。1
2
3
4pre.mermaid > svg {
width: 100%;
height: 100%;
}
2. 添加目录导航侧边栏
对于长文浏览来说,目录导航能有效提高阅读体验。tranquilpeak 主题自带的 toc 不好用,生成的目录默认都位于文章最开头,对于长文不够友好。
tranquilpeak 主题支持多种屏幕大小,以及自定义的窗口样式。tocbot 作为外来者,适配窗口样式有点麻烦。我这个前端小白折腾了好久,终于让 tranquilpeak 勉强兼容了 tocbot,大致步骤如下:
- 安装 tocbot 插件:tocbot是一款自动根据标题构建目录的工具
1
npm install tocbot --save
- 修改配置文件:在
themes/tranquilpeak/_config.yml
中添加如下内容,表示启用 tocbot1
2
3
4
5
6
7
8# add toc in post
tocbot:
enable: true
tocSelector: '#post-toc'
contentSelector: '.post-content'
headings:
- 'h2'
- 'h3' - 修改 script.ejs 文件:在
themes/tranquilpeak/layout/_partial/script.ejs
末尾添加如下内容,完成 tocbot 初始化1
2
3
4
5
6
7
8
9
10
11
12
13
14<% if (theme.tocbot.enable) { %>
<script src="https://cdn.jsdelivr.net/npm/tocbot@4.25.0/dist/tocbot.min.js"></script>
<script type="text/javascript">
tocbot.init({
tocSelector: '<%- theme.tocbot.tocSelector %>', // 目录容器的 ID 或 class
contentSelector: '<%- theme.tocbot.contentSelector %>', // 内容容器的 ID 或 class
headingSelector: '<%- theme.tocbot.headings %>', // 包含在目录中的标题级别
collapseDepth: 3,
scrollSmooth: true,
activeClass: 'active',
orderedList: false
});
</script>
<% } %> - 修改 layout.ejs 文件:在
themes/tranquilpeak/layout/layout.ejs
中<%- body %>
之前添加如下内容,在页面上添加 toc 空间1
<%- partial('_partial/toc', {post: page}) %>
- 增加 toc.ejs 文件:在
themes/tranquilpeak/layout/_partial/
目录下新建 toc.ejs 文件,实现对 toc 的样式控制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<% if (theme.tocbot.enable) { %>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.25.0/tocbot.css">
<style>
#post-toc {
position: fixed ;
top: 80px;
padding: 10px;
z-index: 100;
background-color: rgba(255,255,255,0);
transform: translateX(0);
right: 3%;
width: 220px;
height: auto;
padding-top: 10px;
padding-bottom: 10px;
}
</style>
<script>
var tocWidth = 220; // TOC 的固定宽度
var tocPadding = 10; // TOC 的内边距,这里假设是两边各 10px,总和为 20px
var tocRight = 0.03; // TOC 的右边框距离屏幕右边的距离相对屏幕宽度的占比
// 检查窗口宽度并调整 TOC 显示
function adjustToc() {
var toc = document.getElementById('post-toc');
var screenWidth = window.innerWidth || document.documentElement.clientWidth;
var contentWrap = document.querySelector('div.post-content.markdown div.main-content-wrap');
if (contentWrap) {
var contentWidth = contentWrap.offsetWidth;
// 计算 contentWrap 的宽度加上 TOC 的宽度和内边距
var totalWidth = Math.round((contentWidth + tocWidth * 2 + tocPadding * 4) / (1 - tocRight * 2));
if (totalWidth >= screenWidth) {
toc.style.display = 'none'; // 如果总宽度大于或等于屏幕宽度,不显示 TOC
} else {
toc.style.display = 'block'; // 否则,显示 TOC
}
} else {
toc.style.display = 'none'; // 如果无法获取 contentWrap 的宽度,不显示 TOC
}
}
// 监听窗口大小变化事件
window.addEventListener('resize', adjustToc);
// 页面加载完毕时调用 adjustToc
document.addEventListener('DOMContentLoaded', adjustToc);
</script>
<div id="post-toc" class="toc" style="display: none;"></div> <!-- 初始化时隐藏 -->
<% } %>