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

教程
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 文件中修改以下配置
最后,hexo三件套,应该就能看到效果了!请根据自己的需要进行定制化。
由于我对框架进行了魔改,因此出现了以下bug
就是出现在对应的页面不会显示对应的tag

因此需要在自定义的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; }
|
参考文章