hexo建立个人博客指北

概要

本文用于简要阐释我个人关于使用hexo建个人博客的经验,和解释hexo的各种自定义功能,也可以说是我个人的备忘录。网上很多教程都是直接告诉你怎么做,这在建站时很方便,但如果你要自定义就要知道hexo是怎么自定义的,本文可以帮你对此有一些了解
在进入正文前,我需要补充一些其他东西

hexo的原理

网站分为静态和动态,简单地说,静态网站就是写好了不会改变的页面,可以利用js实现一些小的动态效果,但不会有后台服务,动态网站就是用户发送请求,后台处理后更新网站给用户反馈,大部分商业网站都是此类。
hexo搭建的博客属于典型的静态网站,因此很容易搭建和自定义。可以说,hexo就是根据你的设置和写作,用一定规则渲染出静态页面的一个工具

如何网上访问你的页面

一般来说网站搭建在服务器上,但对静态页面来说,如Github之类的网站后提供免费的托管功能,只要你建一个github账号名.github.io的公共仓库,把静态页面放进去,就可以托管页面,用这个域名访问它(由于众所周知的原因,墙内有时候访问不太稳定)

涉及的工具

linux

我个人推荐你用linux虚拟机来做这件事,一是linux的包管理工具让装各种框架和插件很方便,二是linux的轻量级可以让你如果要切换生产环境,直接导出一个最多10gb左右的镜像拷贝走,就能换到另一台电脑,保留所有装好的环境,三是如果你是cs学生或者有编程需要,linux都是你几乎必学的系统。
这个博客就搭在微软提供的wsl(windows上的linux子系统)上
wsl的教程看这个 linux的教程看这个

git

git和linux是同一个作者,是当下最流行的版本控制工具,如果我们要用github托管页面,也需要用git来推送页面
git也可以帮我们很方便地给你的博客做备份,推送到github的仓库,切换生产环境后把备份拉过来就能继续维护博客

markdown

markdown是一门轻量级标记性语言,很容易学习,被用于hexo渲染出html页面
网上教程很多,比如
如何优雅地使用 Markdown?

建站和自定义

建站

假设你有了一个linux系统,并且掌握了一些基本操作,那么建站教程看这个
【保姆级教程】含泪搭建hexo博客

主题选择

hexo的大部分页面渲染工作由主题决定,直观地说,主题决定你的博客外观
hexo主题列表
我建议新手选择一些比较流行的主题,比如next,butterfly,一般这些主题自定义比较方便,文档易读并且出了问题网上有解决方案

以next为例讲讲主题的自定义

next的简单设置这篇博客有教程
next的官方文档
hexo的大部分设置有两个yml文件控制,一个是根目录下的_config.yml,可以设置语言,作者名,网站名,网站链接等,还有一个是主题目录的_config.yml,设置主题自己的功能,next的评论,访问统计等等功能都在这里设置
主题的目录一般是根目录/node_modules/hexo-theme-主题名/,但也有主题的配置文件放在根目录的命名成_config.主题名.yml
关于部分主题功能的详解我会放在下文的主题使用说明

hexo的工作流程

如果想进一步的自定义,就需要了解hexo的大致原理

前端三件套

  • HTML(超文本标记语言)是一种用来描述网页内容的语言,它使用一系列的标签(tag)来定义网页中的元素,如标题,段落,图片,链接等。
  • CSS(层叠样式表)是一种用来控制网页外观的语言,它可以定义网页中元素的颜色,大小,位置,边框等属性。
  • JavaScript(简称JS)是一种用来实现网页交互的脚本语言,它可以在浏览器中运行,响应用户的操作,修改网页内容,发送和接收数据等。
    hexo目录内的public文件夹就放着最后生成的页面,其中,你看到的页面就是一个个html文件,样式和动态效果则引用js和css文件夹中的文件,hexo g生成和你在github托管的也就是这个文件夹下的文件

源文件

