建议先配置好 Hexo 并确保其能正常使用。

插件卸载指令:

1
npm uninstall <插件名>

注:1. 本文借鉴/搬运部分均标注原文链接(除非二次修改程度极高)。有些片段因格式不方便但自己修改时使用到,将只放原文链接;2. 本文为我自己修改时借鉴或探索时使用到教程的记录,算是“索引”和笔记,可能不适用于你的网站,参考时请根据自己情况酌情修改。


前言

如你所见,Hexo 的有些主题可玩性非常高,看着无相似性的几个 Hexo 站点,没准用的是同一套主题……

本文谨以记录本人折腾博客时用到的教程。

为方便起见,博客根目录记为【Blogroot】,域名记为www.example.com,自定义内容优先放在主题配置文件中,少部分会涉及到 hexo 根目录下配置文件。

本文提及的目录、配置等均为默认安装的样子,你若有自定义的请结合实际。有些教复杂但官方教程写得详细的,此处一笔带过。

本文当前对应环境:

名称 整理教程时最开始环境版本 本文最近一次更新时环境版本
hexo ^6.3.0 ^7.0.0
hexo-theme-butterfly ^4.9.0 ^4.11.0
node.js ^18.(?) ^20.10.1

行数标注对应我的配置文件,但相应代码应该大差不差。

yaml 大小写敏感、yaml 以缩进表示层级关系、yaml 中冒号后空一格再写内容……为防止因格式造成的问题,请在使用时自查代码缩进关系。

实际上,自定义引入文件(如图片、css、js 等),最好在【Blogroot】/source目录下创建文件夹放置,而不应放到主题文件夹,以防更新主题时误删。本文中如有说将上述类型文件存到【Blogroot】/theme目录下某处时,请酌情修改自己的实操方案。【至于 pug、stylus 等类型的文件,为保险起见,最好保持原来路径,不作修改。】

除非强调,否则配置内容时修改的 config 可自行选择。本索引为管理方便,一般与主题关联度大的修改于_config.\[theme\].yml中,与“系统”关联度大的(例如文章加密、缓存等)放在_config.yml中。

Hexo 在合并主题配置时,Hexo 配置文件中的 theme_config 的优先级最高,其次是 _config.\[theme\].yml 文件,最后是位于主题目录下的 _config.yml 文件。

安装主题

