搜索全站
主题 14 分钟阅读

WordPress 日期归档是否该保留:重复内容取舍与处理代码

日期归档页产生大量重复内容?本文对比保留与移除的适用场景,讲清 wp_get_archives 的输出控制、条件 noindex、归档页内容补全与 404 化的实现代码。

U
UFO_PF 2017-09-28 · 阅读 14 分钟
Wo 主题
阅读提示
本文约 5,251 字,预计阅读 14 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:侧边栏挂了「文章归档」,等于开了几十个空页面

wp_get_archives() 输出的那排「2024 年 5 月、2024 年 4 月……」,看着是个方便读者的功能。但每一个月份链接点进去,都是一个只列出该月文章标题的页面——内容与其他归档页高度重合,几乎没有独特价值。经营两三年后,这类页面轻松累积几十个,全都是「内容稀薄」的典型。

要不要保留,取决于站点性质。新闻站、日记站里,「某年某月」是有意义的时间维度(读者确实会按时间回溯);而常青内容的技术博客里,读者根本不关心文章是哪个月写的,日期归档只会稀释站点质量。本文把判断条件讲清楚,并给出三种处理方式:保留但补全、noindex、直接 404。

原理分析:日期归档为什么容易被判为重复内容

归档类型 内容独特性 用户价值 常见处理
分类归档 高,围绕主题组织 高 保留并补全描述
标签归档 中,取决于标签质量 中 精选标签保留
日期归档 低,仅按时间切分 低(常青内容) noindex 或移除
作者归档 中,取决于作者产出 中 按产出决定

日期归档的核心问题是内容集合与其他页面高度重合:2024 年 5 月的文章,几乎必然也属于某个分类;同一个页面上的标题列表,和分类页、首页、搜索结果页大量重叠。Google 的重复内容处理机制会自动选一个 canonical 版本,但选择结果未必是你想要的那个,也可能因为「大量近似页面」而降低抓取预算的使用效率。

另一个常被忽视的问题是抓取预算。站点规模不大时,抓取器会周期性访问所有已发现 URL;日期归档页每次访问都消耗一次抓取机会,而这些页面几乎不会带来流量。把这些机会让给真正重要的文章页,收录效率会更高。

技术上,日期归档由 is_date()(含 is_year() / is_month() / is_day())判定,模板优先级是 date.php → archive.php → index.php。它的链接主要来自 wp_get_archives(),所以「移除日期归档」实际上有两件事:不让链接出现在前台,以及让已有的日期 URL 不再返回正常页面。

保姆级实操

  1. 判断站点性质:常青内容为主 → 移除或 noindex;时效内容为主 → 保留并补全。
  2. 先做 noindex 而非直接 404:noindex 更温和,也便于观察;确认无流量后再考虑 404。
  3. 移除前台链接:把 wp_get_archives() 的调用换成分类列表,或用 getarchives_where 过滤器限制。
  4. 用 wp_robots 条件输出:按 is_date() 判断,注意别和 robots.txt 屏蔽同时使用。
  5. 保留场景下的补全:date.php 里加说明文字、文章数、分页,让页面有独特内容。
  6. 激进方案:确认无价值后用 pre_get_posts 或 parse_query 让日期归档返回 404。
  7. 验证:检查页面源码的 robots meta,并在 Search Console 观察移除进度。
<?php
// 子主题 functions.php:日期归档页输出 noindex
add_filter( 'wp_robots', 'mimangfei_date_archive_robots' );
function mimangfei_date_archive_robots( $robots ) {
    // 保留年度归档(有回顾价值),月份与日归档不索引
    if ( is_month() || is_day() ) {
        $robots['noindex']  = true;
        $robots['nofollow'] = true;
    }
    return $robots;
}
<?php
// 前台只输出年度归档链接,避免产生大量月份页面入口
add_filter( 'widget_archives_args', 'mimangfei_archives_yearly_only' );
function mimangfei_archives_yearly_only( $args ) {
    $args['type']  = 'yearly';
    $args['limit'] = 6;
    return $args;
}

// 自定义归档小工具里同样限制为年度
echo wp_get_archives( array(
    'type'            => 'yearly',
    'limit'           => 6,
    'format'          => 'html',
    'show_post_count' => true,
    'echo'            => false,
) );
<?php
/**
 * date.php:保留日期归档时的补全版本
 *
 * @package lumen-mimangfei-child
 */