那么是什么文件会被推送到public文件夹呢?

  1. 根目录下的source文件夹,有下划线_打头的文件夹一般有特殊性质,如根目录下的_data存放一些自定义样式文件,_post则存放具体文章,这些文件夹不会直接放进public,除此以外的文件夹都会被放进public,但如果文件可以被渲染的话,会经过解析然后储存到 public 文件夹,否则会直接拷贝到 public 文件夹。
  2. 主题目录下的source文件夹,一般来说这些文件夹用来放js,css和主题自定义的一些图片,同样,有下划线开头的不会被直接放进public,其他文件夹下会被放进去

如何跳过渲染

在根目录下设置skip_render,以下设置让source的webstack目录全部跳过渲染

1
2
skip_render:
- webstack/**

写作

文章布局

hexo有三种文章布局,其中post是普通的博文,page是带文件夹的新页面,比如tags,categories,如果主题支持的话,你可以设置page被特别渲染成目录,标签之类的特色页面并放进菜单,draft是草稿,这种布局在建立时会被保存到 source/_drafts 文件夹,您可通过 publish 命令将草稿移动到 source/_posts 文件夹,默认不会被显示在页面中
你也可以禁用布局,根据 _config.ymldefault_layout 的设置,默认布局是 post 。当文章中的布局被禁用(layout: false),它将不会使用主题处理。然而,它仍然会被任何可用的渲染引擎渲染:如果一篇文章是用 Markdown 写的,并且安装了 Markdown 渲染引擎(比如默认的 hexo-renderer-marked),它将被渲染成HTML。

布局 路径
post source/_posts
page source
draft source/_drafts

文章标头

Front-matter 是文件最上方以 --- 分隔的区域,用于指定个别文件的变量,举例来说:
hexo用文章标头来识别文章,因此你可以不用命令行创建文章,把有标头的md文件放进_post就能发布博文了

1
2
3
4
5
6
7
---
title: 基于斯坦福cs106b的c++数据结构笔记
tags:
- 课程笔记
- c++
categories: 课程笔记
---
参数 描述 默认值
layout 布局 config.default_layout
title 标题 文章的文件名
date 建立日期 文件建立日期
updated 更新日期 文件更新日期
comments 开启文章的评论功能 true
tags 标签(不适用于分页)
categories 分类(不适用于分页)
permalink 覆盖文章的永久链接,永久链接应该以 /.html 结尾 null
excerpt 纯文本的页面摘要。使用 该插件 来格式化文本
disableNunjucks 启用时禁用 Nunjucks 标签 {{ }}/ {% %}标签插件 的渲染功能 错误的
lang 设置语言以覆盖 自动检测 继承自 _config.yml
published 文章是否发布 对于 _posts 下的文章为 true,对于 _draft 下的文章为 false

目录和标签

只有文章支持分类和标签,可以在 Front-matter 中设置。在其他系统中,分类和标签听起来很接近,但是在 Hexo 中两者有着明显的差别:分类具有顺序性和层次性,也就是说 Foo, Bar 不等于 Bar, Foo;而标签没有顺序和层次。
eg.如下的标头形成目录是(课程笔记/操作系统)

1
2
3
4
5
6
7
8
9
---
title: 基于恐龙书和苏大ppt的操作系统笔记
tags:
- 课程笔记
- 操作系统
categories:
- 课程笔记
- 操作系统
---

也可以并列

1
2
3
4
5
6
7
8
9
并列分类 
类别:
- [Linux]
- [工具]

并列+子分类
类别:
- [Linux, Hexo]
- [工具,PHP]

文章缩略

一般来说我们不会希望首页显示全文,而是开头的一小部分或者是摘要,摘要可以在标头加上取代缩略,而文章的缩略可以由主题决定,也可以用hexo自己的方式,比如next现在就不支持自动缩略,你只能自己在觉得差不多的地方加上

1
<!-- more -->

每个主题怎么决定缩略或者摘要基本也会在文档里写

主题说明

既然大部分渲染由主题决定,那么自定义往往也会取决于主题,以下是我本人用过的主题的一些经验

next

next是一款典型的黑白简约风主题,并且提供了丰富的自定义性,因此迪瑞克拉的主站就使用了自定义非常方便的next
next的文档比较易读,全部看一遍就知道设置里那些选项怎么用了
这里说说next的自定义
next的渲染由主题文件夹下"layout"目录中的njk文件控制(一些老版本是swig),你也可以使用next提供的自定义文件,去掉注释符号就可以去_data文件新建自定义文件来控制渲染
比如说你想在所有页面加个js特效,就可以在主题文件夹下的layout/_layout.njk文件新增一句

1
2
<script src="/js/jsname.js"></script>

以下是next提供的自定义文件接口,可以对网站各个位置自定义

1
2
3
4
5
6
7
8
9
10
11
12
custom_file_path:
  #head: source/_data/head.njk
  #header: source/_data/header.njk
  sidebar: source/_data/sidebar.njk
  #postMeta: source/_data/post-meta.njk
  #postBodyStart: source/_data/post-body-start.njk
  #postBodyEnd: source/_data/post-body-end.njk
  #footer: source/_data/footer.njk
  #bodyEnd: source/_data/body-end.njk
  #variable: source/_data/variables.styl
  #mixin: source/_data/mixins.styl
  style: source/_data/styles.styl

webstack

webstack主题基于github的一个开源项目,用来做一个导航页面,作为子站非常合适,自定义虽然没有next那么丰富,但作者慷慨地提供了一个随便插入html的head或者body的接口,可以使用html标签进行自定义,就在webstack的配置文件末尾
怎么做子站看下文的多主题
使用方法看github主页的文档

1
2
3
4
5
6
7
custom:
  head: |- # 以下内容插入到<head></head>标签内,可设置多行,注意每行开头至少四个空格
    <!-- 直接添加html内容即可 -->
    <!-- 可设置多行 -->
  body: |- # 以下内容插入到</body>标签之前,可设置多行,注意每行开头至少四个空格
    <!-- 直接添加html内容即可 -->
    <!-- 可设置多行 -->

icarus

伊卡洛斯也是个简约风的主题,特色是两列或者三列式的美观布局,但最让我中意的是它的赛博朋克风格,伊卡洛斯使用jsx定义渲染,因此自定义比较麻烦,可以自己导入js和css,但没有直接插入html标签的接口 使用文档 文档没说那些七七八八的窗口怎么关,但我亲测你不想要的直接在配置文件里删掉就行了 自定义js和css 顺便一提对md的渲染基本都会会直接把正文中的html标签放进最后生成的html文件,所以直接在文章里放html标签基本也能用,如果你想要一个效果只在文章页面出现可以试试,迪瑞克拉神龛的骇入文字特效就是此类

多主题

理论上讲,既然主题只是决定了渲染的方法,你自己可以调用主题的各种样式渲染实现 一个主题下渲染出另一个主题效果的页面,但这样做很麻烦,那么有没有更容易实现多主题的方法呢? 前文说了,source文件夹所有目录都会推送到public,我们可以利用这点把其他主题的网站推送到主站的source文件夹,然后在主站开一个菜单跳转到该子站对应目录的index实现子站用不同主题的功能 具体步骤如下

  1. 如之前的教程一样再建一个站,设置好想要的主题
  2. 根目录的设置这么改
1
2
3
url: 主站目录/子站目录名
index_generator:
path: '/子站目录名/'
  1. 主站子站各自加一个跳转子站,返回主站的菜单 比如next这么改
1
resourcemap: /webstack/ || fa fa-sitemap
  1. 如果你会写脚本,就写个子站生成网站后自动推送的练练手,不会或者嫌麻烦就拿我的改改
1
2
3
4
5
6
7
8
hexo clean

hexo g

rm -rf /home/thinkliving/hexoblog/source/webstack/*

cp -r /home/thinkliving/hexochild/public/* /home/thinkliving/hexoblog/source/webstack/

其他自定义

图标

大部分hexo主题使用fontawesome的图标,类似这种格式

1
fas fa-tools//s指solid图标

想自定义可以在css文件里定义图标再使用,比如next中是这样在styl里定义,不过不是所有主题都提供自定义css

1
2
3
4
5
6
7
8
9
10
.thanks {
background-image: url('/images/thanks.svg');
background-size: 1em 1em;
background-position: 0.05rem 0.2rem;
background-repeat: no-repeat;
height: 1rem;
width: 1rem;
}

thanks: /thanks/ || fa custom thanks

hexo s时自动刷新

1
2
npm install -g browser-sync
npm install hexo-browsersync --save

加密博客

[hexo-blog-encrypt](https://github.com/D0n9X1n/hexo-blog-encrypt/tree/master)

js动效

鼠标移动特效 这种js小特效很多,好奇的话自己去探索吧

黑夜模式

想在半夜刷博客,又被白色背景闪瞎眼?听起来你需要一个可以切换的黑夜模式
如何实现呢?你可能听说过darkmode.js等一键切换时的黑夜模式,这些脚本的原理似乎是给网站盖一层样式来覆盖原有内容,但用在hexo next上呢?你会发现很多地方覆盖不到,或者背景直接来了个吓人的反色
省去废话,最简单的方法就是css+js直接更改网站的样式,在hexo next里可以用以下基本轻松且轻量的实现(说的很好听,但缺点是能用的补集)

  1. 在next的设置文件里把style.styl , body-end.njk等配置文件开启,如果你没有建过的话,在source文件夹下的_data文件夹建立这些文件
  2. 覆盖部分css样式,在styles.styl加入:
1
2
3
4
5
6
7
8
9
10
11
12
:root {
--note-warning-bg-color: #fdf8ea
--note-info-bg-color: #eef7fa
}

.post-body .note.warning {
background: var(--note-warning-bg-color);
}

.post-body .note.info {
background: var(--note-info-bg-color);
}
  1. 在body-end.njk加入以下代码,但需要注意isLightMode对这个变量的判断需要改成你自己网站的'--content-bg-color'的值
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
<script>
function toggleMode() {
console.log("change!");
const root1 = document.documentElement;

// 检查当前 color-scheme
const isLightMode = getComputedStyle(root1).getPropertyValue('--content-bg-color').trim() === '#fff';

if (isLightMode) {
// 切换到暗模式
root1.style.setProperty('--content-bg-color', '#000');
root1.style.setProperty('--text-color', '#fff');
root1.style.setProperty('--highlight-background', '#444');
root1.style.setProperty('--highlight-foreground', '#bbb');
root1.style.setProperty('--btn-default-bg', '#777');
root1.style.setProperty('--menu-item-bg-color', '#777');
root1.style.setProperty('--note-warning-bg-color', '#777');
root1.style.setProperty('--note-info-bg-color', '#777');
root1.style.transition = 'all 0.5s ease';

}

else {
root1.style.setProperty('--content-bg-color', '#fff');
root1.style.setProperty('--text-color', '#111');
root1.style.setProperty('--highlight-background', '#eaeef3');
root1.style.setProperty('--highlight-foreground', '#00193a');
root1.style.setProperty('--btn-default-bg', '#fff');
root1.style.setProperty('--menu-item-bg-color', '#f5f5f5');
root1.style.setProperty('--note-warning-bg-color', '#fdf8ea');
root1.style.setProperty('--note-info-bg-color', '#eef7fa');
root1.style.transition = 'all 0.5s ease';
}
}
</script>

<button style="background: #868686;
width: 3rem;
height: 3rem;
position: fixed;
border-radius: 50%;
border: none;
right: unset;
bottom: 2rem;
left: 2rem;
cursor: pointer;
transition: all 0.5s ease;
display: flex;
justify-content: center;
align-items: center;" class="darkmode-toggle" role="checkbox" onclick="toggleMode()">🌓</button>
  1. enjoy