一个计算机技术爱好者与学习者

0%

好好学Hexo:Hexo更换主题为Next

1. 前言

使用Yilia主题很久了,自己也进行了很多个性化的定制。今日始,决定把博客主题换成更加炫酷强大的Next,本文记录一下替换过程。

2. 下载主题

1、进入hexo/themes目录下,克隆next主题
git clone https://github.com/voidking/hexo-theme-next.git next

2、编辑hexo/_config.yml

1
theme: next

3. 个性化

3.1. 风格

Next主题支持多种风格,默认使用Muse风格。

这里切换成自己更喜欢的Pisces风格,编辑next/_config.yml

1
scheme: Gemini

3.2. 导航

编辑next/_config.yml,启用about、tags、categories、archives。

1
2
3
4
5
6
menu:
home: / || home
about: /about/ || user
tags: /tags/ || tags
categories: /categories/ || th
archives: /archives/ || archive

3.3. tags

原Yilia主题中,是没有tags页面的,因此需要创建。
1、创建tags页面
hexo new page tags

2、编辑tags/index.md

1
2
3
4
5
6
---
title: tags
type: "tags"
layout: "tags"
comments: false
---

3.4. 头像和签名

百年老店,需要logo。
1、把avatar.jpg放入next/source/images目录

2、编辑next/_config.yml,启用avatar

1
2
3
4
5
6
7
8
# Sidebar Avatar
avatar:
# Replace the default image and set the url here.
url: /images/avatar.jpg
# If true, the avatar will be dispalyed in circle.
rounded: false
# If true, the avatar will be rotated with the cursor.
rotated: false

不过,黑白主题配这个头像,有种搞绿化的感觉,哈哈。

3、编辑hexo/_config.yml,修改签名

1
2
3
4
5
6
7
# Site
title: VoidKing
subtitle: 好好学习,天天向上!
description: 学而不思则罔,思而不学则殆!
author: VoidKing
language: zh-CN
timezone:

3.5. favicon

1、把favicon.png放入next/source/images目录

2、编辑next/_config.yml,配置favicon

1
2
3
favicon:
small: /images/favicon.png
medium: /images/favicon.png

3.6. scrollpercent

在阅读文章过程中,scroll to top按钮显示当前滚动的百分比。

1
2
3
4
5
6
back2top:
enable: true
# Back to top in sidebar.
sidebar: false
# Scroll percent label in b2t button.
scrollpercent: true

3.7. 社交链接

编辑next/_config.yml,配置社交链接

1
2
3
4
5
6
7
8
9
10
11
12
# Social Links
social:
E-Mail: mailto:voidking@qq.com || envelope
GitHub: https://github.com/voidking || github
Weibo: http://weibo.com/voidking || weibo
Twitter: https://twitter.com/voidking_com || twitter

# `Follow me on GitHub` banner in the top-right corner.
github_banner:
enable: true
permalink: https://github.com/voidking
title: Follow me on GitHub

3.8. 关闭更新时间

编辑next/_config.yml,关闭文章的更新时间。

1
2
3
4
5
6
7
8
# Post meta display settings
post_meta:
item_text: true
created_at: true
updated_at:
enable: false
another_day: false
categories: true

4. 功能强化

4.1. 评论

原Yilia主题的评论插件是自己添加的livere,而Next主题支持livere。

编辑next/_config.yml,启用livere

1
livere_uid: MTAyMC8zODU3Mi8xNTEwMA==

4.2. 分享

1、编辑next/_config.yml,添加needmoreshare2分享

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
needmoreshare2:
enable: true
postbottom:
enable: true
options:
iconStyle: box
boxForm: horizontal
position: bottomCenter
networks: Weibo,Wechat,Douban,QQZone,Twitter,Facebook
float:
enable: true
options:
iconStyle: box
boxForm: horizontal
position: topRight
networks: Weibo,Wechat,Douban,QQZone,Twitter,Facebook

2、修复微信分享bug
needmoreshare2有一个bug,微信分享不能用,显示loading wechat image
编辑next/source/lib/needsharebutton/needsharebutton.js,如下修改:

