
本文详解如何通过 pre_get_posts 钩子安全、高效地修改 wordpress 分类(category)和标签(tag)归档页的每页文章数,并规避常见陷阱(如误判主查询、样式错乱),附可直接复用的代码及最佳实践建议。
本文详解如何通过 pre_get_posts 钩子安全、高效地修改 wordpress 分类(category)和标签(tag)归档页的每页文章数,并规避常见陷阱(如误判主查询、样式错乱),附可直接复用的代码及最佳实践建议。
在 WordPress 主题开发或站点优化过程中,常需调整归档页(如标签页 /tag/wordpress/ 或分类页 /category/news/)默认的分页数量。WordPress 默认通常每页显示 10 篇文章,但若内容密度高或设计需求特殊,可能需要提升至 20 篇甚至更多。此时,绝不可通过 query_posts() 或 WP_Query 在模板中硬编码覆盖——这会破坏主查询逻辑、影响 SEO、导致分页失效,甚至引发缩略图与标题布局错乱(正如提问者所遇问题)。
正确方式是利用 pre_get_posts 这一核心动作钩子,在主查询执行前动态修改其参数。关键在于:必须严格限定作用范围,仅针对前端的主查询($query->is_main_query())且处于归档上下文(如 is_tag() 或 is_category())。否则,后台管理页、侧边栏小工具、REST API 请求等均可能被意外影响,造成不可预知的样式或功能异常。
以下为推荐的完整实现方案:
/**
* 修改标签页与分类页每页显示文章数
* 注意:仅作用于前端主查询,避免干扰后台及其他查询
*/
add_action('pre_get_posts', 'customize_archive_posts_per_page');
function customize_archive_posts_per_page($query) {
// 仅在前台、且为主查询时执行
if (!is_admin() && $query->is_main_query()) {
// 同时支持标签页与分类页(可按需扩展,如 is_author()、is_date())
if (is_tag() || is_category()) {
$query->set('posts_per_page', 20); // 设定每页显示20篇文章
}
}
return $query;
}? 重要注意事项:
- ✅ 务必检查 is_admin() 和 $query->is_main_query(),防止后台列表、AJAX 请求或自定义小工具查询被误改;
- ✅ 使用 is_tag() / is_category() 等条件函数(而非 $query->is_tag),因后者在早期钩子阶段可能尚未初始化;
- ❌ 避免在 functions.php 中重复添加同名钩子,或与其他插件冲突;
- ⚠️ 若主题使用了 Masonry 布局或 JS 驱动的瀑布流,增加 posts_per_page 后请务必测试响应式断点与元素包裹逻辑——“缩略图与标题不换行”问题往往源于 CSS 的 flex-wrap: nowrap 或固定宽高容器,与 PHP 查询无关,需同步检查 .archive .post 类的样式规则。
最后,将上述代码粘贴至当前启用主题的 functions.php 文件末尾(建议放在










