虽然没有像2017年第一次建博客一样魔改但感觉还是有必要把一些技术问题写下来,也算是对我自己的记录,一些古早的技术步骤这里就不重复了。

自然而然的,在这里我只会记录一些难点,一些比较基础的问题就不再记录了,还有以前写过的也不再记录了。


博客的二级页面

这里的二级页面说的是page打开之后另外为page的情况,butterfly的二级以上的page显示是有点问题的,比如你在当前页面的index.md下,设置url通常为/thisroot/page2,但是如果你设置的是hisroot/page2/subpage2,那么butterfly的狗屎识别在编译后可能变成:你的主页网址/page2/page2/subpage2,然后你就很开心地获得了一个404页面。

解决办法:在设置三级页面的时候直接预判输出后的网页,然后以绝对地址的形式写url,即直接写url(你的主页网址/page2/page2/subpage2),当然这么干也有坏处,如果你是像我一样经常更换网址的人,你可能需要在更换网站绑定网址之后将博客内所有涉及到原主页链接的地址进行替换,当然了考虑到大部分人都有vscode,在vscode这种东西里面进行操作并不困难。

一些关于根目录config的说明

虽然butterfly的最近配置里面说可以在config.butterfly里修改,但一些比较古早的魔改美化教程似乎不能遵循这个原理,所以到最后到底是在根目录的哪个config,以及还是在主题的config里面修改就成为难题,此处稍微有点怀念next,因为next的教程满天飞反而不容易出这种其妙事情。

关于隐藏文章

这一步需要下载隐藏插件,一般来说用的是hexo-hide-post,buttefly似乎无法与另一款兼具隐藏和置顶功能的插件达成一致,不过我倒是见过一些比较早期的魔改butterfly实用者通过魔改下载了那个软件,并实现了文章置顶,当然就我个人而言,目前已经没有这个必要了,一个是已经有了文章轮播功能,再来个置顶本末倒置,另一个是我实在是懒得折腾报错了,毕竟我不是程序员,也并不想一直对着电脑啊!

你用butterfly隐藏文章之后,似乎数量也会发生变化,而且除非你用链接的形式将其引用,你在哪里都找不到它,我试过将某篇文章加入置顶轮播中,结果根本显示不出来。

关于密码锁

使用的是hexo-blog-encrypt,这个是目前hexo界最好用的一个插件,且制作完成了接近六七年后也没有替代品,也没有人完善()这个软件我觉得最大的遗憾就是两个巨大的bug到现在都没有修复。一个是加密之后文章目录会失效,这一点目前之后butterfly和修改过toc部分代码的next能逃过一劫,而其他主题呢,很多连手机端目录都没有,属于迫使我强制选这俩主题了。

另外一个问题似乎是butterfly特有的,就是加密tag功能失效了,这一点我在大部分古典主题上试过都可以,之前似乎也有人问过这个问题,但butterfly的作者似乎在这块很缺乏耐心。

还有一个我觉得无伤大雅的小问题,就是如果你没有写description的话,在部分主题中,你的主页文章简介部分会变成一堆数字乱码,之前用信纸主题的时候这个问题显得尤为突出,因为那个数字密码甚至会导致左右滚轮无限大。

密码锁功能其实应该是本人到目前为止使用最多的一个功能,本人的博客里一大堆上锁的,还得是因为这个博客的私人性质太重了,很多东西真的很难言之于众啊!

关于轮播图和首页精选

轮播图就是我现在首页第一个模块里展示置顶嘟文的地方,好处是不会有一堆置顶嘟文把首页的位置全占了,坏处是这玩意儿必须要加图片,所以如果你并不是一个以图片作为主流的博主就得小心了。

用的插件是hexo-swiper-bar,目前来讲似乎是一个butterfly专属插件,如果你用的是其他博客,那你自己试一试吧,话说我安装这玩意儿的时候也尤其不顺利,试了好几次才能安装上。

首页精选分类则是用的hexo-magnet,设置起来稍微会方便一点,不过稍微得注意一下几个模块的顺序。

这两个插件相对没那么好找,可以去小冰大佬的博客里去寻找和安装小冰插件包,里面还有很多其他适用于butterfly的插件,不过我看了下其他的对于一个文字博客来说必要性不是很大,就放弃了。