(此段引用https://butterfly.js.org/posts/21cfbf15官方教程)

在【Blogroot】(文件夹)中打开 Git(没配置 Hexo 主程序的请移步至之前文章),输入

1
git clone -b master https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly

Hexo 需要 Pug 和 Stylus 渲染器,可使用命令安装

1
npm install hexo-renderer-pug hexo-renderer-stylus --save

之后还是在【Blogroot】中找到_config.yml文件,使用编辑器打开,找到theme: 并修改此行为theme: butterfly

为减少主题升级带来的不便,可将主题的配置文件【Blogroot】/themes/butterfly/_config.yml复制到【Blogroot】目录下,并重命名为_config.butterfly.yml,之后修改主题的配置均可只修改此文件。

注意:

  1. 不要把主题目录的 _config.yml 删掉;
  2. 以后只需要在 _config.butterfly.yml 进行配置就行。如果使用了 _config.butterfly.yml, 配置主题的 _config.yml 将不会有效果;
  3. Hexo 会自动合并主题中的 _config.yml_config.butterfly.yml 里的配置,如果存在同名配置,会使用 _config.butterfly.yml 的配置,其优先度较高。

到这里主题算是安装完成。

Butterfly 自定义

常用基础配置修改索引

常见(字面意思)可用修改有:

自定义导航与页面

  • _config.butterfly.yml中 menu

此处修改后,有些页面可能不存在,此时需要在【Blogroot】/source目录下建立同名文件夹,文件夹内创建index.md(可用 hexo 原生命令或第三方编辑器如 Hexon、ESHexoN 等完成)。自己添加页面也是同理,将自定义页面添加至导航请参考导航处格式。补充:此处导航前文字是可以修改的。

修改例:

1
2
3
4
5
6
7
8
9
10
menu:
主页:/ || fas fa-home
归档:/archives/ || fas fa-archive
# 标签:/tags/ || fas fa-tags
分类:/categories/ || fas fa-folder-open
# 清单||fas fa-list:
# Music: /music/ || fas fa-music
# Movie: /movies/ || fas fa-video
友链:/link/ || fas fa-link
关于:/about/ || fas fa-heart

请在【Blogroot】/source中创建aboutcategorieslink文件夹(与上方文字对应关系不需多说),并分别在文件夹中创建index.md,里面的格式应该不需要多说了,官网有创建单页的教程,很详细;民间也有。

【PS:单页中可以有一定的 CSS 代码与 HTML 代码,但不能有 JS】

简单自定义背景

  • _config.butterfly.yml中 Image (圖片設置)

主页标题

  • _config.butterfly.yml中 blog_title_font、subtitle

  • _config.yml中 Site

Pjax

  • _config.butterfly.yml中 pjax

引入外部资源

  • _config.butterfly.yml中 inject

注:建议 head 后加 css、bottom 后加 js

文章过期提醒

  • _config.butterfly.yml中 noticeOutdate

进阶修改索引

全局美化(参考)

https://moonshuo.cn/

博客背景使用一图流

https://qianchenggit.github.io/

打开_config.butterfly.yml文件,找到图片相关(banner)几个,后面的图片都留空不填,如果和本站效果相仿请直接改成下方内容(注释已去除):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Disable all banner image
disable_top_img: false # 【取消首页全屏的图片】

index_img: transparent # 【此处为透明效果】

default_top_img: 【改成你自己的图片地址,不想要其他图片的改法同上方 index_img】

archive_img: 【改成你自己的图片地址,不想要其他图片的改法同上方 index_img】

tag_img:

tag_per_img:

category_img:

category_per_img:

还是这个文件,找到以下内容并修改(已去除部分注释):

1
2
3
4
5
# Website Background (設置網站背景)
background: url() # 【括号内换成自己希望使用的背景图地址】

# Footer Background
footer_bg: transparent # 【页脚透明】

不喜欢黑色笼罩层的请再往下多看一行(为 header 或 footer 添加黑色半透遮罩)(这里我没试过。当然,另使用 CSS 修改也是可行的)

之后 Hexo 三连即可生效。如果不喜欢此时的样式,请另行参考网上各路大神自定义的 CSS。

随机图片封面

直接填写

如果是使用多个 api 或填入多个图片地址则可不使用此方法,直接在_config.butterfly.yml文件中cover:后添加即可

1
2
default_cover: 
- 【图片路径或 api】

使用 js 支持随机图片 api

https://blog.mitsumune.top/

打开【Blogroot】下/themes/butterfly/scripts 目录,新建一个 random_img.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
/**
* Butterfly
* ramdom cover
*/

'use strict'

hexo.extend.filter.register('before_post_render', function (data) {
const { config } = this
if (config.post_asset_folder) {
const imgTestReg = /\.(png|jpe?g|gif|svg|webp)(\?.*)?$/
const topImg = data.top_img
const cover = data.cover
if (topImg && topImg.indexOf('/') === -1 && imgTestReg.test(topImg)) data.top_img = data.path + topImg
if (cover && cover.indexOf('/') === -1) data.cover = data.path + cover
}

if (data.cover === false) {
data.randomcover = randomCover()
return data
}

data.cover = data.cover || randomCover()
return data
},0)

function randomCover () {
const theme = hexo.theme.config
let cover
let num

if (theme.cover && theme.cover.default_cover) {
if (!Array.isArray(theme.cover.default_cover)) {
cover = theme.cover.default_cover
} else {
num = Math.floor(Math.random() * theme.cover.default_cover.length)
cover = theme.cover.default_cover[num]
}
} else {
cover = theme.default_top_img || 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
}
if(theme.cover.suffix){
if(theme.cover.suffix == 1)
cover = cover + ("?" + Math.ceil(Math.random()*10000))
else if(theme.cover.suffix == 2)
cover = cover + ("&" + Math.ceil(Math.random()*10000))
}
return cover
}

_config.butterfly.yml中找到cover:,并在其后插入suffix: 1并保存(目的是在链接后面加入后缀?spm={随机数} 0 是不使用后缀、1 是?加随机数;2 是&加随机数)

三连生效

深色模式流星特效

【参考https://blog.meta-code.top/2021/09/30/2021-7/

在前文提到的_config.butterfly.yml中找到inject处,在bottom:

1
2
3
bottom:
- '<canvas id="universe"></canvas>'
- '<script src="/js/universe.js"></script>'

之后在【Blogroot】/themes/butterfly/sources/js目录下创建一个universe.js文件,也可以添加到自己的 js 文件中。该文件或相关位置编写如下:

1
2
function dark() {window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame;var n,e,i,h,t=.05,s=document.getElementById("universe"),o=!0,a="180,184,240",r="226,225,142",d="226,225,224",c=[];function f(){n=window.innerWidth,e=window.innerHeight,i=.216*n,s.setAttribute("width",n),s.setAttribute("height",e)}function u(){h.clearRect(0,0,n,e);for(var t=c.length,i=0;i<t;i++){var s=c[i];s.move(),s.fadeIn(),s.fadeOut(),s.draw()}}function y(){this.reset=function(){this.giant=m(3),this.comet=!this.giant&&!o&&m(10),this.x=l(0,n-10),this.y=l(0,e),this.r=l(1.1,2.6),this.dx=l(t,6*t)+(this.comet+1-1)*t*l(50,120)+2*t,this.dy=-l(t,6*t)-(this.comet+1-1)*t*l(50,120),this.fadingOut=null,this.fadingIn=!0,this.opacity=0,this.opacityTresh=l(.2,1-.4*(this.comet+1-1)),this.do=l(5e-4,.002)+.001*(this.comet+1-1)},this.fadeIn=function(){this.fadingIn&&(this.fadingIn=!(this.opacity>this.opacityTresh),this.opacity+=this.do)},this.fadeOut=function(){this.fadingOut&&(this.fadingOut=!(this.opacity<0),this.opacity-=this.do/2,(this.x>n||this.y<0)&&(this.fadingOut=!1,this.reset()))},this.draw=function(){if(h.beginPath(),this.giant)h.fillStyle="rgba("+a+","+this.opacity+")",h.arc(this.x,this.y,2,0,2*Math.PI,!1);else if(this.comet){h.fillStyle="rgba("+d+","+this.opacity+")",h.arc(this.x,this.y,1.5,0,2*Math.PI,!1);for(var t=0;t<30;t++)h.fillStyle="rgba("+d+","+(this.opacity-this.opacity/20*t)+")",h.rect(this.x-this.dx/4*t,this.y-this.dy/4*t-2,2,2),h.fill()}else h.fillStyle="rgba("+r+","+this.opacity+")",h.rect(this.x,this.y,this.r,this.r);h.closePath(),h.fill()},this.move=function(){this.x+=this.dx,this.y+=this.dy,!1===this.fadingOut&&this.reset(),(this.x>n-n/4||this.y<0)&&(this.fadingOut=!0)},setTimeout(function(){o=!1},50)}function m(t){return Math.floor(1e3*Math.random())+1<10*t}function l(t,i){return Math.random()*(i-t)+t}f(),window.addEventListener("resize",f,!1),function(){h=s.getContext("2d");for(var t=0;t<i;t++)c[t]=new y,c[t].reset();u()}(),function t(){document.getElementsByTagName('html')[0].getAttribute('data-theme')=='dark'&&u(),window.requestAnimationFrame(t)}()};
dark()

以上段落的最后部分('data-theme')=='dark'一段表明其仅在主题深色模式下启用。

为修改方便,随后请在【Blogroot】/themes/butterfly/sources/css目录下创建一个 css 文件,名字自定,例如custom.css,在其中加上:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* 夜间模式下背景宇宙星光 */
#universe {
display: block;
position: fixed;
margin: 0;
padding: 0;
border: 0;
outline: 0;
left: 0;
top: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1;
}
/* 亮色模式下隐藏 */
[data-theme='light'] #universe {
display: none;
}

