首页 / 中文教程 / 教程

Bricks 查询循环按 ACF Repeater 子字段值筛选行

团队介绍页想按部门分开显示?ACF Repeater 的每一行都可以在 Bricks 查询循环里按子字段值筛选。用 bricks/query/run 过滤器,按元素 ID 区分多个循环,一个函数搞定所有筛选需求。

Ray Chan·2026-08-11·约 2 分钟

场景:按部门拆分 Repeater 行

很多 Bricks 用户会在页面上用 ACF Repeater 存“团队成员”:一个 Repeater 字段,每个成员一行,行里有姓名(text)和部门(radio/select)等子字段。问题来了——需求是“按部门分开显示”,比如工程部一栏、人事部一栏。

社区里的经典疑问是:要不要干脆把数据迁到 CPT 再用三个循环?其实不必。Repeater 行本来就在查询循环里逐行输出,我们只需要在结果层面把行筛一遍。本文演示怎么用 Bricks 官方的 bricks/query/run 过滤器,把 ACF Repeater 查询循环的结果按子字段值过滤,一行代码不写进构建器,全在 functions.php 里完成。

Step 1:搭建字段组与查询循环

  1. ACF 字段组挂在 Page 上:Repeater 字段 team_members,子字段 name(text)和 department(radio,选项 Engineering / HR / Design 等)。
  2. 在页面里填好成员数据。
  3. 用 Bricks 编辑该页面,在 Block 上启用查询循环,查询类型选择你的 ACF Repeater 字段。
  4. 循环里放 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'] 分流。这个模式同样可以用于按布尔子字段、按数字范围筛行,思路完全一致——拿到行数组,怎么筛都行。

需要帮忙?

用 Bricks 建站?我接客户项目。

从快速营销站到完整的 Bricks 建站,再到从 Elementor 迁移——我都做过。本站每篇教程都来自真实项目经验。告诉我你的需求,一个工作日内回复。

  • Bricks 建站与改版
  • Elementor / Divi → Bricks 迁移
  • Bricks → Astro / headless 性能升级
  • 速度优化,PageSpeed 95+ 目标