这个东西比较适合文章多的人,如果文章并不是很多的话,用起来可能比较累赘,当然相比起安知鱼那个主题来说,已经算得上很简洁了。

关于相册内页

用的是最基础的html设置box和设置css的办法,butterfly本来是有一个自带的相册内页的,但那个也太敷衍了,最后还得我去做一个能排版能显示图片名称的相册内页,就是打理起来没那么方便。

这里我举一个例子(以我的【其他】相册为例):

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
<div class="gallery-page">
<div class="gallery-row">
<div class="gallery-column">
<img src="https://xxxxxxx/files/xxxxxx">
<div class="gallery-item">拜占庭</div>
</div>
<div class="gallery-column">
<img src="https://xxxxxxx/files/xxxxxx">
<div class="gallery-item">奥地利</div>
</div>
</div>
<div class="gallery-row">
<div class="gallery-column">
<img src="https://xxxxxxx/files/xxxxxx">
<div class="gallery-item">拜占庭</div>
</div>
<div class="gallery-column">
<img src="https://xxxxxxx/files/xxxxxx">
<div class="gallery-item">奥地利</div>
</div>
</div>
</div>

<style>
.gallery-page {
margin-left: 90px;
margin-right: 90px;
}
.gallery-row{
display:flex;
flex-wrap: wrap;
justify-content: space-between;
}
img{
height:200px;
border-radius:10px;
box-shadow: 1px 1px 3px 2px #e7d1d191;
}
.gallery-item{
text-align: center;
font-size: 12px;
border-radius: 6px;
text-shadow: 1px 1px 2px #e7d1d1;
color: #b0babb;
margin-top: -17px;
}
.gallery-column{
weight:80px;
}
</style>

配置字数统计

对于一个打字的来讲这个算是比较不可或缺的点了,需要安装hexo-wordcount,这玩意儿还是比较好安装的就不提了。

配置昼夜不同的背景功能

这个是最近刚刚弄好的一个功能,之前其实弄过一次,但是效果不怎么好,所以就一直拖到现在,昨天是恰好想起来这里还有可以更改的地方,所以干脆也做了一下,中途如果你要充分体现图片的美感的话最好不要完全按照原步骤来做,首先position一定要全部改成fixed,然后可以参考这个博客Harris,我一开始是从一个二手复制粘贴链接点进去的,结果它居然不给复制我服了。

压缩

这篇其实写的内容不多,主要我也真的不是什么技术博主,有乐趣再去把技术内容摸一遍,现在最大的想法是看看能不能再次下载一下gulp,现在说实话点开网页的速度都有点慢了。

更新:几乎所有的资源压缩插件我都下载失败了,现在本人已经放弃。

更新:更新了npm镜像源之后我安装好了这玩意儿,现在每次的指令需要多加一步

1
2
3
4
hexo clean
hexo generate
gulp
hexo server 或 hexo deploy

恶搞标题栏文字

参考这篇文章Fomalhaut,实现的事当你离开网站的时候,标题栏显示不同的文字,回来后再显示另外的文字,最后过几秒之后恢复原状这一个过程。其实我感觉这个功能没什么很大的用处,但能用来当彩蛋挺好的。

外挂标签

参考的是这篇文章Akilar,之前的尝试没有成功过所以我一直对这个功能有点心理阴影,不过就是在主题文档里搜索了没有tag plugin puls之后我才意识到那什么划线功能居然是dlc吗。

不过我下载失败了,然后我用直接下载插件源代码分别复制的方法解决了这个问题,我服了……

就是装载完之后感觉其实可用空间并不是很大。

我不懂,我大为震撼,今天已经被npm err多少次了,我实在是不想尝试到底是哪里起冲突了!

更新:最后还是用切换npm镜像的方式解决了,下一次是不是该换一个github镜像来着。

NPM下载太慢

我觉得这个方式真的得改一下,没想到整了这么久最后还是靠改镜像活着的,下面这个是我目前用的镜像。

1
npm config set registry https://registry.npmmirror.com

这个是是否安装成功。

1
npm config get registry

这个是切换为官方镜像

1
npm config set registry https://registry.npmjs.org/

希望这个能坚持很久吧。

魔改页脚

也就是footer的部分,某些可能不怎么好改容易翻车的地方,所以要记下来。

点开[根目录]\themes\butterfly\layout\includes\footer.pug

找到