回到_config.butterfly.yml,再次找到inject处,在head:

1
2
head:
- <link rel="stylesheet" href="/css/custom.css"/>

hexo 三连,完成

live2D

【Blogroot】目录下打开 Git,输入

1
2
npm install --save hexo-helper-live2d #普通版 Live2D 主程序
npm install 【模型名称】 #字面意思

作者提供了以下几个模型于https://github.com/xiazeyu/live2d-widget-models

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
live2d-widget-model-chitose
live2d-widget-model-epsilon2_1
live2d-widget-model-gf
live2d-widget-model-haru/01 (use npm install --save live2d-widget-model-haru)
live2d-widget-model-haru/02 (use npm install --save live2d-widget-model-haru)
live2d-widget-model-haruto
live2d-widget-model-hibiki
live2d-widget-model-hijiki
live2d-widget-model-izumi
live2d-widget-model-koharu
live2d-widget-model-miku
live2d-widget-model-ni-j
live2d-widget-model-nico
live2d-widget-model-nietzsche
live2d-widget-model-nipsilon
live2d-widget-model-nito
live2d-widget-model-shizuku
live2d-widget-model-tororo
live2d-widget-model-tsumiki
live2d-widget-model-unitychan
live2d-widget-model-wanko
live2d-widget-model-z16

回到_config.yml,新起一段添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
live2d:
enable: true #是否启用
scriptFrom: local
model:
use: 【模型名称】 #模型选择
display:
position: right #模型位置
width: 120 #模型宽度
height: 240 #模型高度
hOffset: 20 #纵向偏移
vOffset: -55 #横向偏移
mobile:
show: false #是否在手机端显示
react:
opacity: 0.8 #透明度

另有更高级版本可参考https://www.mmbkz.cn/a262193e.htmlhttps://diego369.github.io/2022/04/08/live2d

全局左下角 APlayer

官方教程为https://butterfly.js.org/posts/507c070f/

hexo-tag-aplayer 可使用下文方法引入并使用。

