Skip to main content

Cloning fields

The clone feature of Meta Box allows you to create multiple inputs from a text, textarea, select, ... fields without declaring many fields in the code. Combining clone with groups gives you a flexible way to define repeatable content.

Clone is a feature

The difference between Meta Box and other plugins is that the clone feature can be applied to all field types. And it's a feature, not a field type.

Making a field cloneable

When editing a field, check the checkbox Cloneable:

enable clone feature

Not a premium user?

This instruction uses Meta Box Builder extension, which is a premium extension and is already bundled in Meta Box AIO and MB Core. If you're not a premium user, please purchase a license to use it. However, you can do this with code. See below for more information.

After checking the checkbox, other clone settings will appear. This is a brief description of them. The keys are for reference in code.

SettingsKeyDescription
CloneablecloneMake the field cloneable? true or false (default). Optional.
Sortablesort_cloneAllow to drag-and-drop sort clones. true or false (default).
Clone default valueclone_defaultClone the default value of the field? true or false (default).
Clone as multipleclone_as_multipleWhether to store cloned values in multiple rows in the database
Max number of clonesmax_cloneLimit the number of clones. Must be greater than 2. Optional.
Min number of clonesmin_cloneMinimum number of clones. Optional.
Add more textadd_buttonThe text for Add more clone button. Optional. Default "+ Add more".

Then click Publish or Update button to save the field group. Now go to your post and you'll see a + Add more button below the field input. Clicking it allows you to enter more values:

view clones in action

If you're a developer and want to use code, then you need to add the clone settings into the field settings:

add_filter( 'rwmb_meta_boxes', function ( $meta_boxes ) {
$meta_boxes[] = [
'title' => 'Event details',
'post_types' => 'event',
'fields' => [
[
'name' => 'Date and time',
'id' => 'datetime',
'type' => 'datetime',
'clone' => true,
// Other clone settings
],
[
'name' => 'Location',
'id' => 'location',
'type' => 'text',
],
[
'name' => 'Map',
'id' => 'map',
'type' => 'osm',
'address_field' => 'location',
],
],
];

return $meta_boxes;
} );

Clone data

For cloneable fields, values are stored as a serialized array in a single row in the database, unless you set 'clone_as_multiple' => true.

Using serialized data has some benefits:

  • Works for all field types, including nested groups.
  • Works perfectly with the helper function or with WordPress's get_post_meta function (WordPress automatically unserializes string and returns an array).
  • Reduces the database size (number of rows), especially when you have nested groups of many fields.

Query posts by cloneable fields

By default, clone values are stored as a serialized array, which doesn't allow you to query posts by these values. For example, if you have a cloneable field start_date for the event post type, and you want to query events in May 2019 like this:

$args = [
'post_type' => 'event',
'meta_query' => [
[
'key' => 'start_date', // This field is cloneable
'value' => ['2019-05-01', '2019-05-31']
'compare' => 'BETWEEN',
],
],
];
$query = new WP_Query( $args );

Then it doesn't work.

To solve this problem, you need to enable the Clone as multiple settings for the field.

With that, Meta Box will save cloneable values in multiple rows in the database, where each row contains one value. That means if start_date has 2 values ['2019-05-01', '2019-04-30'], it will be saved in 2 rows in the database, one for 2019-05-01 and one for 2019-04-30. The data is not serialized anymore. And thus, your above query will work!

Default values

When making a field cloneable, its data is an array of cloned values. So, the std parameter (default value) should represent this structure, e.g. array of cloned values.

add_filter( 'rwmb_meta_boxes', function ( $meta_boxes ) {
$meta_boxes[] = [
'title' => 'Event details',
'post_types' => 'event',
'fields' => [
[
'name' => 'Date and time',
'id' => 'datetime',
'type' => 'datetime',
'clone' => true,
'std' => [
'2022-04-20',
'2022-04-21',
],
],
[
'name' => 'Location',
'id' => 'location',
'type' => 'text',
],
[
'name' => 'Map',
'id' => 'map',
'type' => 'osm',
'address_field' => 'location',
],
],
];

return $meta_boxes;
} );