1
2
3
4
5
6
7
if theme.footer.copyright
.framework-info
span= _p('footer.framework') + ' '
a(href='https://hexo.io')= 'Hexo'
span.footer-separator |
span= _p('footer.theme') + ' '
a(href='https://github.com/jerryc127/hexo-theme-butterfly')= 'Butterfly'

这部分,这部分内容是用来控制页尾的Framework Hexo和Theme Butterfly的,经测试span= _p(‘footer.theme’)里的theme是可以被修改的,文字会发生变化。

汉化系列

和上面的魔改页脚一样,都属于文字内容汉化,点开[根目录]\themes\butterfly\layout\includes\widget里面的card_author,找到

1
2
3
4
5
6
7
8
9
10
.card-info-data.site-data.is-center
a(href=url_for(config.archive_dir) + '/')
.headline= _p('aside.articles')
.length-num= site.posts.length
a(href=url_for(config.tag_dir) + '/')
.headline= _p('aside.tags')
.length-num= site.tags.length
a(href=url_for(config.category_dir) + '/')
.headline= _p('aside.categories')
.length-num= site.categories.length

这部分,还是改_p()中间的内容,把aside.xxx全部改成汉语;
同理找到card_announcement,
找到
1
2
i.fas.fa-bullhorn.fa-shake
span= _p('aside.card_announcement')

可以把i.和_p()的内容都改掉,修改这部分的时候要注意一下,你现在直接去fontawesome网站复制的内容大概会是<i class="fas fa-wine-glass-alt"></i>这种样子的,放到i后面的时候不但要注意删除双引号及以外的所有部分,还要把fas和fa之间的空格变成英语句号,这样才能识别出来。

修改info的话,找到card_webinfo,然后开始修改内容。

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
if theme.aside.card_webinfo.enable
.card-widget.card-webinfo
.item-headline
i.fas.fa-chart-line
span= _p('aside.card_webinfo.headline')
.webinfo
if theme.aside.card_webinfo.post_count
.webinfo-item
.item-name= _p('aside.card_webinfo.article_name') + " :"
.item-count= site.posts.length
if theme.runtimeshow.enable
.webinfo-item
.item-name= _p('aside.card_webinfo.runtime.name') + " :"
.item-count#runtimeshow(data-publishDate=date_xml(theme.runtimeshow.publish_date))
i.fa-solid.fa-spinner.fa-spin
if theme.wordcount.enable && theme.wordcount.total_wordcount
.webinfo-item
.item-name=_p('aside.card_webinfo.site_wordcount') + " :"
.item-count=totalcount(site)
if theme.busuanzi.site_uv
.webinfo-item
.item-name= _p('aside.card_webinfo.site_uv_name') + " :"
.item-count#busuanzi_value_site_uv
i.fa-solid.fa-spinner.fa-spin
if theme.busuanzi.site_pv
.webinfo-item
.item-name= _p('aside.card_webinfo.site_pv_name') + " :"
.item-count#busuanzi_value_site_pv
i.fa-solid.fa-spinner.fa-spin
if theme.aside.card_webinfo.last_push_date
.webinfo-item
.item-name= _p('aside.card_webinfo.last_push_date.name') + " :"
.item-count#last-push-date(data-lastPushDate=date_xml(Date.now()))
i.fa-solid.fa-spinner.fa-spin

这里同样是可以把_p()里面的内容全部重构。

在card_tags里,找到

1
2
3
4
.card-widget.card-tags
.item-headline
i.fas.fa-tags
span= _p('aside.card_tags')

按照同样规则修改

在card_recent_post里,找到

1
2
3
.item-headline
i.fas.fa-history
span= _p('aside.card_recent_post')

同样规则修改。

目前目录、分类和归档卡片还没有奏效。

同样可以修改上方栏目的search按钮,找到[根目录]\themes\butterfly\layout\includes\header里的nav.pug

1
2
3
4
#search-button
a.site-page.social-icon.search(href="javascript:void(0);")
i.fas.fa-search.fa-fw
span=' '+_p('search.title')

找到找到[根目录]\themes\butterfly\layout\includes\header里的post_info.pug,可以修改那堆created之类的内容,原文为
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
- let comments = theme.comments
#post-info
h1.post-title= page.title || _p('no_title')
if theme.post_edit.enable
a.post-edit-link(href=theme.post_edit.url + page.source title=_p('post.edit') target="_blank")
i.fas.fa-pencil-alt

