重建 Hexo 博客日志

重建 Hexo 博客日志

几百年前刚建立这个博客时几乎什么都不懂,胡乱作一气。尽管包管理稀烂,Bug 层出不穷,部署时一堆报错…… 但索性能运行起来。

最近把整个仓库推到 Github 做持续集成,数据也不那么容易遗失。刚开始看没问题,结果主题调用的资源全部变成相对路径了,一片报错。

剪不断,理还乱…… 烂摊不好收,就重新建一个

安装 Hexo

什么?您若想了解安装流程,还请移步至 Hexo 官网

  • Node.js 用 nvm 管理。

版本:

Shell
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
❯ nvm -v
1.1.10

❯ node -v
v12.22.12

❯ hexo version
hexo: 6.3.0
hexo-cli: 4.3.1
os: win32 10.0.22631
node: 12.22.12
v8: 7.8.279.23-node.57
uv: 1.40.0
zlib: 1.2.11
brotli: 1.0.9
ares: 1.18.1
modules: 72
nghttp2: 1.41.0
napi: 8
llhttp: 2.1.4
http_parser: 2.9.4
openssl: 1.1.1n
cldr: 37.0
icu: 67.1
tz: 2021a4
unicode: 13.0

更换渲染引擎

默认孬。即换,以免兼容问题。

hexo-renderer-markdown-it

卸载:

Shell
1
2
❯ npm un hexo-renderer-marked --save
好嘛,卸载 hexo-renderer-marked 中……

安装:

Shell
1
2
❯ npm i hexo-renderer-markdown-it --save
好嘛,安装 hexo-renderer-markdown-it 中……

配置:

_config.yml
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
+ # 以下是扩展设置
+
+ ## hexo-renderer-markdown-it https://github.com/hexojs/hexo-renderer-markdown-it
+ markdown:
+ preset: 'default'
+ render:
+ html: true # 启用页内 HTML
+ xhtmlOut: false # 是否完全兼容 XHTML
+ langPrefix: 'language-'
+ breaks: false # 换行变 <br>
+ linkify: false # 长得像链接的变 <a>
+ typographer: true # 能够替换常见的排版元素,如©、卷曲引号、破折号等
+ quotes: '“”‘’'
+ enable_rules:
+ disable_rules:
+ plugins:
+ - markdown-it-container
+ - markdown-it-footnote
+ - markdown-it-ins
+ anchors:
+ level: 2
+ collisionSuffix: ''
+ permalink: false
+ permalinkClass: 'header-anchor'
+ permalinkSide: 'left'
+ permalinkSymbol: '¶'
+ case: 0
+ separator: '-'
+ images:
+ lazyload: false
+ prepend_root: false
+ post_asset: false
+ inline: false # https://markdown-it.github.io/markdown-it/#MarkdownIt.renderInline

安装并启用 Icarus 主题

Shell
1
2
❯ npm install hexo-theme-icarus
好嘛,安装 hexo-theme-icarus 中……
_config.yml
1
2
3
4
5
# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
- theme: landscape
+ theme: icarus

设置评论系统

本文撰写时 Icarus 主题不支持 giscus 评论系统。只好手动添加到源码。

先随便设置,让界面不报错:

现在已支持 giscus 评论系统。在 giscus 官网设置好配置。

_config.icarus.yml
1
2
3
4
5
6
7
8
9
10
11
# Comment plugin configurations
# https://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Comment/
comment:
- type: disqus
- # Disqus shortname
- shortname: ''
+ type: giscus
+ repo: PJ-568/PJ-568.github.io
+ repoId: X_xxxxxxxxxx
+ categoryId: XXX_xxxxxxxxxxxxxxxx
+ lang: zh-CN

配置 RSS 订阅

hexo-generator-feed

安装:

Shell
1
2
3
4
❯ npm install hexo-generator-feed --save

+ hexo-generator-feed@3.0.0
added 1 package from 1 contributor in 2.848s

配置:

_config.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
+ ## hexo-generator-feed
+ feed:
+ enable: true
+ # type: atom
+ # path: atom.xml
+ type:
+ - atom
+ - rss2
+ path:
+ - atom.xml
+ - rss2.xml
+ limit: 20
+ hub:
+ content:
+ content_limit: 140
+ content_limit_delim: ' '
+ order_by: -date
+ icon: /images/PJ568.svg
+ autodiscovery: true
+ template:

配置自动翻译

不想为国际化而重写文章。因此,我集成 translate.js

规划

顶栏右侧生成 “翻译” 按钮。按下展开菜单以选择语言。

