Hello World

行走即是圆梦,回望亦是前行。

0%

Hexo博客的NexT主题美化和功能增强(一)

前言

这里简单记录下Hexo博客的NexT主题美化和功能增强

环境版本说明

Hexo: v4.2.1
NexT: v8.0.0_rc.3

安装NexT主题

NexT主题下载
下载完成后,解压至themes/next目录下,或者直接拉取Next主题的Github仓库源码

1
$ git clone https://github.com/theme-next/hexo-theme-next.git themes/next

将站点目录下_config.yml配置中theme的由landscape修改为next

_config.yml
1
2
3
4
5
# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
- theme: landscape
+ theme: next

添加数学公式渲染

这里我自己卸载hexo-renderer-marked和安装hexo-renderer-pandoc插件时,出现无法卸载和安装包错等问题,暂时先使用原有的hexo-renderer-marked渲染器,后续出现无法渲染的问题再更换插件。
themes/next/_config.yml中修改math相关参数,并选择mathjax作为渲染引擎

themes/next/_config.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
math:
# Default (true) will load mathjax / katex script on demand.
# That is it only render those page which has `mathjax: true` in Front-matter.
# If you set it to false, it will load mathjax / katex srcipt EVERY PAGE.
per_page: true

# hexo-renderer-pandoc (or hexo-renderer-kramed) required for full MathJax support.
mathjax:
- enable: false
+ enable: true
# See: https://mhchem.github.io/MathJax-mhchem/
- mhchem: false
+ mhchem: true
# See: https://mhchem.github.io/MathJax-mhchem/

per_page默认(true)的行为是只对Front Matter中含有mathjax: true的文章进行数学公式渲染,如果不含有mathjax: true或者设置mathjax: false,那么将不会对文章进行数学公式渲染。例如:

1
2
3
4
5
6
<!-- 这篇文章会渲染数学公式 -->
---
title: 'Will Render Math'
mathjax: true
---
....
1
2
3
4
5
6
<!-- 这篇文章不会渲染数学公式 -->
---
title: 'Not Render Math'
mathjax: false
---
....
1
2
3
4
5
<!-- 这篇文章也不会渲染数学公式 -->
---
title: 'Not Render Math Either'
---
....

公式需要使用$包含,使用$$包含可使公式居中显示:

$y = ax^2 + b + 2^{10}$

$$ e = mc^2 \tag{e}\label{eq1}$$

$$\begin{equation}
\begin{aligned}
a &= b + c \
&= d + e + f + g \
&= h + i
\end{aligned}
\end{equation}\label{eq2}$$

$$\begin{align}
-4 + 5x &= 2+y \nonumber \
w+2 &= -1+w \
ab &= cb
\end{align}$$

$$x+1\over\sqrt{1-x^2} \tag{i}\label{eq_tag}$$

著名的质能方程$\eqref{eq1}$由爱因斯坦提出 …

添加网站运行时长

添加网站运行时长修改如下:

themes/next/_config.yml
1
2
3
4
5
6
7
8
9
footer:
...
# site running time
running_time:
enable: true
# create time of your site
create: 20191231
# color of number
color: "#1890ff"

如果themes/next/layout/layout/_custom/custom.njk(7.x文件后缀为.swig)不存在,需按照对应路径创建,然后在_layout.njk中添加包含:

themes/next/layout/_layout.njk
1
2
3
4
5
  {% include '_third-party/math/index.njk' %}
{% include '_third-party/quicklink.njk' %}
+ {% include '_custom/custom.njk' %}

{{- next_inject('bodyEnd') }}

custom.njk中添加如下代码:(这里实际配置时我个人选择将换行删除,使代码混淆成一行)