1
2
# var imgSrc = "https://api.qinco.me/api/qr?size=400&content=" + encodeURIComponent(myoptions.url);
var imgSrc = "http://api.qrserver.com/v1/create-qr-code/?size=150x150&data=" + encodeURIComponent(myoptions.url);

4.3. 搜索

1、hexo目录下,安装搜索插件
npm install hexo-generator-searchdb --save

2、编辑hexo/_config.yml,添加

1
2
3
4
5
6
# local search
search:
path: search.xml
field: post
format: html
limit: 10000

3、编辑next/_config.yml,启用搜索功能

1
2
3
4
5
6
7
8
9
10
11
12
# Local Search
local_search:
enable: true
# If auto, trigger search by changing input.
# If manual, trigger search by pressing enter key or search button.
trigger: auto
# Show top n results per article, show all results by setting to -1
top_n_per_article: 1
# Unescape html strings to the readable one.
unescape: false
# Preload the search data when the page loads.
preload: false

4.4. 阅读量统计

1、编辑next/_config.yml,启用不蒜子统计

1
2
3
4
5
6
7
8
busuanzi_count:
enable: true
total_visitors: true
total_visitors_icon: user
total_views: true
total_views_icon: eye
post_views: true
post_views_icon: eye

2、修复404问题
不蒜子的原有js地址已经过期,因此插件需要修改。
编辑next/layout/_third-party/analytics/busuanzi-counter.swig,如下修改

1
2
<!-- <script async src="https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script> -->
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>

4.5. 文章置顶

1、安装支持置顶的插件

1
2
npm uninstall hexo-generator-index --save
npm install hexo-generator-index-pin-top --save

2、next主题配置支持显示置顶
编辑文件next/layout/_macro/post.swig<div class="post-meta">中添加:

1
2
3
4
5
{% if post.top %}
<i class="fa fa-thumb-tack"></i>
<font color="RED">置顶</font>
<span class="post-meta-divider">|</span>
{% endif %}

3、需要置顶的文章头部添加top字段

1
top: true

4.6. seo

1、编辑next/_config.yml,修改keywords

1
keywords: "VoidKing, Hankin, 好好学习的好, 郝锦"

2、启用seo优化

1
2
3
canonical: true
seo: true
index_with_subtitle: true

3、启用百度统计

1
baidu_analytics: b759ac2a7fa45129e3ef060bf68259f0

4.7. MathJax

编辑next/_config.yml,启用mathjax。这里指定某些页面启用mathjax,而不是全局。

1
2
3
4
5
6
7
8
9
10
# Math Formulas Render Support
math:
per_page: true
mathjax:
enable: true
mhchem: false

katex:
enable: false
copy_tex: false

4.8. 背景动画

编辑next/_config.yml,启用背景动画

1
2
3
4
5
6
7
8
# Canvas-nest
canvas_nest:
enable: true
onmobile: true # Display on mobile or not
color: "0,0,255" # RGB values, use `,` to separate
opacity: 0.5 # The opacity of line: 0~1
zIndex: -1 # z-index property of the background
count: 99 # The number of lines

4.9. 烟火动画