【Blogroot】目录下打开 Git,安装插件

1
npm un hexo-tag-aplayer

回到_config.butterfly.yml,在约第 859 行 APlayer 处、第 919 行 inject 处作如下修改

1
2
3
4
5
6
7
8
9
10
11
12
13
# Inject the css and script (aplayer/meting)
aplayerInject:
- enable:
- per_page:
+ enable: true
+ per_page: true
......
inject:
head:
......
bottom:
......
+ - <div class="aplayer no-destroy" data-id="【自定义】" data-server="netease" data-type="playlist" data-fixed="true" data-mini="true" data-volume="0.2" data-listFolded="true" data-preload="none" data-autoplay="false" muted></div>

上方示例使用了MetingJS,配置大多与 MetingJS 相同,普通使用只需注意以下参数:

  • data-id=”” : 指定调用的 id ,一般可以在地址栏中找到
  • data-server=”netease” : 网易云音乐服务器,可改为 netease, tencent, kugou, xiami, baidu ,分别对应网易云音乐QQ 音乐酷狗音乐虾米音乐百度音乐
  • data-type=”playlist : 指定调用类型,可选 song, playlist, album, search, artist ,分别对应单曲歌单专辑搜索结果艺术家
  • data-fixed=”true” : 播放器吸附在页面左下角
  • data-mini=”true” : 迷你版播放器
  • data-volume=”0.2” : 默认音量为 0.2
  • autoplay=”false” : 取消自动播放

APlayer 基本配置完成,美化之类的可自行搜索。

信笺样式留言板

https://akilar.top/posts/e2d3c450/

在【Blogroot】下打开 Git 运行指令

1
npm install hexo-butterfly-envelope --save

在站点配置文件或者主题配置文件(二选一)添加配置项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# envelope_comment
# see https://akilar.top/posts/e2d3c450/
envelope_comment:
enable: true #控制开关
custom_pic:
cover: https://npm.elemecdn.com/hexo-butterfly-envelope/lib/violet.jpg #信笺头部图片
line: https://npm.elemecdn.com/hexo-butterfly-envelope/lib/line.png #信笺底部图片
beforeimg: https://npm.elemecdn.com/hexo-butterfly-envelope/lib/before.png # 信封前半部分
afterimg: https://npm.elemecdn.com/hexo-butterfly-envelope/lib/after.png # 信封后半部分
message: #信笺正文,多行文本,写法如下
- 有什么想问的?
- 有什么想说的?
- 有什么想吐槽的?
- 哪怕是有什么想吃的,都可以告诉我哦~
bottom: 自动书记人偶竭诚为您服务! #仅支持单行文本
height: #1050px,信封划出的高度
path: #【可选】comments 的路径名称。默认为 comments,生成的页面为 comments/index.html
front_matter: #【可选】comments 页面的 front_matter 配置
title: 留言板
comments: true

友情链接设置与美化

设置

[Blogroot]\source\目录下创建文件夹(例如friends),然后在此目录下创建index.md文件。在此文件中输入以下内容(基本内容,其他你亦可自定义):

1
2
3
4
---
title: 友情链接
type: 'link'
---

然后前往[Blogroot]\source\_data\目录下新建link.yml文件(没有目录的自己创建个),按照以下格式输入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- class_name: 分组 1 # title
class_desc: # 分组备注
link_list: # 友链列表
- name: 名称
link: 访问链接 url
avatar: 图片链接(最好通过图床构建,避免加载失效)
descr: 链接描述
- name: 名称
link: 访问链接 url
avatar: 图片链接
descr: 链接描述

- class_name: # title
class_desc: # 分组备注
link_list: 分组 2 # 友链列表
- name: 名称
link: 访问链接 url
avatar: 图片链接
descr: 链接描述

_config.butterfly.yml前面关于导航栏的配置,想必无需多言,去除注释即可。

1
友链:/friends/ || fas fa-link # 斜杠中间那个就是相对地址,例如你前面创建单页的文件夹名为`friends`,此处便如是填写。

Hexo 三连即可。

美化

https://akilar.top/posts/57291286/

加载动画

齿轮

参考https://cnhuazhu.top/butterfly/2021/02/25/Hexo%E9%AD%94%E6%94%B9/Hexo%E7%AB%99%E7%82%B9%E5%8A%A0%E8%BD%BD%E5%8A%A8%E7%94%BB%E4%BF%AE%E6%94%B9%EF%BC%88%E9%BD%BF%E8%BD%AE%E6%95%88%E6%9E%9C%EF%BC%89/

(最终我没有选择此方案)

胶囊样式加载进度条

虽说 Butterfly4.5.0 就内置了 pace,但我配置时未能达到预期结果,遂另引入。引入文件后建议把preloader:设置成enable: false,防止冲突(我先前保持这里启用时加载正常,升级完主题至 4.11.0 后不关的话进度条会很奇怪,原因未知,可能是个例)。