#post-meta
.meta-firstline
if (theme.post_meta.post.date_type)
span.post-meta-date
if (theme.post_meta.post.date_type === 'both')
i.far.fa-calendar-alt.fa-fw.post-meta-icon
span.post-meta-label= _p('post.created')
time.post-meta-date-created(datetime=date_xml(page.date) title=_p('post.created') + ' ' + full_date(page.date))=date(page.date, config.date_format)
span.post-meta-separator |
i.fas.fa-history.fa-fw.post-meta-icon
span.post-meta-label= _p('post.updated')
time.post-meta-date-updated(datetime=date_xml(page.updated) title=_p('post.updated') + ' ' + full_date(page.updated))=date(page.updated, config.date_format)
else
- let data_type_update = theme.post_meta.post.date_type === 'updated'
- let date_type = data_type_update ? 'updated' : 'date'
- let date_icon = data_type_update ? 'fas fa-history' :'far fa-calendar-alt'
- let date_title = data_type_update ? _p('post.updated') : _p('post.created')
i.fa-fw.post-meta-icon(class=date_icon)
span.post-meta-label= date_title
time(datetime=date_xml(page[date_type]) title=date_title + ' ' + full_date(page[date_type]))=date(page[date_type], config.date_format)
if (theme.post_meta.post.categories && page.categories.data.length > 0)
span.post-meta-categories
if (theme.post_meta.post.date_type)
span.post-meta-separator |

each item, index in page.categories.data
i.fas.fa-inbox.fa-fw.post-meta-icon
a(href=url_for(item.path)).post-meta-categories #[=item.name]
if (index < page.categories.data.length - 1)
i.fas.fa-angle-right.post-meta-separator

.meta-secondline
- let postWordcount = theme.wordcount.enable && (theme.wordcount.post_wordcount || theme.wordcount.min2read)
if (postWordcount)
span.post-meta-separator |
span.post-meta-wordcount
if theme.wordcount.post_wordcount
i.far.fa-file-word.fa-fw.post-meta-icon
span.post-meta-label= _p('post.wordcount') + ':'
span.word-count= wordcount(page.content)
if theme.wordcount.min2read
span.post-meta-separator |
if theme.wordcount.min2read
i.far.fa-clock.fa-fw.post-meta-icon
span.post-meta-label= _p('post.min2read') + ':'
span= min2read(page.content, {cn: 350, en: 160}) + _p('post.min2read_unit')

//- for pv and count
mixin pvBlock(parent_id,parent_class,parent_title)
span.post-meta-separator |
span(class=parent_class id=parent_id data-flag-title=page.title)
i.far.fa-eye.fa-fw.post-meta-icon
span.post-meta-label=_p('post.page_pv') + ':'
if block
block

- const commentUse = comments.use
if page.comments !== false && commentUse && !comments.lazyload
if commentUse[0] === 'Valine' && theme.valine.visitor
+pvBlock(url_for(page.path),'leancloud_visitors',page.title)
span.leancloud-visitors-count
i.fa-solid.fa-spinner.fa-spin
else if commentUse[0] === 'Waline' && theme.waline.pageview
+pvBlock('','','')
span.waline-pageview-count(data-path=url_for(page.path))
i.fa-solid.fa-spinner.fa-spin
else if commentUse[0] === 'Twikoo' && theme.twikoo.visitor
+pvBlock('','','')
span#twikoo_visitors
i.fa-solid.fa-spinner.fa-spin
else if commentUse[0] === 'Artalk' && theme.artalk.visitor
+pvBlock('','','')
span#ArtalkPV
i.fa-solid.fa-spinner.fa-spin
else if theme.busuanzi.page_pv
+pvBlock('','post-meta-pv-cv','')
span#busuanzi_value_page_pv
i.fa-solid.fa-spinner.fa-spin
else if theme.busuanzi.page_pv
+pvBlock('','post-meta-pv-cv','')
span#busuanzi_value_page_pv
i.fa-solid.fa-spinner.fa-spin

if comments.count && !comments.lazyload && page.comments !== false && comments.use
- var whichCount = comments.use[0]

mixin countBlock
span.post-meta-separator |
span.post-meta-commentcount
i.far.fa-comments.fa-fw.post-meta-icon
span.post-meta-label= _p('post.comments') + ':'
if block
block

