A user asks:
Query a metabox group, but limit items?
…i cannot see how to pick a random text field in that group and change it every X minutes. is it doable?
i need to show only one item in the metabox group, at random, and randomly pick another after one hour.
btw, dunno why the groups have no options like posts or pages.
Non standard query types like ACF Repeaters, Meta Box Groups and Relationships do not have the same controls that the post query loops have.
This Pro tutorial shows how PHP transients and bricks/query/result filter can be used to specify how many random items should be output in the query loop’s result set and for how long.
After implementing the tutorial, you could, for example, show one random row of a Meta Box group on page load, continue to show the same for an hour (the same for all visitors/users), and then output another random row (other than what was shown in the last hour) for the second hour and so on.

Before:

After:

After another hour:

Step 1
In a Bricks template or Page, set up your query loop.
In this example, we are querying a Meta Box group.

Step 2
Before we add the code snippet let’s first understand what the original query result and the query object looks like.
Original query result:

This can be seen by adding this snippet in a code snippets plugin like WPCodeBox or in the child theme’s functions.php at the end w/o the opening PHP tag:
<?php
add_filter( 'bricks/query/result', function( $result, $query_obj ) {
if ( $query_obj->element_id !== 'cwndii' ) {
return $result;
}
print( "<pre>" . print_r( $result, true ) . "</pre>" );
return $result;
}, 30, 2 );
where cwndii is the Bricks ID of the query loop enabled element.
The result is going to be different depending on what is being queried.
Query object:

This can be seen via:
<?php
add_filter( 'bricks/query/result', function( $result, $query_obj ) {
if ( $query_obj->element_id !== 'cwndii' ) {
return $result;
}
print( "<pre>" . print_r( $query_obj, true ) . "</pre>" );
return $result;
}, 30, 2 );
Coming to the task at hand, add the following in child theme‘s functions.php (w/o the opening PHP tag) or a code snippets plugin:
<?php
/**
* Filter to modify query results for a specific Bricks element.
*
* @param array $result The original query result.
* @param object $query_obj The query object.
* @return array The modified query result.
*/
add_filter( 'bricks/query/result', function( $result, $query_obj ) : array {
// Check if this is the specific element we want to modify
if ( $query_obj->element_id !== 'cwndii' ) {
return $result;
}
// Set the cache duration (in hours)
$cache_duration_hours = 1; // Change this value to adjust the cache duration
// Set the number of items to return
$num_items = 1; // Change this value to adjust the number of items returned
return bl_get_random_cached_items( $result, $query_obj->element_id, $num_items, $cache_duration_hours );
}, 30, 2 );
/**
* Get random items from the array and cache them for a specified duration.
*
* @param array $items The array of items to choose from.
* @param string $element_id The ID of the Bricks element.
* @param int $num_items The number of items to return.
* @param int $cache_duration_hours The duration to cache the items, in hours.
* @return array An array containing the selected items.
*/
function bl_get_random_cached_items( array $items, string $element_id, int $num_items = 1, int $cache_duration_hours = 1 ) : array {
// Convert hours to seconds
$cache_duration = $cache_duration_hours * HOUR_IN_SECONDS;
// Create unique transient keys for this element
$transient_key = 'bl_random_items_' . $element_id;
$previous_items_key = 'bl_previous_items_' . $element_id;
// Try to get the cached items
$cached_items = get_transient( $transient_key );
// If cached items exist and the count matches the requested number, return them
if ( $cached_items !== false && count( $cached_items ) === $num_items ) {
return $cached_items;
}
// Get the previously shown items
$previous_items = get_transient( $previous_items_key ) ?: [];
// Filter out the previous items to avoid showing them again
$available_items = array_diff_key( $items, array_flip( $previous_items ) );
// If filtering removed too many items, reset to the full list
if ( count( $available_items ) < $num_items ) {
$available_items = $items;
}
// Select random items
$random_items = [];
$keys = array_keys( $available_items );
for ( $i = 0; $i < $num_items; $i++ ) {
if ( empty( $keys ) ) break;
$random_index = array_rand( $keys );
$random_items[] = $available_items[ $keys[ $random_index ] ];
unset( $keys[ $random_index ] );
}
// Cache the selected items
set_transient( $transient_key, $random_items, $cache_duration );
// Store these items as the "previous" items for twice the cache duration
set_transient( $previous_items_key, array_keys( $random_items ), $cache_duration * 2 );
// Return the selected items
return $random_items;
}
Adjust the $cache_duration_hours value in the filter function to set your desired cache duration.
Set the $num_items value to specify how many random items you want to return.
Ensure the $query_obj->element_id matches the ID of your Bricks element.
That’s it! Check the front end.