
本文详解 Timber 框架下 WordPress 默认主查询(如首页博客列表)的分页失效问题,指出直接使用 Timber::get_posts() 会绕过 WP_Query 生命周期导致分页异常,并提供基于 pre_get_posts 钩子 + Timber\PostQuery 的标准解决方案。
本文详解 timber 框架下 wordpress 默认主查询(如首页博客列表)的分页失效问题,指出直接使用 `timber::get_posts()` 会绕过 wp_query 生命周期导致分页异常,并提供基于 `pre_get_posts` 钩子 + `timber\postquery` 的标准解决方案。
在 Timber 项目中,若希望首页(home.php)使用 WordPress 原生分页机制(如 next_posts_link() 或 Twig 中的 pagination()),必须确保分页逻辑作用于主查询($wp_query),而非独立构造的次级查询。你当前代码中调用 Timber::get_posts($args) 创建的是一个全新的、与主循环无关的 WP_Query 实例,其 paged 参数无法被 WordPress 分页函数识别,因此 posts.pagination() 返回空或无效对象——这是分页失效的根本原因。
同时,{{ dump(posts) }} 失效而 {% for post in posts %} 正常,是因为 Timber::get_posts() 返回的是普通 PHP 数组(含 Timber\Post 对象),而非支持 Twig 调试协议的 Timber\PostQuery 实例;后者实现了 __debugInfo() 方法,使 dump() 可安全输出结构化数据。
✅ 正确做法:将分页逻辑注入主查询,再用 Timber\PostQuery 封装它。具体分两步:
1. 在 functions.php 中钩入 pre_get_posts
function modify_blog_posts_query($query) {
// 仅对首页主查询生效,避免影响后台或其他查询
if ($query->is_home() && $query->is_main_query()) {
$query->set('posts_per_page', 2);
$query->set('offset', 1); // 注意:offset 与 pagination 兼容性需谨慎(见下方提示)
// paged 由 WordPress 自动处理,无需手动 set
}
}
add_action('pre_get_posts', 'modify_blog_posts_query');⚠️ 重要提示:offset 参数与分页存在冲突(会导致第一页跳过指定数量,后续页重复或错乱)。如需“跳过最新文章”,建议改用 post__not_in + 获取最新 ID 的方式,或使用 posts_per_page + paged 组合实现纯分页。
2. 重构 home.php,使用 Timber\PostQuery
<?php
use Timber\Post;
use Timber\Timber;
use Timber\PostQuery; // 必须引入
$context = Timber::context();
$context['post'] = new Post();
// ✅ 关键:直接实例化 PostQuery,它自动绑定主查询
$context['posts'] = new PostQuery();
// 获取最新文章(独立查询,不影响主分页)
$argsLatest = [
'posts_per_page' => 1,
'post_status' => 'publish',
];
$context['latest'] = Timber::get_posts($argsLatest);
Timber::render('page-home.twig', $context);3. Twig 模板中启用分页
在 page-home.twig 中,posts 现为 PostQuery 实例,可直接调用分页方法:
{# 渲染分页导航 #}
{% include 'partial/pagination.twig' with {
pagination: posts.pagination({
show_all: false,
mid_size: 3,
end_size: 2
})
} %}
{# 安全调试(现在 dump 有效) #}
{{ dump(posts) }}
{# 正常循环 #}
{% for post in posts %}
<article>
<h2>{{ post.title }}</h2>
<p>{{ post.excerpt }}</p>
</article>
{% endfor %}? 额外验证:确保主题已启用 posts_per_page 设置(后台 → 设置 → 阅读 → 博客页面至多显示),且 .htaccess 规则支持 /page/2/ 这类 URL(默认启用)。若仍无分页链接,请检查 pagination.twig 是否正确渲染了 pagination.links 数组。
通过以上改造,分页将严格遵循 WordPress 核心逻辑,posts.pagination() 返回完整分页对象,dump() 也能清晰展示查询状态——这才是 Timber 与 WordPress 深度集成的最佳实践。


















