场景:按部门拆分 Repeater 行
很多 Bricks 用户会在页面上用 ACF Repeater 存“团队成员”:一个 Repeater 字段,每个成员一行,行里有姓名(text)和部门(radio/select)等子字段。问题来了——需求是“按部门分开显示”,比如工程部一栏、人事部一栏。
社区里的经典疑问是:要不要干脆把数据迁到 CPT 再用三个循环?其实不必。Repeater 行本来就在查询循环里逐行输出,我们只需要在结果层面把行筛一遍。本文演示怎么用 Bricks 官方的 bricks/query/run 过滤器,把 ACF Repeater 查询循环的结果按子字段值过滤,一行代码不写进构建器,全在 functions.php 里完成。
Step 1:搭建字段组与查询循环
- ACF 字段组挂在 Page 上:Repeater 字段
team_members,子字段name(text)和department(radio,选项 Engineering / HR / Design 等)。 - 在页面里填好成员数据。
- 用 Bricks 编辑该页面,在 Block 上启用查询循环,查询类型选择你的 ACF Repeater 字段。
- 循环里放 Basic Text 输出
{acf_name}和{acf_department},前端能看到全部成员。
此时所有行都会显示。接下来做筛选。
Step 2:bricks/query/run 按子字段筛选
把下面代码加到子主题的 functions.php(去掉开头的 PHP 标签)或代码片段插件里:
add_filter( 'bricks/query/run', function( $results, $query, $query_type ) {
// 只处理 ACF Repeater 类型的查询
if ( $query_type !== 'acf-repeater' || empty( $results ) ) {
return $results;
}
$department = 'Engineering'; // 改成你要筛的部门
return array_values( array_filter( $results, function( $row ) use ( $department ) {
return isset( $row['department'] ) && $row['department'] === $department;
} ) );
}, 10, 3 );
原理拆解:
bricks/query/run是 Bricks 查询系统的总出口过滤器,三个参数依次是$results(查询结果)、$query(查询配置数组)、$query_type(查询类型字符串)。任何查询类型的结果都能在这里拦截修改;acf-repeater是 Bricks 内置的 ACF Repeater 查询类型标识。此时$results里每个元素对应 Repeater 的一行,是以子字段名为键的关联数组,所以直接取$row['department']就能比对;array_filter按条件过滤行,array_values重新索引数组,防止 JSON/循环输出出现键位空洞;- 返回的新数组交给 Bricks 继续渲染,前端就只剩 Engineering 部门的人了。
这个方法对任何“值存字符串”的子字段类型都适用:text、radio、select 都行。想筛多种值就把 $department 换成数组,用 in_array 判断。
按元素 ID 区分多个循环
需求是三栏各显示一个部门,而过滤器是全局的——一个 $department 怎么服务三个循环?答案是:一个函数里做多套规则,用元素 ID 区分。Bricks 的 $query 数组里带 element_id,就是构建器里每个元素唯一的 brxe-xxxx ID:
add_filter( 'bricks/query/run', function( $results, $query, $query_type ) {
if ( $query_type !== 'acf-repeater' || empty( $results ) ) {
return $results;
}
// 元素 ID => 要保留的部门
$rules = [
'brxe-engineering' => 'Engineering',
'brxe-hr' => 'HR',
'brxe-design' => 'Design',
];
$element_id = isset( $query['element_id'] ) ? $query['element_id'] : '';
if ( ! isset( $rules[ $element_id ] ) ) {
return $results;
}
$department = $rules[ $element_id ];
return array_values( array_filter( $results, function( $row ) use ( $department ) {
return isset( $row['department'] ) && $row['department'] === $department;
} ) );
}, 10, 3 );
元素 ID 怎么拿:在构建器里选中 Block,检查器里能看到元素 ID(形如 brxe-ab12cd);也可以先在查询设置里把查询类型选好,保存后看页面 HTML 源码中该循环容器的 class。
小结:ACF Repeater 行筛选 = bricks/query/run + array_filter。记住三个关键点:只在 $query_type === 'acf-repeater' 时动手(避免误伤其他查询);$results 的行是关联数组,直接用子字段名取值;多循环场景靠 $query['element_id'] 分流。这个模式同样可以用于按布尔子字段、按数字范围筛行,思路完全一致——拿到行数组,怎么筛都行。