case whichCount
when 'Disqus'
+countBlock
a.disqus-comment-count(href=full_url_for(page.path) + '#post-comment')
i.fa-solid.fa-spinner.fa-spin
when 'Disqusjs'
+countBlock
a.disqusjs-comment-count(href=full_url_for(page.path) + '#post-comment')
i.fa-solid.fa-spinner.fa-spin
when 'Valine'
+countBlock
a(href=url_for(page.path) + '#post-comment' itemprop="discussionUrl")
span.valine-comment-count(data-xid=url_for(page.path) itemprop="commentCount")
i.fa-solid.fa-spinner.fa-spin
when 'Waline'
+countBlock
a(href=url_for(page.path) + '#post-comment')
span.waline-comment-count(data-path=url_for(page.path))
i.fa-solid.fa-spinner.fa-spin
when 'Gitalk'
+countBlock
a(href=url_for(page.path) + '#post-comment')
span.gitalk-comment-count
i.fa-solid.fa-spinner.fa-spin
when 'Twikoo'
+countBlock
a(href=url_for(page.path) + '#post-comment')
span#twikoo-count
i.fa-solid.fa-spinner.fa-spin
when 'Facebook Comments'
+countBlock
a(href=url_for(page.path) + '#post-comment')
span.fb-comments-count(data-href=urlNoIndex())
when 'Remark42'
+countBlock
a(href=url_for(page.path) + '#post-comment')
span.remark42__counter(data-url=urlNoIndex())
i.fa-solid.fa-spinner.fa-spin
when 'Artalk'
+countBlock
a(href=url_for(page.path) + '#post-comment')
span.artalk-count
i.fa-solid.fa-spinner.fa-spin

找到[根目录】\themes\butterfly\layout\includes\mixins里面的post_ui.pug

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
.article-meta-wrap
if (theme.post_meta.page.date_type)
span.post-meta-date
if (theme.post_meta.page.date_type === 'both')
i.far.fa-calendar-alt
span.article-meta-label=_p('post.created')
time.post-meta-date-created(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date))=date(article.date, config.date_format)
span.article-meta-separator |
i.fas.fa-history
span.article-meta-label=_p('post.updated')
time.post-meta-date-updated(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated))=date(article.updated, config.date_format)
else
- let data_type_updated = theme.post_meta.page.date_type === 'updated'
- let date_type = data_type_updated ? 'updated' : 'date'
- let date_icon = data_type_updated ? 'fas fa-history' :'far fa-calendar-alt'
- let date_title = data_type_updated ? _p('post.updated') : _p('post.created')
i(class=date_icon)
span.article-meta-label=date_title
time(datetime=date_xml(article[date_type]) title=date_title + ' ' + full_date(article[date_type]))=date(article[date_type], config.date_format)
if (theme.post_meta.page.categories && article.categories.data.length > 0)
span.article-meta
span.article-meta-separator |
i.fas.fa-inbox
each item, index in article.categories.data
a(href=url_for(item.path)).article-meta__categories #[=item.name]
if (index < article.categories.data.length - 1)
i.fas.fa-angle-right.article-meta-link
if (theme.post_meta.page.tags && article.tags.data.length > 0)
span.article-meta.tags
span.article-meta-separator |
i.fas.fa-tag
each item, index in article.tags.data
a(href=url_for(item.path)).article-meta__tags #[=item.name]
if (index < article.tags.data.length - 1)
span.article-meta-link #[='•']

修改右下角的设置标签不转动

如果我不用墨水屏就原谅它了,但我确实要用,所以必须把它设置成静止的免得消耗我博客的寿命,找到[根目录]\themes\butterfly\layout\includes,打开rightside.pug。

1
2
3
4
5
6
7
if is_post()
if (readmode || translate.enable || (darkmode.enable && darkmode.button))
button#rightside-config(type="button" title=_p("rightside.setting"))
i.fas.fa-cog.fa-spin
else if translate.enable || (darkmode.enable && darkmode.button)
button#rightside-config(type="button" title=_p("rightside.setting"))
i.fas.fa-cog.fa-spin

修改图标部分,注意要替换干净,我是用fa-solid.fa-gear替换了这部分内容,刷新了之后也确实是不动了。

butterfly磁卡重构

是由Akilar大佬重写的教程,内容全部参见这里。但经检验新版hexo无法正确加载,所以慎用。