Code Snippets for the ACF Repeater Field
Table of Contents
ACF Repeater is one of the most popular and powerful field types in the Advanced Custom Fields plugin. This article is a collection of code snippets that can simplify your day-to-day work with Repeater fields.
1. Displaying ACF Repeater field data
There are so many different ways to display Repeater field data on the front end, so we have dedicated a separate article to this topic.
The demo example below showcases pulling the repeater data using the ACF get_field() function:
// Get the Repeater field data
$repeater_field = get_field('your_repeater_field_name'); // from the current post
$repeater_field = get_field('your_repeater_field_name', 10); // from a specific post by ID
$repeater_field = get_field('your_repeater_field_name', 'option'); // from the options page
$repeater_field = get_field('your_repeater_field_name', 'user_1'); // from the user by ID
$repeater_field = get_field('your_repeater_field_name', 'category_2'); // from the category term with ID 2
$repeater_field = get_field('your_repeater_field_name', 'genre_3'); // from the custom genre term with ID 3
// Check if the repeater field has data
if ( $repeater_field ) {
// items wrapper
echo '<div class="repeater">';
// Loop through each row in the Repeater field
foreach ( $repeater_field as $row ) {
// Get sub-field values
$label = $row['label']; // Text sub-field
$attachment = $row['attachment']; // File sub-field
// Get attachment details (URL, title, etc.)
$attachment_url = isset( $attachment['url'] ) ? esc_url( $attachment['url'] ) : '';
$attachment_title = isset( $attachment['title'] ) ? esc_attr( $attachment['title'] ) : '';
// Output the label
printf( '<div class="repeater__item"><p class="repeater__label">%s</p>', esc_html( $label ) );
// Output the attachment link if available
if ( $attachment_url ) {
printf(
'<a class="repeater__file" href="%s" download="">%s</a>',
esc_url($attachment_url),
esc_html($attachment_title)
);
}
// Close the repeater item div
echo '</div>';
}
// Close the items wrapper div
echo '</div>';
}
2. Updating ACF Repeater field programmatically
To update the Repeater field programmatically, you can use the ACF update_field function. Since this field stores items in an array, the data you pass must be an array of sub-field values.
add_action('acf/init', function() {
// Define the repeater data
$repeater_data = array(
array(
'sub_field_1' => 'Value 1', // Replace with your actual sub-field key and value
'sub_field_2' => 'Value 2', // Replace with your actual sub-field key and value
),
array(
'sub_field_1' => 'Value 3', // Replace with your actual sub-field key and value
'sub_field_2' => 'Value 4', // Replace with your actual sub-field key and value
),
);
// Update the Repeater field
update_field('my_repeater_field', $repeater_data, 1); // Replace 'my_repeater_field' with your Repeater field key, and 1 with the target post ID
});
If you need to update the Repeater field on a user or term object, you must add the appropriate prefix, just as shown in the "loading" field value section.
Note: You should call the update_field function inside the acf/init action, or in any hooks that happen later.
3. Querying by the ACF Repeater field
The way ACF Repeater stores data in the database - using individual rows for each field value - allows you to query repeater fields, but it requires manual handling.
To query by repeater fields, you'll need to work directly with MySQL queries because WP_Query and other WordPress query builders do not support querying meta fields using LIKE for meta_key comparison. This approach is necessary to query across all repeater rows.
Below we provide examples of how to master MySql queries depending on where the Repeater field values are stored. To better understand the used tables and columns, you can read the WordPress database description in the WP Docs.
3.1) By postmeta repeater (within Post, Page, Any CPT)
We execute the direct MySql query in WordPress we need to use the global wpdb class. Replace the repeater-name and field-name in the code with the name of your repeater field and target subfield.
global $wpdb;
// Prepare the query
$query = $wpdb->prepare(
"SELECT post_id
FROM $wpdb->postmeta
WHERE meta_key LIKE 'repeater-name_%_field-name'
AND meta_value = %s",
'the very first item'
);
// Execute the query. The array will contain the post IDs of the posts where the key is found.
$results = $wpdb->get_col( $query );
3.2) By termmeta repeater (within Terms)
The same as by postmeta, but only using termmeta table name from the wpdb class:
global $wpdb;
// Prepare the query
$query = $wpdb->prepare(
"SELECT term_id
FROM $wpdb->termmeta
WHERE meta_key LIKE 'repeater-name_%_field-name'
AND meta_value = %s",
'the very first item'
);
// Execute the query. The array will contain the term IDs of the terms where the key is found.
$results = $wpdb->get_col( $query );
3.3) By usermeta repeater (within user profile)
In this case using usermeta of the wpdb class:
global $wpdb;
// Prepare the query
$query = $wpdb->prepare(
"SELECT user_id
FROM $wpdb->usermeta
WHERE meta_key LIKE 'repeater-name_%_field-name'
AND meta_value = %s",
'the very first item'
);
// Execute the query. The array will contain the user IDs of the users where the key is found.
$results = $wpdb->get_col( $query );
3.4) Inside ACF Blocks (within Gutenberg)
ACF Blocks save their data as JSON in the post_content. This data cannot be queried directly. However, if you enable the "Save in Meta" feature for ACF Blocks, the field values are also saved in post meta, allowing you to query them similarly to other postmeta fields.
4. Repeater field filters and hooks
ACF offers a variety of filters and hooks that enable you to modify field data and behavior, extending WordPress's core hooks functionality. You can utilize the standard add_action and add_filter functions to attach custom code to these hooks.
Below are some of the most commonly used hooks along with the ACF Repeater field type:
4.1) acf/load_field
The acf/load_field filter allows you to modify the field settings before it is displayed on the editor's screen. This filter is particularly useful for dynamically adjusting the field's configuration, such as setting default values, changing labels, or customizing available options.
add_filter('acf/load_field/name=my_repeater_field', function (array $field): array {
// Modify the field settings as needed
$field['instructions'] = 'Please fill out all repeater fields.';
return $field;
});
4.2) acf/render_field
The acf/render_field action allows you to add custom HTML before or after a field's input on the editor's screen in the WordPress admin. This can be particularly useful for adding custom-styled text, icons, styles, or additional interactive elements to enhance the field's functionality.
// Replace field key with yours
add_action('acf/render_field/key=field_123456789abc', function (array $field): void {
// Your custom HTML
echo '<div class="my-custom-class">Custom field-related element</div>';
});
Note: By default, the acf/render_field action is triggered after the field input has been printed. If you need to print your HTML before the input, you should set the priority number to 9 or lower in the third argument of the add_action WordPress function.
4.3) acf/validate_value
Use the acf/validate_value filter to validate the values entered into the field. You can ensure that the entered value meets specific criteria:
add_filter('acf/validate_value/name=my_repeater_field', function($valid, $value, array $field) {
if (true !== $valid) {
return $valid; // Skip validation if there is an existing error
}
// Custom validation: Ensure each repeater row has a non-empty value
foreach ($value as $row) {
if (empty($row['sub_field_1']) && empty($row['sub_field_2'])) {
$valid = 'Please fill out at least one sub-field in the repeater row.';
break;
}
}
return $valid;
}, 10, 3);
4.4) acf/validate_save_post
The acf/validate_save_post action allows you to perform custom form validations before saving ACF fields. This is particularly useful when you need to validate one field's value based on another field's input or enforce specific rules across multiple fields.
add_action('acf/validate_save_post', function () {
// Get the repeater field values from ACF fields
$repeater_1 = $_POST['acf']['field_repeater_id_1'] ?? [];
$repeater_2 = $_POST['acf']['field_repeater_id_2'] ?? [];
if (empty($repeater_1) || empty($repeater_2)) {
return;
}
// Check if the number of rows in both repeaters are the same
if (count($repeater_1) !== count($repeater_2)) {
// Add a validation error if the row counts do not match
acf_add_validation_error('field_repeater_id_1', 'The number of rows must match.');
acf_add_validation_error('field_repeater_id_2', 'The number of rows must match.');
}
});
Tip: To find the field key, navigate to the ACF field group in the WordPress admin. Click on the Screen Options button at the top right corner of the page, then check the Field Keys option. Once enabled, the field keys will be displayed next to each field name in the group.
4.5) acf/save_post
The acf/save_post action is triggered when the current item (page/product/user) is saved. You can use it to perform any additional actions, e.g. updating related data.
add_action('acf/save_post', function ($post_id) {
// Retrieve the repeater field value (replace with your actual repeater field key)
$repeater = get_field('project_repeater', $post_id); // Field key for repeater
if (!$repeater) {
return;
}
// Process each row in the repeater field
foreach ($repeater as $row) {
// Get the related post ID from the relationship field
$related_post_id = $row['sub_field_1']; // Replace with your actual sub-field key
if (!$related_post_id) {
continue;
}
// Fetch the current related items for the related post
$related_items = get_field('related_item', $related_post_id);
// If there are no related items, initialize as an array
if (!$related_items) {
$related_items = [];
}
// Add the current post ID to the related items array
if (!in_array($post_id, $related_items, true)) {
$related_items[] = $post_id;
}
// Update the related items field with the new array
update_field('related_item', $related_items, $related_post_id);
}
});
Thank you for reading! to our monthly newsletter to stay updated on the latest WordPress news and useful tips.
Stuck with development or facing an issue?
WPLake offers affordable on-demand website development and design.
No matter the size of your project - contact us now, and we'll get it done for you!