再次印证了 bug 是永远处理不完的...博客归档页面展开收缩功能想着是默认显示当月和上一个月的归档信息,其它默认隐藏。这样做的目的是为了能够始终保持归档页面有足够的归档信息始终显示。但进入新的一年后发现发表文章后就只显示了新的一年一月份的,而上一年度十二月份的归档信息被隐藏。查看代码发现目前的实现是在每个年份内部重置月份计数器,导致只显示当前年份的前两个月份...
修复思路:
引入全局月份计数器: 在函数开始时,初始化一个全局的月份计数器 $global_month_counter,用于跟踪已经显示的月份数量。
调整年份和月份的显示逻辑: 在遍历每个年份和月份时,使用 $global_month_counter 来判断是否显示当前月份。如果 $global_month_counter 小于2,则显示该月份,并递增计数器。否则,隐藏该月份。
确保年份的显示逻辑正确: 由于月份可能跨年份,需要确保年份部分始终显示,但仅在包含至少一个默认显示的月份时才显示其下的月份内容。
现对修复后的代码记录如下:
<?php /* Template Name: 综合归档 */ get_header(); function generate_archive_item($data, $chinese_months, $type = 'post') { $output = ''; $global_month_counter = 0; // 全局月份计数器 $default_display_months = 2; // 默认显示的月份数量 foreach ( $data as $year => $year_data ) { $output .= '<div class="timeline-item" data-toggle="year"> <div class="timeline-left"> <div class="timeline-icon icon-lg"><i class="czs-medal"></i></div> </div> <div class="timeline-content pt-0"> <div class="tile"> <div class="tile-content"> <p class="tile-subtitle text-large text-bold">' . esc_html( $year_data['year'] ) . '</p> </div> </div> </div> </div>'; $output .= '<div class="year-months" style="display: block;">'; // 始终显示年份部分 foreach ( $year_data['months'] as $month => $month_data ) { // 判断是否为默认显示的月份 $is_default = ($global_month_counter < $default_display_months); if ($is_default) { $global_month_counter++; } $output .= '<div class="timeline-item" data-toggle="month"> <div class="timeline-left"> <div class="timeline-icon icon-md"></div> </div> <div class="timeline-content pt-0"> <div class="tile"> <div class="tile-content"> <p class="tile-subtitle text-medium text-bold">' . esc_html( $chinese_months[$month] ) . '</p> </div> <div class="tile-action"> <span class="chip">' . count( $month_data['articles'] ) . '</span> </div> </div> </div> </div>'; $output .= '<div class="timeline-articles" style="display: ' . ($is_default ? 'block' : 'none') . ';">'; foreach ( $month_data['articles'] as $article ) { $output .= '<div class="timeline-item"> <div class="timeline-left"> <div class="timeline-icon"></div> </div> <div class="timeline-content pt-0"> <div class="tile"> <div class="tile-content"> <p class="tile-subtitle"> <a href="' . esc_url( $article['permalink'] ) . '">' . esc_html( $article['title'] ) . '</a> - ' . esc_html( $article['month-day'] ) . ' </p> </div> </div> </div> </div>'; } $output .= '</div>'; } $output .= '</div>'; } return $output; } ?> <article class="article archives" itemscope itemtype="https://schema.org/Article"> <?php if ( have_posts() ) { while ( have_posts() ) { the_post(); require_once( "inc/article-header.php" ); } } ?> <div class="archive-tabs"> <button class="tab-link active" data-tab="posts">文章归档</button> <button class="tab-link" data-tab="notes">笔记归档</button> </div> <div class="timeline" itemprop="articleBody"> <div class="archive-content" id="posts" style="display: block;"> <?php $archives = get_my_archives( 'post' ); $chinese_months = [ '01' => '一月', '02' => '二月', '03' => '三月', '04' => '四月', '05' => '五月', '06' => '六月', '07' => '七月', '08' => '八月', '09' => '九月', '10' => '十月', '11' => '十一月', '12' => '十二月', ]; echo generate_archive_item( $archives, $chinese_months ); ?> </div> <div class="archive-content" id="notes" style="display: none;"> <?php $archives = get_my_archives( 'note' ); echo generate_archive_item( $archives, $chinese_months, 'note' ); ?> </div> </div> </article> <script> document.addEventListener("DOMContentLoaded", function () { const tabLinks = document.querySelectorAll('.tab-link'); const archiveContents = document.querySelectorAll('.archive-content'); tabLinks.forEach(link => { link.addEventListener('click', function () { const activeTab = this.getAttribute('data-tab'); tabLinks.forEach(l => l.classList.remove('active')); archiveContents.forEach(content => content.style.display = 'none'); this.classList.add('active'); document.getElementById(activeTab).style.display = 'block'; }); }); const toggleVisibility = (selector) => { document.querySelectorAll(selector).forEach(header => { header.addEventListener('click', function () { const sibling = this.nextElementSibling; sibling.style.display = sibling.style.display === 'block' ? 'none' : 'block'; }); }); }; toggleVisibility('.timeline-item[data-toggle="year"]'); toggleVisibility('.timeline-item[data-toggle="month"]'); }); </script> <?php get_footer(); ?>
通过上述修改,无论当前月份是否跨年,模板都会默认显示最近的两个月份。例如,当前是 2025 年 01 月,默认显示 2025 年 01 月和 2024 年 12 月。