get_header();
global $wp_query;

if ( is_year() ) {
    $title = sprintf( '%d 年的文章', (int) get_query_var( 'year' ) );
} elseif ( is_month() ) {
    $title = sprintf( '%d 年 %d 月的文章', (int) get_query_var( 'year' ), (int) get_query_var( 'monthnum' ) );
} else {
    $title = sprintf( '%d 年 %d 月 %d 日的文章', (int) get_query_var( 'year' ), (int) get_query_var( 'monthnum' ), (int) get_query_var( 'day' ) );
}
?>
<main id="primary" class="site-main site-main--date">
    <header class="archive-header">
        <h1><?php echo esc_html( $title ); ?></h1>
        <p class="archive-desc">
            本页共 <?php echo (int) $wp_query->found_posts; ?> 篇文章,按发布时间排列。
        </p>
    </header>

    <?php if ( have_posts() ) : ?>
        <ul class="archive-list">
            <?php
            while ( have_posts() ) :
                the_post();
                ?>
                <li>
                    <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
                    <span class="archive-list__cat">
                        <?php
                        $cats = get_the_category();
                        echo $cats ? esc_html( $cats[0]->name ) : '';
                        ?>
                    </span>
                </li>
                <?php
            endwhile;
            ?>
        </ul>
        <?php the_posts_pagination(); ?>
    <?php else : ?>
        <p>这段时间没有发布文章。</p>
    <?php endif; ?>
</main>
<?php
get_footer();
<?php
// 激进方案:确认无价值后让月份/日归档直接返回 404
add_action( 'parse_query', 'mimangfei_disable_date_archives' );
function mimangfei_disable_date_archives( $query ) {
    if ( is_admin() || ! $query->is_main_query() ) {
        return;
    }

    if ( $query->is_month() || $query->is_day() ) {
        $query->set_404();
        status_header( 404 );
        nocache_headers();
    }
}

常见踩坑

  1. noindex 与 robots.txt 同时用:爬虫被挡住就读不到 noindex,页面会以「无描述」形式残留。只保留 noindex 一种手段。
  2. 直接 404 却没有先移除内链:站点里还有几百个月份链接指向 404 页面,等于给自己制造大量死链。先移除链接来源,再改状态码。
  3. 案例:某站为了「减少重复内容」,一次性把全部日期归档 404 化,结果当月的几篇重要文章被分享到社交平台时,链接正好命中了日期归档 URL(分享插件自动生成了月度归档链接),全部变成 404,损失了一批流量。复盘结论:应当先做 noindex 观察 1–2 个月,用数据确认这些页面确实没有流量与外部链接后,再考虑 404 化。教训:移除操作要分阶段,noindex 先行。
  4. wp_get_archives() 的 echo 参数:默认直接输出,想二次处理必须传 'echo' => false,否则字符串会被提前打印。
  5. widget_archives_args 只影响小工具:主题模板里直接调用 wp_get_archives() 的部分不受这个过滤器控制,两处都要改。
  6. set_404() 后没调用 status_header():主查询标记了 404,但 HTTP 状态码仍是 200,产生软 404。两个都要调用。
  7. 年度归档一刀切 noindex:年度归档对有时效价值的站点(年终总结、年度报告)是有意义的,别和月度归档一起屏蔽。
  8. 归类错误:把日期归档和分类归档混为一谈,一刀切处理掉有价值的分类页。分类页应保留并补全描述,取舍思路可参考 主题作者页与归档页的 SEO 处理。

总结

日期归档的判断标准是:读者会不会主动想看「某年某月的所有文章」。新闻、日记类站点会,常青内容的技术博客不会。行动清单:判断站点性质 → 常青站先给月度/日归档加 noindex 并移除前台链接 → 保留年度归档 → 观察 1–2 个月的流量与外部链接数据 → 确认无价值后再 404 化(记得同时调用 set_404() 与 status_header())→ 保留场景用 date.php 补全说明文字与文章数。归档页清理完,站点的内容密度会明显提升,抓取预算也能集中在真正重要的页面上。清理过程中别忘了同步检查 主题分页与 SEO:rel=next/prev 的现状,归档页的分页同样需要正确的 canonical 处理。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。