mohのAI正在绞尽脑汁想思路ING···
mohのAI摘要
mohのAI-Lite

魔改教程

注意: 由于本次魔改修改了主题内部文件,一定要注意提前备份! 一定要注意提前备份! 一定要注意提前备份!

分类条

我原有的分类条采用的是小冰的分类卡片,但是我中感觉占用空间较大,且出现多个分类会显示滚动条.我个人觉得不够美观,因此在网上查找分类条的魔改,正好看到了 liushen 博主发的文章,由于liushen博主的魔改教程是适用于旧版的butterfly主题,而我采用的是新版的butterfly主题,因此做了这篇教程.如果没有魔改基础建议紧跟教程,如果有任何问题可以在下方评论区提出。

效果真实图

image-20260404214007957

教程

1、新建文件 [BlogRoot]\themes\butterfly\layout\includes\categoryBar.pug文件,写入

1
2
3
4
5
6
7
8
9
10
11
.category-bar-items#category-bar-items(class=is_home() ? 'home' : '')
.category-bar-item(class=is_home() ? 'select' : '', id="category-bar-home")
a(href=url_for('/'))= __('博客首页')
each item in site.categories.find({ parent: { $exists: false } }).data
.category-bar-item(class=select ? (select === item.name ? 'select' : '') : '', id=item.name)
a(href=url_for(item.path))= item.name
.category-bar-item
a(href=url_for('/archives/'))= __('文章存档')
div.category-bar-right
a.category-bar-more(href=url_for('/categories/'))= __('更多分类')

以上就是该滚动条的结构,下面我们开始实现样式的定义,

2、新建文件[BlogRoot]\themes\butterfly\source\css\_layout\category-bar.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
#category-bar
padding 7px 11px
background var(--card-bg)
border-radius 8px
display flex
white-space nowrap
overflow hidden
transition 0.3s
height 50px
width 100%
justify-content space-between
user-select none
align-items center
margin-bottom 20px

.category-bar-right
display flex
border-radius 8px
align-items center

.category-bar-more
margin-left 4px
margin-right 4px
font-weight 700
border-radius 8px
padding 0 8px

.category-bar-items
width 100%
white-space nowrap
overflow-x scroll
scrollbar-width: none
-ms-overflow-style: none
overflow-y hidden
display flex
border-radius 8px
align-items center
height 30px

&::-webkit-scrollbar
display: none

.category-bar-item
a
padding .1rem .5rem
margin-right 6px
font-weight 700
border-radius 8px
display flex
align-items center
height 30px

&.select
a
background #3eb8be
color var(--btn-color)

3、打开文件[BlogRoot]\themes\butterfly\layout\includes\mixins\indexPostUI.pug

方式一:添加以下两行代码,删除+

1
2
3
4
5
6
7
8
9
mixin indexPostUI()
- const indexLayout = theme.index_layout
- const masonryLayoutClass = (indexLayout === 6 || indexLayout === 7) ? 'masonry' : ''
#recent-posts.recent-posts.nc(class=masonryLayoutClass)
+ #category-bar.category-bar
+ include ../categoryBar.pug
.recent-post-items
each article, index in page.posts.data

方式二:直接复制下面一份代码直接对整个文件进行替换

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
mixin indexPostUI()
- const indexLayout = theme.index_layout
- const masonryLayoutClass = [6, 7].includes(indexLayout) ? 'masonry' : ''
#recent-posts.recent-posts.nc(class=masonryLayoutClass)
#category-bar.category-bar
include ../categoryBar.pug
.recent-post-items
each article, index in page.posts.data
.recent-post-item
- const link = article.link || article.path
- const title = article.title || _p('no_title')
- const leftOrRight = indexLayout === 3 ? (index % 2 === 0 ? 'left' : 'right') : (indexLayout === 2 ? 'right' : '')
- const postCover = article.cover
- const noCover = article.cover === false || !theme.cover.index_enable ? 'no-cover' : ''