问题在于 translate.js 生成的是 <select> 元素。难以做到按下按钮打开 <select> 元素。

我可以将 <select> 元素设定成透明,用 z-index 使它覆盖在 “翻译” 按钮上层,这样点击按钮位置实际上点到的是 <select> 元素。(哈,我聪明)

调整样式

创建并写入:

source/css/override.css
1
+ .translateSelectLanguage{z-index:10;width:100%;height:100%;opacity:0;cursor:pointer;position:absolute;left:0}

设置翻译

创建并写入:

source/js/override.js
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// 使用 IIFE 包裹以避免全局变量污染
(function () {
// 初始化导航栏
function initNavBar() {
try {
const navbar = document.querySelector('.navbar-end');
var darkButton = document.createElement('a');
darkButton.id = 'dark_b';
darkButton.title = '更改显示模式';
darkButton.href = 'javascript:;';
darkButton.className = 'navbar-item';
darkButton.innerHTML = '<i class="fa fa-adjust"></i>';
var translateButton = document.createElement('a');
translateButton.id = 'translate';
translateButton.title = '翻译';
translateButton.className = 'navbar-item';
translateButton.innerHTML = '<i class="fa fa-language"></i>';
navbar.insertBefore(darkButton, navbar.children[0]);
navbar.insertBefore(translateButton, navbar.children[0]);
} catch (e) {
console.error('初始化导航栏出错:' + e);
}
}

// translate-js 翻译系统
//// 初始化翻译系统
function initTranslate() {
try {
translate.service.use('client.edge');
translate.listener.start();
translate.setAutoDiscriminateLocalLanguage();
translate.language.setUrlParamControl();
translate.ignore.class.push('notTranslate');
translate.nomenclature.append('chinese_simplified', 'english', `
刘甜=Liu Tian
主页=Home
知乎=Zhihu
友链=Links
爱发电=Create by love
送我杯咖啡=Buy me a tea
哈姆语言之书=Hamud Book
哈姆语=the language of Hamud
哈姆=Hamud
关于=About
`);
translate.execute();
} catch (e) {
console.error('翻译系统出错:' + e);
}
}

//// 手动触发翻译
function reTranslate() {
translate.execute();
}

//// 检查并提示翻译
function infoTranslate() {
try {
var currentLang = translate.language.getCurrent();
var originalLang = translate.language.getLocal();
if (currentLang !== originalLang) {
// 获取所有文章元素
var articleElements = document.querySelectorAll('.article');
articleElements.forEach(element => {
var langInfo = document.createElement('article');
langInfo.classList.add('message');
langInfo.classList.add('message-immersive');
langInfo.classList.add('is-primary');

var msgBody = document.createElement('div');
msgBody.classList.add('message-body');

var langIcon = document.createElement('i');
langIcon.classList.add('fas');
langIcon.classList.add('fa-globe-americas');
langIcon.classList.add('mr-2');

var switchButton = document.createElement('a');
switchButton.href = 'javascript:;';
switchButton.title = '切换到原语言';
switchButton.innerText = '切换到文章原本的语言';

msgBody.appendChild(langIcon);
msgBody.appendChild(switchButton);

langInfo.appendChild(msgBody);

element.insertBefore(langInfo, element.children[2]);

switchButton.addEventListener('click', function () {
translate.changeLanguage(originalLang);
});
});
reTranslate();
}
} catch (e) {
console.error('检查并提示翻译出错:' + e);
}
}

//// 刷新翻译
function refreshTranslate() {
try {
translate.selectLanguageTag.refreshRender();
} catch (e) {
console.error('刷新翻译出错:' + e);
}
}

// 初始化
function initialize() {
initNavBar(); //// 初始化导航栏
initTranslate(); //// 初始化页面翻译
}


// 触发器
//// 网页加载完毕后触发
window.addEventListener('DOMContentLoaded', () => initialize());
//// 翻译执行完成后触发
// translate.listener.renderTaskFinish = function (_task) {

// }
//// 监听 Pjax 完成后,重新加载
document.addEventListener("pjax:complete", function () {
initNavBar();
refreshTranslate();
})
})();

插入代码

引入设置

引入 translate.js 代码:

scripts/inject.js
1
2
3
4
5
6
7
8
+ hexo.extend.injector.register('head_end', () => {
+ return css('/css/override.css');
+ });
+ // 引入翻译
+ hexo.extend.injector.register('head_end', '<script src="//lib.baomitu.com/translate.js/3.7.2/translate.js"></script>');
+ hexo.extend.injector.register('body_end', () => {
+ return js('/js/override.js');
+ });