回到_config.butterfly.yml找到preloader,将enable: false改为 true。你要不放心的话在此段的 pace_css_url 后修改

1
2
3
4
5
6
preloader:
- enable: false
+ enable: true
...
- pace_css_url:
+ pace_css_url: https://cdn.jsdelivr.net/npm/pace-js@1.2.4/pace-theme-default.min.css

找到inject:bottom:,添加 js:

1
2
3
bottom:
...
+ - <script data-pjax src="https://cdn.jsdelivr.net/npm/pace-js@1.2.4/pace.min.js"></script>

随后在【Blogroot】/themes/butterfly/sources/css中新建一个 css 文件(也可以使用前文提到的 custom.css),引入方法同前文。在这个文件中添加

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
.pace {
-webkit-pointer-events: none;
pointer-events: none;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
z-index: 2000;
position: fixed;
margin: auto;
top: 10px;
left: 0;
right: 0;
height: 8px;
border-radius: 8px;
width: 4rem;
background: #eaecf2;
border: 1px #e3e8f7;
overflow: hidden
}

.pace-inactive .pace-progress {
opacity: 0;
transition: .3s ease-in
}

.pace .pace-progress {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
-o-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
max-width: 200px;
position: absolute;
z-index: 2000;
display: block;
top: 0;
right: 100%;
height: 100%;
width: 100%;
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
animation: gradient 1.5s ease infinite;
background-size: 200%
}

.pace.pace-inactive {
opacity: 0;
transition: .3s;
top: -8px
}
@keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}

hexo 三连,完成

页脚电子钟与 GitHub 徽标

Native JS Timer(页脚电子钟):https://akilar.top/posts/b941af/

Add Github Badge(自定义添加 GitHub 徽标):https://akilar.top/posts/e87ad7f8/

RSS

在【Blogroot】下打开 Git,输入

1
npm install hexo-generator-feed --save

然后打开_config.yml,在末尾新起一行添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# RSS
feed:
enable: true # 是否启用插件
type: atom # RSS 的类型,有 atom 和 rss2 两个选项,使用默认 atom 就好了
path: atom.xml # 文件路径,默认是 atom.xml/rss2.xml
limit: 15 # 展示文章的数量,使用 0 或 false 代表展示全部
hub: # 这个我没用上,根据官网,空着就行
content: # 在 RSS 文件中是否包含内容 , 有 3 个值 true/false/默认不填 (false)
content_limit: 100 # 指定内容的长度作为摘要,仅仅在上面 content 设置为 false 和没有自定义的描述出现
content_limit_delim: ' ' # 上面截取描述的分隔符,截取内容是以指定的这个分隔符作为截取结束的标志。在达到规定的内容长度之前最后出现的这个分隔符之前的内容,防止从中间截断。
order_by: -date # 采用日期进行排序
icon: icon.png # 给 rss 链接配置 icon
autodiscovery: true # 自动发现提要
template: # 给 rss 文章配置模板

【注:_config.yml文件前面约 16 行左右 url 处需填写你博客的地址,详见“优化链接”】

【注:主题配置文件中不添加下面这一段貌似不影响什么】

回到_config.butterfly.yml,新起一行,添加

1
rss: /atom.xml

还是这个文件,找到 social 一栏,添加

1
2
3
4
social:
# fab fa-github: https://github.com/xxxxx || Github || '#24292e'
# fas fa-envelope: mailto:xxxxxx@gmail.com || Email || '#4a7dbe'
+ fas fa-rss: https://www.example.com/atom.xml # 在右侧作者头像下面添加 RSS 按钮

hexo 三连,完成

侧边栏日历

参考https://moonshuo.cn/posts/50269.html

【Blogroot】目录下打开 Git,输入

1
2
npm install -g cnpm -registry=https://registry.npm.taobao.org # 你如果已经安装过 cnpm 则可忽略这条
cnpm install --save git://github.com/howiefh/hexo-generator-calendar.git

https://github.com/pengloo53/Hexo-theme-light_cn/tree/master/source/js下载calendar.jslanguage.js两个文件,将其保存到【Blogroot】/themes/Butterfly/source/js/目录下。保存后请使用编辑器打开calendar.js文件,在结尾}(jQuery));前添加

1
2
3
4
5
6
7
8
9
10
......
root: '/calendar/',
url: '/calendar.json'
};

+ $(document).ready(function () {
+ $('#calendar').aCalendar('zh-CN');//'zh-CN'请根据自己博客的语言选择
+ });

}(jQuery));

之后打开_config.butterfly.yml,找到inject:,在bottom:后添加