if postCover && theme.cover.index_enable
.post_cover(class=leftOrRight)
a(href=url_for(link) title=title)
if article.cover_type === 'img'
img.post-bg(src=url_for(postCover) onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'` alt=title)
else
div.post-bg(style=`background: ${postCover}`)
.recent-post-info(class=noCover)
a.article-title(href=url_for(link) title=title)
if globalPageType === 'home' && (article.top || article.sticky > 0)
i.fas.fa-thumbtack.sticky
= title
.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
- const isUpdatedType = theme.post_meta.page.date_type === 'updated'
- const dateType = isUpdatedType ? 'updated' : 'date'
- const dateIcon = isUpdatedType ? 'fas fa-history' : 'far fa-calendar-alt'
- const dateTitle = isUpdatedType ? _p('post.updated') : _p('post.created')
i(class=dateIcon)
span.article-meta-label= dateTitle
time(datetime=date_xml(article[dateType]) title=dateTitle + ' ' + full_date(article[dateType]))= date(article[dateType], config.date_format)
if theme.post_meta.page.categories && article.categories.data.length > 0
span.article-meta
span.article-meta-separator |
each item, index in article.categories.data
i.fas.fa-inbox
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.length > 0
span.article-meta.tags
span.article-meta-separator |
each item, index in article.tags.data
i.fas.fa-tag
a(href=url_for(item.path)).article-meta__tags #[=item.name]
if index < article.tags.data.length - 1
span.article-meta-link #[='•']

mixin countBlockInIndex
- needLoadCountJs = true
span.article-meta
span.article-meta-separator |
i.fas.fa-comments
if block
block
span.article-meta-label= ' ' + _p('card_post_count')

if theme.comments.card_post_count && theme.comments.use
- const commentSystem = theme.comments.use[0]
- const commentLink = url_for(link) + '#post-comment'

case commentSystem
when 'Disqus'
when 'Disqusjs'
+countBlockInIndex
a.disqus-count(href=full_url_for(link) + '#post-comment')
i.fa-solid.fa-spinner.fa-spin
when 'Valine'
+countBlockInIndex
a(href=commentLink)
span.valine-comment-count(data-xid=url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Waline'
+countBlockInIndex
a(href=commentLink)
span.waline-comment-count(data-path=url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Twikoo'
+countBlockInIndex
a.twikoo-count(href=commentLink)
i.fa-solid.fa-spinner.fa-spin
when 'Facebook Comments'
+countBlockInIndex
a(href=commentLink)
span.fb-comments-count(data-href=urlNoIndex(article.permalink))
when 'Remark42'
+countBlockInIndex
a(href=commentLink)
span.remark42__counter(data-url=urlNoIndex(article.permalink))
i.fa-solid.fa-spinner.fa-spin
when 'Artalk'
+countBlockInIndex
a(href=commentLink)
span.artalk-count(data-page-key=url_for(link))
i.fa-solid.fa-spinner.fa-spin

//- Display the article introduction on homepage
- const content = postDesc(article)
if content
.content!=content

if theme.ad && theme.ad.index
if (index + 1) % 3 === 0
.recent-post-item.ads-wrap!= theme.ad.index

include ../pagination.pug

4、打开[BlogRoot]\themes\butterfly\source\js\main.js,添加js函数,比如我添加到了778行左右,switchComments函数的上面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 自己写的,实现功能切换类别表
*/
const setCategoryBarActive = () => {
const categoryBar = document.querySelector("#category-bar");
const currentPath = decodeURIComponent(window.location.pathname);
const isHomePage = currentPath === GLOBAL_CONFIG.root;

if (categoryBar) {
const categoryItems = categoryBar.querySelectorAll(".category-bar-item");
categoryItems.forEach(item => item.classList.remove("select"));

const activeItemId = isHomePage ? "category-bar-home" : currentPath.split("/").slice(-2, -1)[0];
const activeItem = document.getElementById(activeItemId);

if (activeItem) {
activeItem.classList.add("select");
}
}
};

然后再在引用部分执行这个函数,在同一个文件,找到下面的函数并添加函数的调用,位置看下方注释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
window.refreshFn = function () {
initAdjust()

if (GLOBAL_CONFIG_SITE.isPost) {
GLOBAL_CONFIG.noticeOutdate !== undefined && addPostOutdateNotice()
GLOBAL_CONFIG.relativeDate.post && relativeDate(document.querySelectorAll('#post-meta time'))
} else {
GLOBAL_CONFIG.relativeDate.homepage && relativeDate(document.querySelectorAll('#recent-posts time'))
GLOBAL_CONFIG.runtime && addRuntime()
addLastPushDate()
toggleCardCategory()
setCategoryBarActive() // 自己加的,用于切换类别栏目
}

5、打开[BlogRoot]/_config.butterfly.yml 文件中修改以下配置

1
category_ui: index

最后,hexo三件套,应该就能看到效果了!请根据自己的需要进行定制化。

由于我对框架进行了魔改,因此出现了以下bug

就是出现在对应的页面不会显示对应的tag

image-20260404225640499

因此需要在自定义的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
/*======================================================*/


/* 分类页面分页样式修复 - 确保当前页背景色正常显示 */
#category .pagination .page-number.current {
background: var(--theme-paginator-color, #00c4b6) !important;
color: #fff !important;
}

/* 归档页面分页样式保持一致 */
#archive .pagination .page-number.current {
background: var(--theme-paginator-color, #00c4b6) !important;
color: #fff !important;
}

/* 标签页面分页样式保持一致 */
#tag .pagination .page-number.current {
background: var(--theme-paginator-color, #00c4b6) !important;
color: #fff !important;
}

/* 确保分页按钮在悬停时也有正确的样式 */
#category .pagination > *:not(.space):not(.current):hover,
#archive .pagination > *:not(.space):not(.current):hover,
#tag .pagination > *:not(.space):not(.current):hover {
background: var(--btn-hover-color) !important;
color: var(--btn-color) !important;
}


参考文章