我的Butterfly美化
前言
关于我博客的整个搭建过程可以参照我知乎这篇文章
有涉及到修改源码的部分,Butterfly 版本3.8.3
优先考虑顺序:插件 > 自定义css > 魔改(改源码)
背景板
该调整不涉及源码修改。原先的主题分为了上中下三层结构,我觉得过于花了,统一改为了一种背景,文章栏与侧边栏透明思路也简单,只留背景,其余部分去色,替换为背景图的方式,背景0.9透明,主题色做出了调整,可以在主题文件中的theme_color中修改
效果预览(旧)
配置
在themes/source/css下创建自己的css文件
加入以下代码,前提是将_config.butterfly文件中的background不能为空且与index_img一致
首先是调整背景板为一体(但在暗黑模式下,页脚还会出现阴影快)
1 | /* 页脚去色 */ |
替换为阿里图标
效果预览
配置
阿里巴巴矢量图标库提供了三种引入方案,其实也就是两种,一种单色,一种多色(需要改源码)既然都是引入,不会真有人自己写css吧
推荐symbol引入这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。本教程来源于这篇文章
新建图标
- 进入阿里巴巴矢量图标库 , 注册登录
- 加入自己需要的图标
- 添加到项目中
引入图标
官方提供了三种方式,我只列举我的彩色实现方案,彩色的本质是因为它是一个svg
,源码中不支持这种能力,所以需要调整源码
- 修改 [root]\themes\butterfly\layout\includes\header\menu_item.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
36
37
38
39
40
41
42
43
44if theme.menu
//- for mobile sidebar
- let sidebarChildHide = theme.hide_sidebar_menu_child ? 'hide' : ''
.menus_items
each value, label in theme.menu
if typeof value !== 'object'
.menus_item
a.site-page(href=url_for(trim(value.split('||')[0])))
if value.split('||')[1]
- i.fa-fw(class=trim(value.split('||')[1]))
+ - var icon_value = trim(value.split('||')[1])
+ if icon_value.substring(0,2)=="fa"
+ i.fa-fw(class=icon_value)
+ else if icon_value.substring(0,4)=="icon"
+ svg.icon(aria-hidden="true")
+ use(xlink:href=`#`+ icon_value)
span=' '+label
else
.menus_item
a.site-page(href='javascript:void(0);')
if label.split('||')[1]
- i.fa-fw(class=trim(label.split('||')[1]))
+ - var icon_label = trim(label.split('||')[1])
+ if icon_label.substring(0,2)=="fa"
+ i.fa-fw(class=icon_label)
+ else if icon_label.substring(0,4)=="icon"
+ svg.icon(aria-hidden="true")
+ use(xlink:href=`#`+ icon_label)
span=' '+ trim(label.split('||')[0])
i.fas.fa-chevron-down.expand(class=sidebarChildHide)
ul.menus_item_child
each val,lab in value
li
a.faa-parent.animated-hover.site-page.child(href=url_for(trim(val.split('||')[0])))
if val.split('||')[1]
- i.fa-fw(class=trim(val.split('||')[1]))
+ - var icon_val = trim(val.split('||')[1])
+ if icon_val.substring(0,2)=="fa"
+ i.fa-fw(class=icon_val)
+ else if icon_val.substring(0,4)=="icon"
+ svg.icon(aria-hidden="true")
+ use(xlink:href=`#`+ icon_val)
span=' '+ lab - 直接复制版
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
41if theme.menu
//- for mobile sidebar
- let sidebarChildHide = theme.hide_sidebar_menu_child ? 'hide' : ''
.menus_items
each value, label in theme.menu
if typeof value !== 'object'
.menus_item
a.site-page(href=url_for(trim(value.split('||')[0])))
if value.split('||')[1]
- var icon_value = trim(value.split('||')[1])
if icon_value.substring(0,2)=="fa"
i.fa-fw(class=icon_value)
else if icon_value.substring(0,4)=="icon"
svg.icon(aria-hidden="true")
use(xlink:href=`#`+ icon_value)
span=' '+label
else
.menus_item
a.site-page(href='javascript:void(0);')
if label.split('||')[1]
- var icon_label = trim(label.split('||')[1])
if icon_label.substring(0,2)=="fa"
i.fa-fw(class=icon_label)
else if icon_label.substring(0,4)=="icon"
svg.icon(aria-hidden="true")
use(xlink:href=`#`+ icon_label)
span=' '+ trim(label.split('||')[0])
i.fas.fa-chevron-down.expand(class=sidebarChildHide)
ul.menus_item_child
each val,lab in value
li
a.site-page.child(href=url_for(trim(val.split('||')[0])))
if val.split('||')[1]
- var icon_val = trim(val.split('||')[1])
if icon_val.substring(0,2)=="fa"
i.fa-fw(class=icon_val)
else if icon_val.substring(0,4)=="icon"
svg.icon(aria-hidden="true")
use(xlink:href=`#`+ icon_val)
span=' '+ lab - 使用方式上面是菜单的,接下来替换social图标
1
2
3
4
5
6
7
8
9
10menu:
首页: / || icon-shouye_huaban
文章 || icon-wenzhang :
归档: /archives/ || icon-shijianzhou
标签: /tags/ || icon-biaoqian-copy-copy
分类: /categories/ || icon-ziyuan
闲言碎语: /talk/ || icon-liuyanban
友情链接: /link/ || icon-lianjie
留言板: /board/ || icon-xiaoxi
关于: /about/ || icon-bixin1 - 修改 [root]\themes\butterfly\layout\includes\header\social.pug, 替换为以下代码
1
2
3
4
5
6
7
8
9each value, title in theme.social
a.social-icon(href=url_for(trim(value.split('||')[0])) target="_blank" title=title === undefined ? '' : trim(title))
if value.split('||')[1]
- var icon_value = trim(value.split('||')[1])
if icon_value.substring(0,2)=="fa"
i.fa-fw(class=icon_value)
else if icon_value.substring(0,4)=="icon"
svg.icon(aria-hidden="true")
use(xlink:href=`#`+ icon_value) - 使用方式
1
2
3
4social:
gitee: https://github.com/bigli97 || icon-gitee
zhihu: https://www.zhihu.com/people/da-hu-you-55-56 || icon-zhihu
juejin: https://juejin.cn/user/2093100615603101 || icon-juejin
说说
不怕折腾的可以考虑。我这里配置了两套,一个手机发用于首页顶部显示,一个电脑发用于闲言碎语
前置要求 参照官方文档的LeanCloud 的相关准备环节,一定要每一步都配置
调用方式 采用插件的方式
- 前往 LeanCloud 国际版,注册账号。
- 注册完成之后根据 LeanCloud 的提示绑定手机号和邮箱。
- 绑定完成之后点击
创建应用
,应用名称随意,接着在结构化数据
中创建class
,命名为shuoshuo
。- 在你新建的应用中找到
结构化数据
下的用户
。点击添加用户
,输入想用的用户名及密码。- 回到
结构化数据
中,点击class
下的shuoshuo
。找到权限,在Class 访问权限
中将add_fields
以及create
权限设置为指定用户,输入你刚才输入的用户名会自动匹配。为了安全起见,将delete
和update
也设置为跟它们一样的权限。- 然后新建一个名为
atComment
的class,权限什么的使用默认的即可。- 点击
class
下的_User
添加列,列名称为img
,默认值填上你这个账号想要用的发布说说的头像url,这一项不进行配置,说说头像会显示为默认头像 —— Artitalk 的 logo。- 在最菜单栏中找到设置-> 应用 keys,记下来
AppID
和AppKey
,一会会用。- 最后将
_User
中的权限全部调为指定用户,或者数据创建者,为了保证不被篡改用户数据已达到强制发布说说。
效果预览
配置
安装Artitalk插件
1 | npm install hexo-butterfly-artitalk |
修改主题配置文件
1 | artitalk: |
评论
前期用的valine,后来换为了twikoo,主要是valine不好管理,但配置起来挺快的,而twikoo配置起来会麻烦一点,不怕折腾的推荐twikoo
这里就只说下twikoo吧,valine有兴趣可以看官方文档
效果预览
配置
twikoo官方文档推荐了4种云函数部署方式,官方建议Vercel部署 ,优点是免费
同样,严格按照步骤来,不过这里我推荐观看视频教程,我当时就给整晕了
- 申请 MongoDB (opens new window)账号
- 创建免费 MongoDB 数据库,区域推荐选择
AWS / N. Virginia (us-east-1)
- 在 Clusters 页面点击 CONNECT,按步骤设置允许所有 IP 地址的连接(为什么? (opens new window)),创建数据库用户,并记录数据库连接字符串,请将连接字符串中的
<password>
修改为数据库密码- 申请 Vercel (opens new window)账号
- 点击以下按钮将 Twikoo 一键部署到 Vercel
- 添加环境变量
MONGODB_URI
到 Vercel,值为第 3 步的数据库连接字符串- Vercel 环境地址(包含
https://
前缀)即为您的环境 id
留言板
加了一个效果,npm插件的方式,很奈斯,来源于作者Akilar
效果预览
配置
安装插件
1 | npm install hexo-butterfly-envelope --save |
主题配置文件添加如下
1 | envelope_comment: |
古诗词
来源于HEO,需要修改源码,我把诗词这块转移到了banner图中
效果预览
配置
在themes/butterfly/layout/includes/widget下新建card_poem.pug
1 | #card-poem.card-widget |
在themes/butterfly/layout/includes/widget/index.pug下添加
1 | !=partial('includes/widget/card_poem', {}, {cache: true}) |
位置如下
在主题中引入两个css
1 | - <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/zhheo/JS-Heo@main/mainColor/heoMainColor.css"> |
历史上的今天
一个很有意思的插件,来源于小冰
效果预览
配置
1 | npm i hexo-history-calendar --save |
在hexo的配置文件中添加如下
1 | history_calendar: |
微博热搜
对于我这种不想下微博,又只想看热搜的人来说是再适合不过了,来源于这篇文章
该技术通过增加侧边栏模块,爬虫的方式实现,同理知乎的热搜如果能爬到,也可用同样的方式
效果预览
配置
创建card_weibo.js,或者直接引用现成的js路径
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23fetch('https://weibo-top-api.vercel.app/api').then(data => data.json()).then(data => {
let html = '<style>.weibo-new{background:#ff3852}.weibo-hot{background:#ff9406}.weibo-jyzy{background:#ffc000}.weibo-recommend{background:#00b7ee}.weibo-adrecommend{background:#febd22}.weibo-friend{background:#8fc21e}.weibo-boom{background:#bd0000}.weibo-topic{background:#ff6f49}.weibo-topic-ad{background:#4dadff}.weibo-boil{background:#f86400}#weibo-container{overflow-y:auto;-ms-overflow-style:none;scrollbar-width:none}#weibo-container::-webkit-scrollbar{display:none}.weibo-list-item{display:flex;flex-direction:row;justify-content:space-between;flex-wrap:nowrap}.weibo-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-right:auto}.weibo-num{float:right}.weibo-hotness{display:inline-block;padding:0 6px;transform:scale(.8) translateX(-3px);color:#fff;border-radius:8px}</style>'
html += '<div class="weibo-list">'
let hotness = {
'爆': 'weibo-boom',
'热': 'weibo-hot',
'沸': 'weibo-boil',
'新': 'weibo-new',
'荐': 'weibo-recommend',
'影': 'weibo-jyzy',
'剧': 'weibo-jyzy',
'综': 'weibo-jyzy'
}
for (let item of data) {
html += '<div class="weibo-list-item"><div class="weibo-hotness ' + hotness[(item.hot || '荐')] + '">' + (item.hot || '荐') + '</div>'
+ '<span class="weibo-title"><a title="' + item.title + '"href="' + item.url + '" target="_blank" rel="external nofollow noreferrer">' + item.title + '</a></span>'
+ '<div class="weibo-num"><span>' + item.num + '</span></div></div>'
}
html += '</div>'
document.getElementById('weibo-container').innerHTML = html
}).catch(function (error) {
console.log(error);
});在 config.butterfly.yml 增加以下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20aside:
enable: true
hide: true
button: true
...
+ card_weibo:
+ enable: true
# CDN
# Don't modify the following settings unless you know how they work
# 非必要請不要修改
CDN:
# main
main_css: /css/index.css
jquery: https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js
main: /js/main.js
utils: /js/utils.js
+ #weibo
+ card_weibo: https://cdn.jsdelivr.net/gh/Eurkon/CDN/hexo/js/card_weibo.js在 [root]\themes\butterfly\layout\includes\widget 目录下创建 card_weibo.pug 文件,添加以下内容
1
2
3
4
5
6
7
8if theme.aside.card_weibo.enable
.card-widget.card-weibo
.card-content
.item-headline
i.fab.fa-weibo
span= _p('微博热搜')
#weibo-container(style="width: 100%; height: 150px;font-size: 95%;")
script(defer data-pjax src=url_for(theme.CDN.card_weibo))在 [Blogroot]\themes\butterfly\layout\includes\widget\index.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#aside-content.aside-content
//- post
if is_post()
if showToc && theme.toc.style_simple
.sticky_layout
include ./card_post_toc.pug
else
!=partial('includes/widget/card_author', {}, {cache: true})
!=partial('includes/widget/card_announcement', {}, {cache: true})
.sticky_layout
if showToc
include ./card_post_toc.pug
+ !=partial('includes/widget/card_weibo', {}, {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})
.sticky_layout
+ !=partial('includes/widget/card_weibo', {}, {cache: true})
!=partial('includes/widget/card_recent_post', {}, {cache: true})
!=partial('includes/widget/card_ad', {}, {cache: true})
!=partial('includes/widget/card_newest_comment', {}, {cache: true})
!=partial('includes/widget/card_categories', {}, {cache: true})
!=partial('includes/widget/card_tags', {}, {cache: true})
!=partial('includes/widget/card_archives', {}, {cache: true})
!=partial('includes/widget/card_webinfo', {}, {cache: true})
!=partial('includes/widget/card_self', {}, {cache: true})hexo三连
1
hexo clean && hexo g && hexo s