1、在next/source/js/src目录下新建fireworks.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
"use strict";
function updateCoords(e) {
pointerX = (e.clientX || e.touches[0].clientX) - canvasEl.getBoundingClientRect().left,
pointerY = e.clientY || e.touches[0].clientY - canvasEl.getBoundingClientRect().top
}
function setParticuleDirection(e) {
var t = anime.random(0, 360) * Math.PI / 180,
a = anime.random(50, 180),
n = [ - 1, 1][anime.random(0, 1)] * a;
return {
x: e.x + n * Math.cos(t),
y: e.y + n * Math.sin(t)
}
}
function createParticule(e, t) {
var a = {};
return a.x = e,
a.y = t,
a.color = colors[anime.random(0, colors.length - 1)],
a.radius = anime.random(16, 32),
a.endPos = setParticuleDirection(a),
a.draw = function() {
ctx.beginPath(),
ctx.arc(a.x, a.y, a.radius, 0, 2 * Math.PI, !0),
ctx.fillStyle = a.color,
ctx.fill()
},
a
}
function createCircle(e, t) {
var a = {};
return a.x = e,
a.y = t,
a.color = "#F00",
a.radius = 0.1,
a.alpha = 0.5,
a.lineWidth = 6,
a.draw = function() {
ctx.globalAlpha = a.alpha,
ctx.beginPath(),
ctx.arc(a.x, a.y, a.radius, 0, 2 * Math.PI, !0),
ctx.lineWidth = a.lineWidth,
ctx.strokeStyle = a.color,
ctx.stroke(),
ctx.globalAlpha = 1
},
a
}
function renderParticule(e) {
for (var t = 0; t < e.animatables.length; t++) {
e.animatables[t].target.draw()
}
}
function animateParticules(e, t) {
for (var a = createCircle(e, t), n = [], i = 0; i < numberOfParticules; i++) {
n.push(createParticule(e, t))
}
anime.timeline().add({
targets: n,
x: function(e) {
return e.endPos.x
},
y: function(e) {
return e.endPos.y
},
radius: 0.1,
duration: anime.random(1200, 1800),
easing: "easeOutExpo",
update: renderParticule
}).add({
targets: a,
radius: anime.random(80, 160),
lineWidth: 0,
alpha: {
value: 0,
easing: "linear",
duration: anime.random(600, 800)
},
duration: anime.random(1200, 1800),
easing: "easeOutExpo",
update: renderParticule,
offset: 0
})
}
function debounce(e, t) {
var a;
return function() {
var n = this,
i = arguments;
clearTimeout(a),
a = setTimeout(function() {
e.apply(n, i)
},
t)
}
}
var canvasEl = document.querySelector(".fireworks");
if (canvasEl) {
var ctx = canvasEl.getContext("2d"),
numberOfParticules = 30,
pointerX = 0,
pointerY = 0,
tap = "mousedown",
colors = ["#FF1461", "#18FF92", "#5A87FF", "#FBF38C"],
setCanvasSize = debounce(function() {
canvasEl.width = 2 * window.innerWidth,
canvasEl.height = 2 * window.innerHeight,
canvasEl.style.width = window.innerWidth + "px",
canvasEl.style.height = window.innerHeight + "px",
canvasEl.getContext("2d").scale(2, 2)
},
500),
render = anime({
duration: 1 / 0,
update: function() {
ctx.clearRect(0, 0, canvasEl.width, canvasEl.height)
}
});
document.addEventListener(tap,
function(e) {
"sidebar" !== e.target.id && "toggle-sidebar" !== e.target.id && "A" !== e.target.nodeName && "IMG" !== e.target.nodeName && (render.play(), updateCoords(e), animateParticules(pointerX, pointerY))
},
!1),
setCanvasSize(),
window.addEventListener("resize", setCanvasSize, !1)
}
"use strict";
function updateCoords(e) {
pointerX = (e.clientX || e.touches[0].clientX) - canvasEl.getBoundingClientRect().left,
pointerY = e.clientY || e.touches[0].clientY - canvasEl.getBoundingClientRect().top
}
function setParticuleDirection(e) {
var t = anime.random(0, 360) * Math.PI / 180,
a = anime.random(50, 180),
n = [ - 1, 1][anime.random(0, 1)] * a;
return {
x: e.x + n * Math.cos(t),
y: e.y + n * Math.sin(t)
}
}
function createParticule(e, t) {
var a = {};
return a.x = e,
a.y = t,
a.color = colors[anime.random(0, colors.length - 1)],
a.radius = anime.random(16, 32),
a.endPos = setParticuleDirection(a),
a.draw = function() {
ctx.beginPath(),
ctx.arc(a.x, a.y, a.radius, 0, 2 * Math.PI, !0),
ctx.fillStyle = a.color,
ctx.fill()
},
a
}
function createCircle(e, t) {
var a = {};
return a.x = e,
a.y = t,
a.color = "#F00",
a.radius = 0.1,
a.alpha = 0.5,
a.lineWidth = 6,
a.draw = function() {
ctx.globalAlpha = a.alpha,
ctx.beginPath(),
ctx.arc(a.x, a.y, a.radius, 0, 2 * Math.PI, !0),
ctx.lineWidth = a.lineWidth,
ctx.strokeStyle = a.color,
ctx.stroke(),
ctx.globalAlpha = 1
},
a
}
function renderParticule(e) {
for (var t = 0; t < e.animatables.length; t++) {
e.animatables[t].target.draw()
}
}
function animateParticules(e, t) {
for (var a = createCircle(e, t), n = [], i = 0; i < numberOfParticules; i++) {
n.push(createParticule(e, t))
}
anime.timeline().add({
targets: n,
x: function(e) {
return e.endPos.x
},
y: function(e) {
return e.endPos.y
},
radius: 0.1,
duration: anime.random(1200, 1800),
easing: "easeOutExpo",
update: renderParticule
}).add({
targets: a,
radius: anime.random(80, 160),
lineWidth: 0,
alpha: {
value: 0,
easing: "linear",
duration: anime.random(600, 800)
},
duration: anime.random(1200, 1800),
easing: "easeOutExpo",
update: renderParticule,
offset: 0
})
}
function debounce(e, t) {
var a;
return function() {
var n = this,
i = arguments;
clearTimeout(a),
a = setTimeout(function() {
e.apply(n, i)
},
t)
}
}
var canvasEl = document.querySelector(".fireworks");
if (canvasEl) {
var ctx = canvasEl.getContext("2d"),
numberOfParticules = 30,
pointerX = 0,
pointerY = 0,
tap = "mousedown",
colors = ["#FF1461", "#18FF92", "#5A87FF", "#FBF38C"],
setCanvasSize = debounce(function() {
canvasEl.width = 2 * window.innerWidth,
canvasEl.height = 2 * window.innerHeight,
canvasEl.style.width = window.innerWidth + "px",
canvasEl.style.height = window.innerHeight + "px",
canvasEl.getContext("2d").scale(2, 2)
},
500),
render = anime({
duration: 1 / 0,
update: function() {
ctx.clearRect(0, 0, canvasEl.width, canvasEl.height)
}
});
document.addEventListener(tap,
function(e) {
"sidebar" !== e.target.id && "toggle-sidebar" !== e.target.id && "A" !== e.target.nodeName && "IMG" !== e.target.nodeName && (render.play(), updateCoords(e), animateParticules(pointerX, pointerY))
},
!1),
setCanvasSize(),
window.addEventListener("resize", setCanvasSize, !1)
};

