一句话结论
WordPress 的 Query Loop 区块不只是「列出最新文章」那么简单:通过注册区块变体(block variation)、用 query_loop_block_query_vars 过滤器注入自定义 WP_Query 参数,以及配合自定义文章类型,你可以不写一整个区块就实现「按评分筛选的书评网格」「按活动日期排序的事件列表」这类动态查询。本文用三段最小可用代码讲清进阶玩法。
一、 Query Loop 区块能查什么
Query Loop(core/query)本质是把 WP_Query 包装成可视化区块。它的 query 属性已经支持分类、标签、作者、排序、每页数量等参数。但有些需求核心区块面板没有暴露,比如「按自定义字段排序」「只显示未来活动」——这时候要借助过滤器。
记住一个分工:编辑器里的可视设置走区块属性;核心区块没暴露的查询条件,交给 PHP 过滤器在前后台两侧补齐。
二、用区块变体做「开箱即用」的预设
如果你做了一个「书评」自定义文章类型,每次插入 Query Loop 都要手动切到 book 类型很烦。注册一个变体,让它默认就查 book:
const MY_VARIATION = 'my-plugin/books-list';
registerBlockVariation( 'core/query', {
name: MY_VARIATION,
title: 'Books List',
description: 'Displays a list of books',
isActive: ( { namespace, query } ) =>
namespace === MY_VARIATION && query.postType === 'book',
attributes: {
namespace: MY_VARIATION,
query: { postType: 'book', perPage: 6, order: 'desc', orderBy: 'date', inherit: false },
},
scope: [ 'inserter' ],
} );
这样用户在插入器里看到的就是一个像独立区块一样的「 Books List 」,点一下就能用,无需懂 query 是什么。
三、用过滤器注入自定义查询
想「只显示未来活动、且按活动日期排序」,核心区块面板没有这个开关。用 query_loop_block_query_vars 钩子注入 meta 查询:
add_filter( 'query_loop_block_query_vars', 'wpdocs_filter_query' );
function wpdocs_filter_query( $query ) {
if ( 'wpdocs_event' !== $query['post_type'] ) {
return $query;
}
$query['meta_key'] = 'eventDate';
$query['meta_value'] = date( 'Y-m-d' );
$query['meta_compare'] = '>=';
if ( 'date' === $query['orderby'] ) {
$query['orderby'] = 'meta_value';
}
return $query;
}
为什么编辑器预览也要单独处理?
核心区块在编辑器里走 REST API 取数,过滤器只影响前台渲染。要让编辑器预览和前台一致,还需在
rest_post_query 钩子上做同样的 meta 注入。两个口子都补上,体验才统一。四、进阶能力对照
| 需求 | 实现方式 | 是否写区块 |
|---|---|---|
| 预设文章类型列表 | registerBlockVariation | 否 |
| 按自定义字段排序 / 筛选 | query_loop_block_query_vars | 否 |
| 编辑器预览一致 | rest_post_query 同源注入 | 否 |
| 完全自定义布局 | 自定义区块 | 是 |
相关阅读
- WordPress 区块绑定(Block Bindings):不写自定义区块也能接动态数据
- WordPress 区块方案(Block Patterns)实战
- WordPress 自定义文章类型从零注册
- WordPress 构建你的第一个区块
Query Loop 和 Posts List 变体是什么关系?
Posts List 是核心自带的一个预设变体;你注册的变体(如 Books List)和它同级,只是默认 query 不同。用户从插入器点哪个,就套用哪套默认参数。
为什么前台和编辑器看到的结果不一样?
编辑器预览走 REST API(rest_post_query),前台渲染走 query_loop_block_query_vars 。只挂一个过滤器会导致两侧不一致,记得两个钩子都补。
这些过滤器对所有 Query Loop 都生效吗?
会作用于全站所有 Query Loop 。务必在回调里用 post_type 等条件收窄,避免误伤其他列表。
不想写代码,能实现类似效果吗?
基础筛选(分类、标签、排序、数量)在区块面板直接点选即可;只有 meta 查询、未来日期这类高级条件才需要上面那段 PHP 。










评论 (0)