自定义页脚

_config.icarus.yml
1
2
3
footer:
# Copyright text
+ copyright: <a href="//icp.gov.moe/?keyword=20230568" target="_blank" rel="noopener">萌 ICP 备 20230568 号</a>&nbsp;&nbsp;未特殊声明文章默认遵循 CC BY 4.0 许可协议

压缩静态文件

Hexo-neat

安装:

Shell
1
2
3
4
❯ npm install hexo-neat --save

+ hexo-neat@1.0.9
added 17 packages from 14 contributors in 4.12s

配置:

_config.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
+ ## hexo-neat
+ neat_enable: true
+ neat_html:
+ enable: true
+ exclude:
+ - games/lib/**
+ neat_css:
+ enable: true
+ exclude:
+ - '*.min.css'
+ neat_js: # js 一模炸,别动
+ enable: false
+ mangle: true
+ output:
+ compress:
+ exclude:
+ - '*.min.js'

自动推送至搜索引擎

hexo-submit-urls-to-search-engine

具体请依据配置文档

安装

Shell
1
2
3
4
❯ npm install --save hexo-submit-urls-to-search-engine

+ hexo-submit-urls-to-search-engine@2.1.0
added 79 packages from 81 contributors in 9.513s

配置:

_config.yml
1
2
3
4
5
6
7
8
9
10
# Deployment
## Docs: https://hexo.io/docs/one-command-deployment
- deploy:
- type: ''
+ # deploy:
+ # type: ''
+ deploy:
+ - type: cjh_google_url_submitter
+ - type: cjh_bing_url_submitter
+ - type: cjh_baidu_url_submitter
_config.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
+ hexo_submit_urls_to_search_engine:
+ submit_condition: count #链接被提交的条件,可选值:count | period 现仅支持count
+ count: 10 # 提交最新的10个链接
+ period: 900 # 提交修改时间在 900 秒内的链接
+ google: 0 # 是否向Google提交,可选值:1 | 0(0:否;1:是)
+ bing: 1 # 是否向bing提交,可选值:1 | 0(0:否;1:是)
+ baidu: 1 # 是否向baidu提交,可选值:1 | 0(0:否;1:是)
+ txt_path: submit_urls.txt ## 文本文档名, 需要推送的链接会保存在此文本文档里
+ baidu_host: https://Username.github.io ## 在百度站长平台中注册的域名
+ baidu_token: 请按照文档说明获取 ## 请注意这是您的秘钥, 所以请不要把它直接发布在公众仓库里!
+ bing_host: https://Username.github.io ## 在bing站长平台中注册的域名
+ bing_token: 请按照文档说明获取 ## 请注意这是您的秘钥, 所以请不要把它直接发布在公众仓库里!
+ google_host: https://Username.github.io ## 在google站长平台中注册的域名
+ google_key_file: Project.json #存放google key的json文件,放于网站根目录(与hexo _config.yml文件位置相同),请不要把json文件内容直接发布在公众仓库里!
+ google_proxy: http://127.0.0.1:8080 # 向谷歌提交网址所使用的系统 http 代理,填 0 不使用
+ replace: 0 # 是否替换链接中的部分字符串,可选值:1 | 0(0:否;1:是)
+ find_what: http://Username.github.io/blog
+ replace_with: https://cjh0613.com

持续集成

.github/workflows/Deploy.yml.bak
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
52
53
name: 【部署】

on:
workflow_dispatch:
push:
paths:
- '**'
- '!LICENSE'
- '!.github\workflows\**'

jobs:
hexo-deployment:
runs-on: ubuntu-latest
env:
TZ: Asia/Shanghai

steps:
- name: Checkout source
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '14.17.0'

- name: Restore file modification time
run: |
git ls-files -z | while read -d '' path; do touch -d "$(git log -1 --format="@%ct" "$path")" "$path"; done

- name: Install dependencies & Generate static files
run: |
node -v
npm i -g hexo-cli
npm i
# cp -vrf override/* node_modules/
[ -d auth ] && [ "$(ls -A auth)" ] && cp -vrf auth/* source/ || echo "auth 为空或不存在"
hexo clean
hexo g
hexo d

- name: Generate the sitemap
id: sitemap
uses: cicirello/generate-sitemap@v1
with:
path-to-root: ./public
base-url-path: https://blog.pj568.sbs/

- name: 移动特定文件
run: |
cp -v ./README.md public/README.md
作者

PJ568

发布于

2023-09-23

更新于

2023-11-28

许可协议

评论