themes/next/layout/_custom/custom.njk
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
{# 网站运行时间统计 #}
{%- if theme.footer.running_time.enable %}
<script src="https://cdn.jsdelivr.net/npm/moment@2.22.2/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/moment-precise-range-plugin@1.3.0/moment-precise-range.min.js"></script>
<script>
// 实现高位自动补0,num传入的数字,n需要的字符长度
function PrefixInteger(num, n = 2) {
return (Array(n).join(0) + num).slice(-n);
}
function GetRunningTime() {
var timesDiff = moment.preciseDiff(moment(), moment({{ theme.footer.running_time.create }}, "YYYYMMDD"), true);
var strText = "";
strText += " " + PrefixInteger(timesDiff.years).toString() + " 年";
strText += " " + PrefixInteger(timesDiff.months).toString() + " 月";
strText += " " + PrefixInteger(timesDiff.days).toString() + " 天";
strText += " " + PrefixInteger(timesDiff.hours).toString() + " 时";
strText += " " + PrefixInteger(timesDiff.minutes).toString() + " 分";
strText += " " + PrefixInteger(timesDiff.seconds).toString() + " 秒";

strText = strText.replace(/\d+/g, '<span style="color:{{ theme.footer.running_time.color }}">$&</span>');
element.innerHTML = "本站已安全运行" + strText;
}
var element = document.createElement("div");
// 插入到theme(主题)节点后
// var select = document.querySelector(".theme-info");
// document.querySelector(".footer-inner").insertBefore(element, select.nextSibling);

// 插入到最后一个节点后
document.querySelector(".footer-inner").appendChild(element);
GetRunningTime();
setInterval("GetRunningTime()", 1000);
</script>
{%- endif %}

代码块进阶用法

可以通过为代码块附加参数的形式为其添加更丰富的信息提示,效果如下:

Hello world链接地址
1
console.log("Hello World!");

代码块进阶语法规则:

1
2
3
```[language] [title] [url] [link text]
console.log("Hello World!");
```

其中,各参数意义如下:

  1. langugae:语言名称,引导渲染引擎正确解析并高亮显示关键字
  2. title:代码块标题,将会显示在左上角
  3. url:链接地址,如果没有指定link text则会在右上角显示link
  4. link text:链接名称,指定url后有效,将会显示在右上角

url必须为有效链接地址才会以链接的形式显示在右上角,否则将作为标题显示在左上角。以url为分界,左侧除了第一个单词会被解析为language,其他所有单词都会被解析为title,而右侧的所有单词都会被解析为link text。

如果不想填写title,可以在language和url之间添加至少三个空格。
可以在主题配置文件_config.yml中设置highlight.auto_detect: true来开启自动语言检测高亮。

如果设置语言为diff,可以在代码前添加+-来使用如上所示的高亮增删行提示效果,在展示代码改动痕迹时比较实用,和github上的diff功能类似。效果如下:

1
2
3
4
5
6
highlight:
enable: true
line_number: false
- auto_detect: false
+ auto_detect: true
tab_replace:

Markdown表格美化

如果themes\next\source\css\_custom\custom.styl不存在,需按照对应路径创建,然后在main.styl中添加包含:

themes/next/source/css/main.styl
1
2
3
4
5
6
// Custom Layer
// --------------------------------------------------
for $inject_style in hexo-config('injects.style')
@import $inject_style;

+ @import "_custom/custom.styl";

custom.styl中添加如下代码:

themes\next\source\css\_custom\custom.styl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Custom styles.

table th {
white-space: nowrap; // 表格表头单元格内容不换行
// text-align: center !important; // 表格表头内容居中,加上!important避免被Markdown样式覆盖
}

table td {
// text-align: center !important; //表格单元格内容不换行,加上!important避免被Markdown样式覆盖
}

table td:nth-child(1) {
white-space: nowrap; // 表格第一列单元格内容不换行
}

markdown语法:---:表格内容居中,NexT(v7.7.0v7.8.0)主题不生效,所以使用html语法实现左中右对齐方式:
注:v7.7.0升级到v8.0.0后,:---:语法效果显示正常。

语法效果
<p align="left">左对齐</p>

左对齐

<p align="center">居中对齐</p>

居中对齐

<p align="right">右对齐</p>

右对齐

使用style实现单元格宽度,但是会对这个界面的表格生效:

姓名性别年龄
张三10
李四12

代码块收起与展开

实现代码折叠

1
2
3
4
5
6
<details>
<summary>点击查看</summary>
```cpp
std::cout << "Hello World!" << std::endl;
```
</details>

效果展示如下:

点击查看
1
std::cout << "Hello World!" << std::endl;

静态资源压缩

Hexo生成html文件时,产生大量的换行和空格,导致html的可读性下降,同时也拖慢了博客的加载速度。
解决方案:通过gulp插件对资源进行压缩,然后在推送到服务器。

安装gulp相关依赖

因为npm服务器速度很慢,所以选择使用cnpm

1
$ npm install -g cnpm --registry=https://registry.npm.taobao.org

gulp安装到全局中

1
$ cnpm install gulp -g

方法一:直接安装相关依赖gulp-imagemin、gulp-minify-css、gulp-minify-html、gulp-uglify到项目中

1
$ cnpm install gulp gulp-imagemin gulp-minify-css gulp-minify-html gulp-uglify --save

方法二:将需要的依赖放在package.jsondevDependencies字段中,然后执行cnpm install命令就会自动安装添加的依赖,这样的好处是可以保证如果换台电脑安装版本仍然是一致的,避免版本兼容问题。

1
2
3
4
5
6
7
"dependencies": {
"gulp": "^4.0.2",
"gulp-imagemin": "^7.1.0",
"gulp-minify-css": "^1.2.4",
"gulp-minify-html": "^1.0.6",
"gulp-uglify": "^3.0.2",
}

创建 gulpfile.js

在Hexo博客的根目录下面,创建一个gulpfile.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
var gulp = require('gulp');

// Plugins模块获取
var minifycss = require('gulp-minify-css');
var uglify = require('gulp-uglify');
var minifyhtml = require('gulp-minify-html');
var imagemin = require('gulp-imagemin')

// 压缩 public 目录 css文件
gulp.task('minify-css', function () {
return gulp.src('./public/**/*.css')
.pipe(minifycss())
.pipe(gulp.dest('./public'));
});

// 压缩 public 目录 html文件
gulp.task('minify-html', function () {
return gulp.src('./public/**/*.html')
.pipe(minifyhtml())
.pipe(gulp.dest('./public'))
});

// 压缩 public/js 目录 js文件
gulp.task('minify-js', function () {
return gulp.src('./public/**/*.js')
.pipe(uglify())
.pipe(gulp.dest('./public'));
});

// 压缩public/posts 目录 图片文件
gulp.task('minify-img', function () {
return gulp.src('./public/**/*.*')
.pipe(imagemin(
[
imagemin.gifsicle({
'optimizationLevel': 3
}),
imagemin.jpegtran({
'progressive': true
}),
imagemin.optipng({
'optimizationLevel': 7
}),
imagemin.svgo()
], {
'verbose': true
}))
.pipe(gulp.dest('./public'))
});

// 分别执行css、html、js和图片的压缩任务
gulp.task('build', gulp.series('minify-css', 'minify-html', 'minify-js', 'minify-img'));

注意:
图片压缩速度很慢,若不需要压缩图片,请将第52行的代码中的minify-img删除,忽略其它文件压缩同理。
自己按照教程部署时,压缩minify-jsminify-img报错如下:

1
2
GulpUglifyError: unable to minify JavaScript
Caused by: SyntaxError: Unexpected token: punc «)»

