其实我一直不太明白几乎所有独立博客里都有这么一个归档页面,它到底起到什么作用呢?竟然让人们如此一致的都设定这个功能。如果只是为了方便快速查找定位过往的文章应该有更好的方式方法吧。算了不琢磨这些有的没得了,反正要是删除这个归档页面感觉也不太合适,还是想法优化一下吧。
随着博客文章的增多,也是时候优化下主题归档页面了。这个主题的归档页面只有年份分组,确实有点过于简单。于是先在网上找了找,看有没有现成的归档页面样式可以拿来用,废了半天劲,挑了好几个试了试,感觉跟主题都不太契合,适配起来也很麻烦。
在看了不少其他家归档页面后,感觉主题自带的归档页面样式还是比较简洁耐看的。于是经过一番折腾,就在现有归档页面基础上增加了月份统计分组,增加了点击年月展开收缩功能,最近一个月默认展开,同时对主题开启 PJAX 进行了适配。现将相关修改代码记录如下:
1.修改主题 core.php 文件内 //获取文章归档 相关代码如下:
function get_my_archives() {
// 尝试从缓存中获取归档数据
if ( false === ( $archives = get_transient( 'my_archives' ) ) ) {
$archives = [];
$posts = get_posts( array(
'numberposts' => -1,
'orderby' => 'post_date',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish',
) );
foreach ( $posts as $post ) {
// 获取年份和月份
$year = date( 'Y', strtotime( $post->post_date ) );
$month = date( 'm', strtotime( $post->post_date ) );
// 初始化年份分组
if ( ! isset( $archives[ $year ] ) ) {
$archives[ $year ] = [
'year' => $year,
'months' => [],
];
}
// 初始化月份分组
if ( ! isset( $archives[ $year ]['months'][ $month ] ) ) {
$archives[ $year ]['months'][ $month ] = [
'month' => $month,
'articles' => [],
];
}
// 添加文章到对应的年份和月份
$archives[ $year ]['months'][ $month ]['articles'][] = [
'month-day' => date( 'm-d', strtotime( $post->post_date ) ),
'permalink' => get_permalink( $post->ID ),
'title' => get_the_title( $post->ID ),
'comments' => get_comments_number( $post->ID ),
];
}
// 将归档数据缓存 12 小时
set_transient( 'my_archives', $archives, 12 * HOUR_IN_SECONDS );
}
return $archives;
}
// 清除归档缓存
function clear_my_archives_cache() {
delete_transient( 'my_archives' );
}
// 在发布、更新或删除文章时清除缓存
add_action( 'save_post', 'clear_my_archives_cache' );
add_action( 'deleted_post', 'clear_my_archives_cache' );
add_action( 'trashed_post', 'clear_my_archives_cache' );
2.修改主题 page-archive.php 文件代码如下:
<?php
/*
Template Name: 文章归档
*/
get_header();
?>
<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="timeline" itemprop="articleBody">
<?php
$archives = get_my_archives();
// 定义月份中文名称
$chinese_months = array(
'01' => '一月',
'02' => '二月',
'03' => '三月',
'04' => '四月',
'05' => '五月',
'06' => '六月',
'07' => '七月',
'08' => '八月',
'09' => '九月',
'10' => '十月',
'11' => '十一月',
'12' => '十二月',
);
$is_first_year = true; // 标记是否是第一个年份
foreach ( $archives as $year => $year_data ): ?>
<!-- 年份分组 -->
<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>
<div class="year-months" style="display: <?= $is_first_year ? 'block' : 'none' ?>;">
<?php
$is_first_month = true; // 标记是否是最新月份
foreach ( $year_data['months'] as $month => $month_data ): ?>
<!-- 月份分组 -->
<div class="timeline-item" data-toggle="month">
<div class="timeline-left">
<div class="timeline-icon icon-md"><i class="czs-calendar"></i></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>
<div class="timeline-articles" style="display: <?= $is_first_month ? 'block' : 'none' ?>;">
<?php
foreach ( $month_data['articles'] as $article ): ?>
<!-- 文章列表 -->
<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>
<?php endforeach; ?>
</div>
<?php
$is_first_month = false; // 第一个月后设置为 false
endforeach; ?>
</div>
<?php
$is_first_year = false; // 第一年后设置为 false
endforeach; ?>
</div>
</article>
<script>
document.addEventListener("DOMContentLoaded", function () {
const yearHeaders = document.querySelectorAll('.timeline-item[data-toggle="year"]');
const monthHeaders = document.querySelectorAll('.timeline-item[data-toggle="month"]');
yearHeaders.forEach(header => {
header.addEventListener('click', function () {
const yearMonths = this.nextElementSibling;
if (yearMonths.style.display === 'block') {
yearMonths.style.display = 'none';
} else {
yearMonths.style.display = 'block';
}
});
});
monthHeaders.forEach(header => {
header.addEventListener('click', function () {
const articles = this.nextElementSibling;
if (articles.style.display === 'block') {
articles.style.display = 'none';
} else {
articles.style.display = 'block';
}
});
});
});
</script>
<?php get_footer(); ?>
3.修改主题 script.js 文件中如下代码:
mounted() {
if ( !!$base.pjax ) {
new WingPjax({
// selector: '.header_nav a, .footer_nav a, .article-list a',
origin: $base.origin,
before() {
$h.scrollTo();
$vm.animation = 'animation-start';
// 清除当前页面创建的实例
Object.keys($h.tasks).forEach(name => {
$h.tasks[name] = null;
$h.store[name] = null;
});
return $vm.sleep(0);
},
complete() {
$vm.animation = 'animation-toward';
// 更新节点
return $vm.sleep().then(() => ['#core']);
},
after() {
$vm.sleep(100).then(() => {
$vm.animation = 'animation-end';
$vm.overload();
});
// 绑定时间轴头部的点击事件
const yearHeaders = document.querySelectorAll('.timeline-item[data-toggle="year"]');
const monthHeaders = document.querySelectorAll('.timeline-item[data-toggle="month"]');
yearHeaders.forEach(header => {
header.addEventListener('click', function () {
const yearMonths = this.nextElementSibling;
if (yearMonths.style.display === 'block') {
yearMonths.style.display = 'none';
} else {
yearMonths.style.display = 'block';
}
});
});
monthHeaders.forEach(header => {
header.addEventListener('click', function () {
const articles = this.nextElementSibling;
if (articles.style.display === 'block') {
articles.style.display = 'none';
} else {
articles.style.display = 'block';
}
});
});
},
});
}
CSS 如下:
.timeline-item[data-toggle="year"]:hover,.timeline-item[data-toggle="month"]:hover {cursor: pointer;}