1
2
3
4
5
6
bottom:
...
+ - <script src="/js/jquery.min.js"></script> # 这段没引入的自行添加,而且需在 bottom 后第一个引入,否则可能出现加载出错问题
......
+ - <script data-pjax src="/js/calendar.js"></script>
+ - <script data-pjax src="/js/languages.js"></script>

【Blogroot】/themes/Butterfly/source/css/_layout/目录下新建calendar.styl文件,内容如下

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
#calendar
a
text-decoration none

.cal-head
margin-bottom: 15px
position relative
height 20px
padding 8px 6px 2px 6px

.cal-prev,.cal-next
position absolute
top 9px
width 16px
height 18px
padding 3px 4px
border 1px solid transparent
color #333
outline 0

.cal-prev
left 8px
&:before
border-right 9px solid #333

.cal-next
right 8px
&:before
border-left 9px solid #333

.cal-prev:before,.cal-next:before
content ''
display block
width 0
height 0
border-top 5px solid transparent
border-bottom 5px solid transparent

.cal-title
width 100px
margin 0 auto
color #333
font bold 14px/18px Arial
text-align center
a
border 1px solid transparent
color #9f9f9f

.cal,
.cal th,
.cal td
border 1px solid #d1d1d1

.cal
display: table
border-collapse separate
border-spacing 0
border-width 1px 0 0 1px
table-layout fixed
width 100%
margin 0
th
background #9f9f9f
color #fff
border-width 0 1px 1px 0
font-weight 700
td
border-width 0 1px 1px 0
tbody
a
background-color #007acc
color #fff
display block
font-weight 700
.cal-today
background-color #66ecfd
color #fff
.cal-gray
color #bbb8b8

[data-theme='dark'] .cal .cal-gray
color #505050

.cal th,
.cal td
font-weight normal
line-height 2.5625
padding 0
text-align center

[data-theme='dark'] .cal .cal-foot
color #9f9f9f

.cal .cal-foot
color #2ca6cb

.cal-title a:hover,
.cal-prev:hover,
.cal-next:hover,
.cal .cal-foot:hover,
.cal .cal-foot:focus,
.cal tbody a:hover,
.cal tbody a:focus
background-color #686868
color #fff
cursor pointer

【Blogroot】/themes/Butterfly/layout/includes/widget/目录下新建card_calendar.pug文件,编辑内容如下

1
2
3
4
5
6
7
if theme.aside.card_calendar.enable
.card-widget.card-calendar
.card-content
.item-headline
i.fas.fa-calendar
span= _p('日历')
div#calendar.widget

【Blogroot】/themes/Butterfly/layout/includes/widget/目录下找到并使用编辑器打开index.pug文件,在你认为合适的位置插入以下内容

1
2
if theme.aside.card_calendar
!=partial('includes/widget/card_calendar', {}, {cache:theme.fragment_cache})

例如:

1
2
3
4
5
6
7
8
9
10
11
12
......
include ./card_post_toc.pug
+ !=partial('includes/widget/card_calendar', {}, {cache: true})
!=partial('includes/widget/card_recent_post', {}, {cache: true})
!=partial('includes/widget/card_ad', {}, {cache: true})
else
//- page
!=partial('includes/widget/card_author', {}, {cache: true})
!=partial('includes/widget/card_announcement', {}, {cache: true})
+ !=partial('includes/widget/card_calendar', {}, {cache: true})
!=partial('includes/widget/card_top_self', {}, {cache: true})
......

回到_config.butterfly.yml配置文件,找到aside:段落,在这段结尾添加相关内容,修改完应如下(calendar 一段,缩进与前部分配置齐平,其相对关系应为 aside 内)

1
2
3
4
5
6
7
8
......
+ card_calendar:
+ enable: true

# busuanzi count for PV / UV in site
# 訪問人數
busuanzi:
......

打开_config.yml配置文件,新起一段添加:

1
2
3
4
5
......
calendar:
single: true
root: calendar/
......

三连后日历成功显示

进入离开页面时修改标题

你可能见过一些网站,当离开网页时,上方标签内标题会变成另一段文字;回到页面后标签内容再次修改,几秒后恢复。

【Blogroot】/themes/Butterfly/source/js/目录下随便找个 js 文件打开(也可以自己新建),添加以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var originTitle = document.title;
var titleTime;
document.addEventListener('visibilitychange', function () {
if (document.hidden) {
document.title = 'w(゚Д゚)w 不要走啊!!! ' + originTitle;
if (titleTime != null) {
clearTimeout(titleTime);
}
} else {
document.title = 'ヾ (^▽^*))) 欢迎回来! ' + originTitle;
titleTime = setTimeout(function () {
document.title = originTitle;
}, 2000);
}
});

新建 js 的记得在_config.butterfly.ymlinject:部分的bottom:后引入你新建的文件,然后 Hexo 三连即可。

