继上次折腾归档页面展开收缩后,看着归档页面只有文章却没有说说内容,心想凭什么瞧不起说说呢,说说就不配拥有归档资格?本着不能厚此薄彼的想法,决定也给说说建一个归档页面吧…
在这次折腾笔记归档功能过程中突然意识到,由于我的博客建站时间太短,等到了下个月月初,按照现在的展开收缩逻辑,以前的月份将全部收缩起来,悲催的是目前仅有的这两个月文章将全部收缩起来,造成归档页面太短。因此改为了最新的两个月文章默认展开。哈哈!
现将修改后的相关代码记录如下:
1. 调整 get_my_archives 函数:使其能够根据传入的文章类型参数动态获取归档数据。
// 获取文章归档,接受一个或多个文章类型作为参数
function get_my_archives( $post_types = array( 'post' ) ) {
// 确保 $post_types 是数组
if ( ! is_array( $post_types ) ) {
$post_types = array( $post_types );
}
// 生成唯一的 transient 名称,根据文章类型
$transient_name = 'my_archives_' . implode( '_', $post_types );
// 尝试从缓存中获取归档数据
if ( false === ( $archives = get_transient( $transient_name ) ) ) {
$archives = [];
$posts = get_posts( array(
'numberposts' => -1,
'orderby' => 'post_date',
'order' => 'DESC',
'post_type' => $post_types,
'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 ),
'type' => get_post_type( $post->ID ), // 可选:添加文章类型
];
}
// 将归档数据缓存 12 小时
set_transient( $transient_name, $archives, 12 * HOUR_IN_SECONDS );
}
return $archives;
}
// 清除归档缓存,接受文章类型参数
function clear_my_archives_cache( $post_id ) {
// 获取文章类型
$post_type = get_post_type( $post_id );
// 生成 transient 名称
$transient_name = 'my_archives_' . $post_type;
delete_transient( $transient_name );
}
// 在发布、更新或删除文章时清除缓存
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. 创建新的页面模板:一个专门用于展示 note 类型的文章归档。一个专门用于展示 post 类型的文章归档。下面代码是 note 类型的,post 类型的按注释改一下就行。
<?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
// 获取 'note' 类型的归档数据,'post' 类型的改为 'post' 即可。
$archives = get_my_archives( 'note' );
// 定义月份中文名称
$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
$month_counter = 0; // 初始化月份计数器
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: <?= $month_counter < 2 ? '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
$month_counter++; // 增加月份计数器
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(); ?>