可克隆字段的两种输出路线
Meta Box 的可克隆(Cloneable)字段让用户添加任意多个同类型值:一门课程可以填 3 个上课日期,一个活动可以填多张图片。这些值在数据库里是一组记录,Bricks 内置查询类型里没有直接对应的(内置的 MB Group 是针对 Group 类型字段的),所以输出有两条路线:
- Code 元素路线:用 Meta Box 生成的代码(如
foreach ( rwmb_meta( 'course_dates' ) ... ))直接输出 HTML。快、简单,但样式只能写死在 HTML 里; - 自定义查询类型路线:注册一个查询类型,让每个值变成一个循环项,循环项里用 Basic Text 等 Bricks 元素排版,样式完全在构建器里调。
两条路线都成立,本文讲的是第二种——它更符合“用 Bricks 元素做视觉样式”的需求,同时和上一篇 Checkbox List 一样,本质是“任意数组变查询循环”通用模式的复用。
Step 1:字段与模板准备
- 课程 CPT(
course)上挂一个字段组,加一个 Date Picker 字段,IDcourse_dates,勾选 Cloneable(可克隆)。 - 给某门课填 2-3 个日期;再留一门课不填,用来验证条件渲染。
- 用 Bricks 编辑课程单篇模板,搭一个 Section,里面放 Block 准备挂循环。
Step 2:注册自定义查询类型
// 1. 注册查询类型
add_filter( 'bricks/query/register_types', function( $query_types ) {
$query_types['bl_mb_cloneable'] = [
'name' => 'BL MB Cloneable',
'supports' => [ 'field' ],
];
return $query_types;
} );
// 2. 把可克隆字段的每个值变成一个循环项
add_filter( 'bricks/query/run', function( $results, $query, $query_type ) {
if ( $query_type !== 'bl_mb_cloneable' || ! function_exists( 'rwmb_meta' ) ) {
return $results;
}
$object_id = isset( $query['object_id'] ) ? $query['object_id'] : get_the_ID();
$dates = (array) rwmb_meta( 'course_dates', [ 'object_type' => 'post' ], $object_id );
$results = [];
foreach ( $dates as $i => $date ) {
$results[] = (object) [
'ID' => $i + 1,
'date' => $date,
];
}
return $results;
}, 10, 3 );
// 3. 配套动态标签:输出循环项的 date 属性
add_filter( 'bricks/dynamic_data/tags', function( $tags ) {
$tags['bl_cloneable_date'] = [
'label' => 'BL Cloneable Date',
'render' => 'bl_render_cloneable_date',
];
return $tags;
} );
function bl_render_cloneable_date( $tag, $post, $context, $name ) {
if ( is_object( $post ) && isset( $post->date ) ) {
return $post->date;
}
return '';
}
然后在模板里:Block 启用查询循环,查询类型选 BL MB Cloneable,循环项放 Basic Text 插入 {bl_cloneable_date}。前端每门课列出全部上课日期。
两个细节:
- 日期格式:Date Picker 默认按字段设置的 Save format 返回字符串(如
Y-m-d)。如果字段设了“存为时间戳”,$post->date是数字,渲染函数里加一行return date( 'Y-m-d', (int) $post->date );转成可读格式; rwmb_meta对可克隆字段:返回“每个值一个元素”的数组,所以foreach直接遍历即可,这也是和普通字段最大的区别。
另外,这套循环项还可以继续嵌套:循环项里的 $post 就是当前的日期值对象,如果哪天需求变成“每个日期下面再列该日期的名额数(另一个可克隆字段)”,在循环项里再挂一层自定义查询类型、读取时按日期匹配即可——查询循环的嵌套能力对自定义类型同样开放。
Step 3:空值时不渲染整块
客户不会喜欢“没有日期的课程也显示一个空标题栏”。做法:注册一个计数动态标签,配合 Bricks 元素条件:
// 4. 计数标签:返回可克隆字段的值数量
add_filter( 'bricks/dynamic_data/tags', function( $tags ) {
$tags['bl_cloneable_count'] = [
'label' => 'BL Cloneable Count',
'render' => 'bl_render_cloneable_count',
];
return $tags;
} );
function bl_render_cloneable_count( $tag, $post, $context, $name ) {
if ( ! function_exists( 'rwmb_meta' ) ) {
return '0';
}
return (string) count( (array) rwmb_meta( 'course_dates', [ 'object_type' => 'post' ], get_the_ID() ) );
}
构建器里:选中放循环的整个 Section,在元素设置的 Conditions(条件)里加一条——动态数据 {bl_cloneable_count} 不等于 0 时显示。保存后,没填日期的课程整块 Section 直接消失,填了的正常显示。
小结:Meta Box 可克隆字段的查询循环方案 = 注册查询类型 + rwmb_meta 遍历取值 + 动态标签渲染,再加一个计数标签做条件渲染。它和 Checkbox List 那篇是同一套“数组变循环”模板的两次应用——把 rwmb_meta( 'course_dates' ) 换成任意返回数组的函数(图片字段的 ID 列表、Select 多选值等),循环项属性跟着改就行。如果只是要快速输出 HTML,Code 元素路线更快;要视觉样式可控,就用这套。