搜索全站
主题 9 分钟阅读

lumen-mimangfei 主题文章列表与归档样式调整:摘要、列表布局与分页

列表页摘要太长、归档页文章数和设置不一致、分页样式难看?本文讲清 excerpt 过滤、pre_get_posts 改查询与 the_posts_pagination 的可用参数。

U
UFO_PF 2022-04-07 · 阅读 9 分钟
lu 主题
阅读提示
本文约 3,447 字,预计阅读 9 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:三个”设置不管用”的瞬间

第一个:后台”阅读设置”里写了每页 10 篇,分类页却只显示 6 篇。第二个:想让摘要短一点,改了主题的 the_excerpt() 调用,结果有的文章摘要是一整段,有的只有一句。第三个:分页只有”上一页/下一页”两个链接,想显示页码数字却不知道从哪加。

第一个问题多半是主题(或插件)用 pre_get_posts 改过主查询;第二个是 the_excerpt() 的行为差异——有手动摘要时原样输出,excerpt_length 过滤器只在自动生成摘要时生效;第三个则是模板里没有调用分页函数或只调用了 posts_nav_link()。理解这三点,列表页就能按自己的意图来。

原理分析:查询、摘要、分页三段各自独立

查询段:WordPress 在解析请求时生成主查询 WP_Query,posts_per_page 来自”阅读设置”。任何挂在 pre_get_posts 上的回调都能在 SQL 执行前修改这个查询对象,所以”设置与实际不符”基本都是被改过。注意 pre_get_posts 会对所有查询生效,必须加 is_main_query() 判断,否则后台、小工具、REST 请求都会被牵连。

摘要段:the_excerpt() 先看文章有没有手动填写的”摘要”字段,有就原样输出(仍会经过 the_excerpt 过滤器与 wpautop);没有则截取正文前若干词,词数由 excerpt_length 过滤器控制,结尾由 excerpt_more 过滤器控制。所以”改了长度没变化”往往是那些文章本来就有手动摘要。

分页段:the_posts_pagination() 内部调用 paginate_links(),支持 mid_size、end_size、prev_text、next_text、screen_reader_text 等参数,输出带 nav 包裹的页码链接,比老的 posts_nav_link() 可控得多。

现象 检查点
归档页数量与设置不一致 pre_get_posts / posts_per_page
摘要长度不统一 是否填写了手动摘要
只有上下页没有页码 是否用了 the_posts_pagination
分页 404 固定链接未刷新 / paged 变量未处理
后台也被影响 is_main_query() 判断缺失

保姆级实操

  1. 确认当前查询参数:临时打印 $query->get( 'posts_per_page' )(仅本地调试),确认是否被改过。
  2. 搜索主题的 pre_get_posts:找到后在其之上叠加你的规则,或用自己的回调覆盖,注意优先级。
  3. 限定生效范围:只改前台主查询,跳过后台、搜索与 feeds。
  4. 统一摘要长度:同时处理 excerpt_length 与 excerpt_more;对有手动摘要的文章,用 wp_trim_words() 强制截断以保证列表整齐。
  5. 换分页函数:把模板里的 posts_nav_link() 换成 the_posts_pagination(),并配置页码数量。
  6. 列表布局用 CSS Grid:卡片式列表比浮动布局更好维护,配合 get_template_part 抽离单项模板。
<?php
// 分类归档页单独设置每页数量,其余保持后台设置
add_action( 'pre_get_posts', 'mimangfei_archive_per_page' );
function mimangfei_archive_per_page( $query ) {
    if ( is_admin() || ! $query->is_main_query() ) {
        return;
    }
    if ( $query->is_category() ) {
        $query->set( 'posts_per_page', 12 );
    }
}
<?php
// 摘要:自动生成的截断到 80 个词,结尾改成省略号
add_filter( 'excerpt_length', function () {
    return 80;
} );
add_filter( 'excerpt_more', function () {
    return '…';
} );

// 手动摘要也统一长度,避免列表长短不一
add_filter( 'get_the_excerpt', 'mimangfei_uniform_excerpt', 20 );
function mimangfei_uniform_excerpt( $excerpt ) {
    if ( is_admin() ) {
        return $excerpt;
    }
    return wp_trim_words( wp_strip_all_tags( $excerpt ), 80, '…' );
}
<?php
// archive.php:分页 + 单项模板抽离
if ( have_posts() ) :
    while ( have_posts() ) :
        the_post();
        get_template_part( 'template-parts/content', get_post_format() );
    endwhile;

    the_posts_pagination( array(
        'mid_size'           => 2,
        'end_size'           => 1,
        'prev_text'          => __( '上一页', 'lumen-mimangfei' ),
        'next_text'          => __( '下一页', 'lumen-mimangfei' ),
        'screen_reader_text' => __( '文章导航', 'lumen-mimangfei' ),
    ) );
else :
    get_template_part( 'template-parts/content', 'none' );
endif;

常见踩坑

  • pre_get_posts 没加 is_main_query(),导致后台文章列表、站内搜索结果数量一起被改。
  • 摘要长度改了没效果,因为文章本身就填了手动摘要,excerpt_length 不参与。
  • is_home() 与 is_front_page() 混用:静态首页下 is_home() 指向的是”文章页”,不是首页。
  • 分页第二页 404,实际是固定链接结构改过但没刷新重写规则。
  • 案例:某站分类页只显示 6 篇,改”阅读设置”毫无反应。排查发现主题为首页轮播注册了一个 pre_get_posts,里面写了 if ( $query->is_home() ),但没判断 is_main_query(),导致侧边栏”最新文章”小工具也变成 6 篇。补全判断并改为只对特定分类生效后恢复正常。
  • 用 query_posts() 改查询,会覆盖主查询并引发分页错乱(应改用 pre_get_posts)。
  • 摘要里保留 HTML 标签导致截断后出现未闭合标签,列表结构崩坏。

总结

列表页的三段各自独立:数量看 pre_get_posts(务必加 is_main_query()),摘要看 excerpt_length 与手动摘要的差别,分页看是否用 the_posts_pagination()。判断标准是”改完一个参数,只在目标归档页生效,后台与搜索不受影响”。行动清单:① 先查主题是否改过主查询;② 统一手动与自动摘要的长度;③ 换用带页码的分页函数;④ 列表结构用 Grid;⑤ 改完刷新固定链接。延伸阅读 lumen-mimangfei 主题首页布局、lumen-mimangfei 主题特色图片设置 与 WordPress 模板层级。

U
UFO_PF作者

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

留下你的想法

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