1、在根目录(不是主题目录)的 _config.yml
修改(如果没有就添加)per_page 的值为 0
archive_generator: per_page: 0 yearly: true monthly: true daily: false
然后去主题的 _config.yml
中把侧边栏的归档去掉,因为都在一页上面折叠显示了,这个侧边栏的月份归档意义不大了。另外就是,通过侧边进入的页面会有bug,所有文章会自动展开。
其实是可以做一个:从侧边栏进入的页面自动定位到目前月份的位置,然后自动展开月份下的文章。但是我觉得这样就过于折腾了,侧边栏的月份归档的意义对我也不大,索性就怎么简单怎么来了。
aside: card_categories: enable: false
之后来到 themes/butterfly/layout/archive.pug
将 +articleSort(page.posts)
修改为 +articleSort(site.posts.sort('date', -1))
,从而获取全站所有文章数据。
删除 include includes/pagination.pug
这一行,目的是移除分页导航栏
extends includes/layout.pug block content include ./includes/mixins/article-sort.pug #archive .article-sort-title= `${_p('page.articles')} - ${getArchiveLength()}` +articleSort(site.posts.sort('date', -1)) //include includes/pagination.pug
2、创建 themes/butterfly/scripts/helpers/archive_helpers.js
内容为:
hexo.extend .helper .register ('getMonthArticleCount' , function (posts, year, month ) { let count = 0 ; posts.forEach (article => { if (this .date (article.date , 'YYYY' ) === year && this .date (article.date , 'MM' ) === month) { count++; } }); return count; });
这里是创建了 getMonthArticleCount
函数,用于统计指定年月中包含的文章数量。目的是为在月份标题上显示文章计数(如“八月 (2篇文章)”)提供数据支持。
3、修改 themes/butterfly/layout/includes/mixins.article-sort.pug
(下面代码全部覆盖)内容为:
mixin articleSort(posts) .article-sort - let currentYear = 0 - let currentMonth = 0 - posts.forEach(post => { - const postYear = date(post.date, 'YYYY') - const postMonth = date(post.date, 'MM') - const noCoverClass = post.cover === false || !theme.cover.archives_enable ? 'no-article-cover' : '' - const title = post.title || _p('no_title') if postYear !== currentYear - currentYear = postYear - currentMonth = 0 // 新的一年,重置月份跟踪器 .article-sort-item.year= postYear if postMonth !== currentMonth - currentMonth = postMonth - const monthName = date(post.date, config.month_format || 'MMMM') // 使用配置中的月份格式,默认为 'MMMM' - const articleCountInMonth = getMonthArticleCount(posts, postYear, postMonth) // 新增月份头部,可点击 .archive-month-header i.fas.fa-folder.folder-icon span.month-name= `${monthName} (${articleCountInMonth}篇文章)` // 文章条目,默认会被JS隐藏 .article-sort-item(class=noCoverClass) if post.cover && theme.cover.archives_enable a.article-sort-item-img(href=url_for(post.path) title=title) if post.cover_type === 'img' img(src=url_for(post.cover) alt=title onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'`) else div(style=`background: ${post.cover}`) .article-sort-item-info .article-sort-item-time i.far.fa-calendar-alt time.post-meta-date-created(datetime=date_xml(post.date) title=_p('post.created') + ' ' + full_date(post.date))= date(post.date, config.date_format) a.article-sort-item-title(href=url_for(post.path) title=title)= title - })
这里修改了 mixin articleSort
,在原有的按年分组逻辑之上,增加了按月分组的逻辑。为每个月份创建了一个可点击的 <div class="archive-month-header">
元素,并将该月的所有文章放在其后。目的是生成支持折叠功能的 HTML 结构。
4、在 themes/butterfly/source/css/_page/archive.styl
最后添加:
.archive-month-header position : relative display : flex align-items : center margin : 15px 0 15px 10px padding : 8px 15px cursor : pointer border-radius : 8px background : var (--card-bg) box-shadow : var (--card-shadow) transition : all .3s ease-in-out &:hover transform : translateX (5px ) .folder-icon margin-right : 12px transition : transform .3s ease .month-name font-size : 1.1em font-weight : bold color : var (--font-color) &.active .folder-icon transform : rotate (90deg ) color : var (--pseudo-hover) .article-sort-item &.is-hidden display : none .archive-month-header + .article-sort-item margin-left : 30px .article-sort-item &:not (.year) + .article-sort-item :not (.year) margin-left : 30px
5、创建 themes/butterfly/layout/includes/archive-collapse.pug
内容为:
script. function initArchiveCollapse() { //- console.log('initArchiveCollapse function called!'); const archivePage = document.getElementById('archive'); if (!archivePage) { //- console.log('Archive page element not found.'); return; } // 查找所有月份标题,如果一个都没有,就没必要继续了 const monthHeaders = archivePage.querySelectorAll('.archive-month-header'); if (monthHeaders.length === 0) { //- console.log('No month headers found.'); return; } // 默认隐藏所有文章条目 const allArticles = archivePage.querySelectorAll('.article-sort-item:not(.year)'); allArticles.forEach(article => { article.classList.add('is-hidden'); }); monthHeaders.forEach(header => { // 避免重复绑定事件 if (header.classList.contains('archive-event-bound')) { //- console.log('Skipping already bound header:', header); return; } header.classList.add('archive-event-bound'); header.addEventListener('click', function () { this.classList.toggle('active'); const icon = this.querySelector('.folder-icon'); if (icon) { if (this.classList.contains('active')) { icon.classList.remove('fa-folder'); icon.classList.add('fa-folder-open'); } else { icon.classList.remove('fa-folder-open'); icon.classList.add('fa-folder'); } } let nextSibling = this.nextElementSibling; while (nextSibling && nextSibling.classList.contains('article-sort-item') && !nextSibling.classList.contains('year')) { nextSibling.classList.toggle('is-hidden'); nextSibling = nextSibling.nextElementSibling; } }); }); } // 将执行函数包装起来 function executeScript() { //- console.log('executeScript called!'); // 使用一个短暂的延迟来确保长列表完全渲染完毕 setTimeout(initArchiveCollapse, 100); } document.addEventListener('DOMContentLoaded', executeScript); document.addEventListener('pjax:complete', executeScript);
这里给予浏览器一个短暂的(100毫秒)缓冲时间,确保庞大的文章列表完全渲染到 DOM 中后,再执行隐藏和绑定事件的脚本,从而修复了页面加载后默认全部展开且无法操作的 Bug。
之后来到 themes/butterfly/layout/includes/additional-js.pug
来到文件最后,添加:
//- Archives page collapse if is_archive() !=partial('includes/archive-collapse', {}, {cache: true})
大功告成!!