2、添加next/layout/_third-party/fireworks.swig,内容如下:

1
2
3
4
5
{% if theme.fireworks %}
<canvas class="fireworks" style="position: fixed;left: 0;top: 0;z-index: 1; pointer-events: none;" ></canvas>
<script type="text/javascript" src="//cdn.bootcss.com/animejs/2.2.0/anime.min.js"></script>
<script type="text/javascript" src="/js/src/fireworks.js"></script>
{% endif %}

3、编辑next/layout/_layout.swig,在</body>上面添加:

1
{% include '_third-party/fireworks.swig' %}

4、编辑next/_config.yml,添加并启用firework

1
2
# Fireworks
fireworks: true

5. 后记

至此,完成了Hexo主题从Yilia到Next的替换。进行了一些个性化设置,并且应用了Next的很多新特性。更多关于Next主题的内容,需要时再去学习使用。

6. 书签

theme-next/hexo-theme-next

Next

iissnan/hexo-theme-next

IIssNan’s Notes

Elegant Theme for Hexo

  • 本文作者: 好好学习的郝
  • 原文链接: https://www.voidking.com/dev-hexo-theme-next/
  • 版权声明: 本文采用 BY-NC-SA 许可协议,转载请注明出处!源站会即时更新知识点并修正错误,欢迎访问~
  • 微信公众号同步更新,欢迎关注~