主要是因为javascirpt语法问题,在es5环境里使用了es6、es7语法,暂时不压缩js,img上传前都会先用工具压缩,先不做处理。
压缩css后,部署远程站点后发现网页样式中,部分元素本地预览是居中对齐,但线上显示左对齐,所以这里只对html文件压缩。

1
2
// 执行html压缩任务
gulp.task('build', gulp.series('minify-html'));

或者参考Gulp打包问题处理es5语法兼容问题。

压缩资源发布:

1
2
3
4
$ hexo clean
$ hexo g
$ gulp build
$ hexo d

CDN加速

由于将博客从Github迁移到Coding后访问响应速度已经比较快,因此暂时不做CDN加速配置,如需配置,可参考上述博客。

跳过source指定文件渲染

修改_config.yml配置文件中的skip_render跳过指定文件渲染。
注:_config.yml文件是站点根目录下的,不是主题目录下的。
如下配置表示,跳过source/README.md的渲染,应填相对于source文件夹的相对路径。

_config.yml
1
2
3
4
5
6
7
8
9
10
# Directory
source_dir: source
public_dir: public
tag_dir: tags
archive_dir: archives
category_dir: categories
code_dir: downloads/code
i18n_dir: :lang
- skip_render:
+ skip_render: [README.md]

全局字体修改

默认字体为Lato,可根据个人喜好选择字体,例如:很有科技感的字体Monda,下面就将它应用到自己的博客。
在主题配置文件_config.yml中修改字体配置:(如果修改没有效果,需要安装配置的字体)

themes/next/_config.yml
1
2
3
4
5
6
7
8
9
font:
- enable: false
+ enable: true

global:
external: true
- family: Lato
+ family: Monda # 设置Monda字体
size:

显示加载进度条

当网络不好的时候会出现白屏等待,此时如果能有加载进度提示将会提高用户操作体验。
首先,在根目录下执行以下命令安装相关依赖,下载theme-next-pacethemes/next/source/lib/pace

themes/next/source/lib/pace
1
$ git clone https://github.com/theme-next/theme-next-pace themes/next/source/lib/pace

在主题配置文件_config.yml中修改进度条配置,theme使用默认配置minimal,也可以使用Themes list中的其他pace主题:

themes/next/_config.yml
1
2
3
4
5
6
7
pace:
- enable: false
+ enable: true # 开启加载进度条
# Themes list:
# big-counter | bounce | barber-shop | center-atom | center-circle | center-radar | center-simple
# corner-indicator | fill-left | flat-top | flash | loading-bar | mac-osx | material | minimal
theme: minimal

Hexo博客的NexT主题美化和功能增强(二) 去看看