去掉 Pjax 与某些插件并存时地址栏的后缀

https://android99.com/2020/12/18/pjax-and-pwa-conflict/

增加一段 Javascript 代码,用来劫持 Pjax 处理响应的方法。

把 request 对象中的响应地址修改为请求地址。

这里用到了 Object.defineProperty 方法,因为 request.responseURL 是只读变量,无法直接修改。

1
2
3
4
5
6
7
8
// 重定向浏览器地址
pjax.site_handleResponse = pjax.handleResponse;
pjax.handleResponse = function(responseText, request, href, options) {
Object.defineProperty(request, 'responseURL', {
value: href
});
pjax.site_handleResponse(responseText, request, href, options);
}

在【Blogroot】/source/js 目录下创建自定义 js 文件(没有文件夹的自己建一个),将以上内容写入。之后编辑_config.butterfly.yml,增加以下代码到 inject:bottom:之后:

1
2
3
bottom:
...
+ - <script defer type="text/javascript" src="/js/【文件名】.js"></script>

优化链接

Hexo 原生情况下文章链接是日期+标题的形式,这样会出现一个问题,一旦修改文章标题,原来的地址就无法访问;若使用汉字标题,复制链接时会非常难看;分级太多,对 SEO 不利。

而 abbrlink 这个插件就解决了此问题。此插件会给文章按照一定规则生成永久地址,只要文章还在,无论如何修改,原地址均可访问。

【Blogroot】目录下打开 Git 执行

1
npm install hexo-abbrlink --save

打开博客根目录下的_config.yml文件,找到 url 处,修改

1
2
3
4
5
6
7
8
9
10
11
12
# URL
## Set your site url here. For example, if you use GitHub Page, set url as 'https://username.github.io/project'
url: https://www.example.com
#permalink: :year/:month/:day/:title/
#permalink_defaults:
permalink: posts/:abbrlink/
abbrlink:
alg: crc32 #support crc16(default) and crc32
rep: dec #support dec(default) and hex
pretty_urls:
trailing_index: true # Set to false to remove trailing 'index.html' from permalinks
trailing_html: true # Set to false to remove trailing '.html' from permalinks

hexo 三连生效

自动为外链添加 nofollow 属性

https://github.com/hexojs/hexo-filter-nofollow

https://blog.skk.moe/post/hexo-filter-nofollow-joined-hexo-official-plugin/

安装

1
npm i hexo-filter-nofollow --save

如果你使用 yarn 作为你的 Hexo 的包管理器,你也可以使用下述命令:

1
yarn add hexo-filter-nofollow

选项

1
2
3
4
5
6
nofollow:
enable: true
field: site
exclude:
- 'exclude1.com'
- 'exclude2.com'

enable - 是否启用插件,默认值为 true
field - 插件的处理范围,默认值为 site,可选 post 或 site
post - 仅处理文章内容
site - 处理全站所有页面
exclude - 域名白名单,不同的子域名视为不同的域名(如 www)
exclude1.com 不包括 www.exclude1.com 或 en.exclude1.com

指定文章不在首页显示

先前看到张洪 Heo 大佬的方法,感觉不错,可惜若隐藏文章则首页文章数量也会受影响。而下文这个插件可以避免此问题。

项目地址:https://github.com/im0o/hexo-generator-index-custom

  • 在官方的首页生成器的基础上添加了使用 top 置顶文章和 hide 隐藏文章的功能。
  • hexo-generator-index-custom 可以完全替代官方的 hexojs/hexo-generator-index,所以安装之后,先卸载官方的插件,不然会引起一些冲突。

在【Blogroot】下打开 Git,输入

1
2
npm uninstall hexo-generator-index  
npm install hexo-generator-index-custom --save

_config.butterfly.yml中添加如下配置:

1
2
3
4
5
index_generator:
path: ''
per_page: 10
order_by: -date
pagination_dir: page

(所有的配置均与官方首页生成器一样,不必修改。)

配置完后便可使用。在文章开头的配置中添加stickytop参数,可以置顶文章。
其值可以是true或数字,数字越大,文章排在越前面。在文章开头的配置中添加hide参数,可以隐藏文章。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
---
title: Hello World
date: 2013/7/13 20:46:25
sticky: 100
---

---
title: Hello World
date: 2013/7/13 20:46:25
top: 100
---

---
title: Hello World
date: 2013/7/13 20:46:25
hide: true
---

给文章加上密码

项目地址:https://github.com/D0n9X1n/hexo-blog-encrypt
【快速使用。更多配置详见该项目文档】

首先,这是 Hexo 生态圈中 最好的 博客加密插件
你可能需要写一些私密的博客,通过密码验证的方式让人不能随意浏览。
这在 wordpress, emlog 或是其他博客系统中都很容易实现,然而 hexo 除外。:(
为了解决这个问题,让我们有请 “hexo-blog-encrypt”.

在【Blogroot】下打开 Git,输入

1
npm install --save hexo-blog-encrypt

然后在文章开头添加:

1
2
3
4
5
---
title: Hello World
date: 2016-03-30 21:18:02
password: hello
---

三连即可生效。高级点可以再添加:

1
2
3
4
5
password: pwd
abstract: 有东西被加密了,请输入密码查看。
message: 您好,这里需要密码。
wrong_pass_message: 抱歉,这个密码看着不太对,请再试试。
wrong_hash_message: 抱歉,这个文章不能被校验,不过您还是能看看解密后的内容。

将博文头部的password一条删去即取消加密。

博客加速/更新时弹窗提醒

https://colsrch.cn/posts/32c8ba21/
https://akilar.top/posts/8f31c3d0/
【快速使用。更多配置详见该项目文档】

hexo-offline-popup是一个 hexo 插件, 它可加速您的 Hexo 网站的加载速度,以及网站内容更新弹窗提示。

该插件基于停止维护已久的hexo-service-worker插件,并在它的基础上加以改进。

【Blogroot】目录下打开 Git 并输入:

1
npm i hexo-offline-popup --save

安装后,运行以下命令激活插件:

1
hexo clean && hexo generate

如果网站提供的所有内容来自原始服务器,你不需要添加任何配置。只需安装和运行 hexo clean && hexo generate。如果不是,请在博客根目录的_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
# offline config passed to sw-precache.
service_worker:
maximumFileSizeToCacheInBytes: 5242880 # 缓存的最大文件大小,以字节为单位,此处设置为 3MB。
staticFileGlobs:
- public/**/*.{js,html,xml,css,png,jpg,gif,svg,webp,eot,ttf,woff,woff2}
# - public/**/*.{html,xml} #精简版使用这行即可
# 静态文件合集,如果你的站点使用了例如 webp 格式的文件,请将文件类型添加进去。
# 注意,此处的文件类型就是会缓存下来的所有文件类型,如果不需要缓存那么多,
# 而只是想判断网页更新与否,缓存 html 和 xml 即可。
stripPrefix: public
verbose: true
runtimeCaching:
# CDNs - should be cacheFirst, since they should be used specific versions so should not change
# - urlPattern: /* # 如果你需要加载 CDN 資源,请配置该选项,如果沒有,可以不配置。
# handler: cacheFirst
# options:
# origin: example.com
- urlPattern: /*
handler: cacheFirst
options:
origin: cdn.jsdelivr.net # jsdelivr
- urlPattern: /*
handler: cacheFirst
options:
origin: unpkg.com # UNPKG
# 更多 cdn 可自行参照上述格式进行配置。

若不想再使用 hexo-offline-popup,您需要将改插件卸载,然后安装

1
npm uninstall hexo-offline-popup

注:本地预览不生效!

使用索引

自定义侧边栏

https://butterfly.js.org/posts/ea33ab97/

在 Hexo 博客目录中的source/_data(如果没有_data文件夹,请自行创建),创建一个文件widget.yml,填写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
top:
- class_name:
id_name:
name:
icon:
html:

bottom:
- class_name:
id_name:
name:
icon:
order:
html:

top: 创建的 widget 会出现在非 sticky 区域(即所有页面都会显示)

bottom: 创建的 widget 会出现在 sticky 区域(除了文章页都会显示)

参数 解释
class_name 所创建的 widget 父类 class 名 (可选)
id_name 所创建的 widget 父类 id 名(可选)
name 所创建的 widget 标题
icon 所创建的 widget 图标
order 所创建的 widget 排序 (可选)(简单来讲,就是配置数字来实现排序,如果不配置,则默认为 0。数字越小,排序越靠前。)
html 所创建的 widget 相关代码

标签外挂

https://butterfly.js.org/posts/4aa8abbe/

提示块标签

1
2
3
{% note [class] [icon] [style] %}
Any content (support inline tags too.io).
{% endnote %}
名称 用法
class 【可选】标识,不同的标识有不同的配色,可选 default / primary / success / info / warning / danger
no-icon 【可选】不显示 icon
style 【可选】可以覆盖配置中的 style,可选 simple/modern/flat/disabled

备注:[class]不填写则为默认灰色,[icon]处不填写则使用默认 icon。

例:

1
2
3
4
5
6
7
8
9
10
11
{% note info simple %}
info 提示块标签
{% endnote %}

{% note 'fab fa-cc-visa' simple %}
你是刷 Visa 还是 UnionPay
{% endnote %}

{% note green 'fab fa-internet-explorer' simple %}
前端最讨厌的浏览器
{% endnote %}

本文可能不定时更新。