Bricks Query Loop: Outputting a Fixed Number of Items

In the BricksLabs Facebook group a user asks:

How might I repeat query loop items until it reaches a specific number?

One service might have 7 images, another might have 10, but there needs to be exactly 13, so they need to loop again until 13 is reached.

This Pro tutorial shows how bricks/query/result filter can be used to intercept the query result and modify it to output a fixed number of items by re-using the items.

We shall cover two types of queries – Meta Box cloneable group and Posts.

Meta Box Cloneable Group

Consider a “Features” group-type field having “Feature Name” and “Feature Details” subfields.

Field populated for a specific Page:

In the Bricks editor setting up a query loop for this Meta Box group shows the three items like this:

The requirement is to show exactly 13 items by filling the remaining 10 slots with the existing ones, like this (screenshot after implementing the tutorial):

Here’s how.

Add the following in child theme‘s functions.php (w/o the opening PHP tag) or a code snippets plugin:

<?php

/**
 * Ensure exactly 13 items are output.
 *
 * @param array  $result    The original query result.
 * @param object $query_obj The query object.
 * @return array Modified query result.
 */
add_filter( 'bricks/query/result', function ( array $result, object $query_obj ): array {
    // Return early if not the target element
    if ( $query_obj->element_id !== 'hpkldp' ) {
        return $result;
    }

    $desired_count = 13; // Set this to the desired number of items

    // Sort by feature_name (ascending)
    // usort( $result, function ( $a, $b ) {
    //     return strcmp( $a['feature_name'], $b['feature_name'] );
    // } );

    // Ensure we have exactly the desired number of items
    $adjusted_result = []; // Will hold our final 13 items
    $original_count = count( $result ); // 3 in this example

    // If we already have 13 or more items, return the original result
    if ( $original_count >= $desired_count ) {
        return $result;
    }

    for ( $i = 0; $i < $desired_count; $i++ ) {
        $index = $i % $original_count;
        // Iteration 0: $i = 0, $index = 0 % 3 = 0
        // Iteration 1: $i = 1, $index = 1 % 3 = 1
        // Iteration 2: $i = 2, $index = 2 % 3 = 2
        // Iteration 3: $i = 3, $index = 3 % 3 = 0
        // Iteration 4: $i = 4, $index = 4 % 3 = 1
        // Iteration 5: $i = 5, $index = 5 % 3 = 2
        // Iteration 6: $i = 6, $index = 6 % 3 = 0
        // Iteration 7: $i = 7, $index = 7 % 3 = 1
        // Iteration 8: $i = 8, $index = 8 % 3 = 2
        // Iteration 9: $i = 9, $index = 9 % 3 = 0
        // Iteration 10: $i = 10, $index = 10 % 3 = 1
        // Iteration 11: $i = 11, $index = 11 % 3 = 2
        // Iteration 12: $i = 12, $index = 12 % 3 = 0

        $adjusted_result[] = $result[$index];
        // https://gist.githubusercontent.com/srikat/be51ba23f804b616ce08b164c48a378f/raw/84e7814ed60ce48e1935027b61e7e0d6273c73e8/gistfile1.txt
    }

    return $adjusted_result; // Returns an array with exactly 13 items, repeating the original 3 items as needed
}, 10, 2 );

Replace hpkldp with the Bricks ID of the query loop-enabled element.

Set your desired number of items to be shown in

$desired_count = 13;

As can be seen from the comments:

  1. The loop runs 13 times (0 to 12) to create exactly 13 items.
  2. The $index calculation uses the modulo operator (the remainder that’s left after doing a division) to cycle through 0, 1, and 2 repeatedly.
  3. Each iteration adds an item from the original $result array to $adjusted_result, using the calculated $index.
  4. The process repeats the original items as needed to reach the desired count of 13.

The final $adjusted_result array contains exactly 13 items, with the pattern of the original 3 items repeating: [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0]. This ensures that no matter how many items are in the original query result (in this case, 3), the function always returns exactly 13 items.

Posts (can be of any post type)

Before:

After:

<?php

/**
 * Ensure that exactly 13 items are output.
 *
 * @param WP_Query $result   The original query result.
 * @param object   $query_obj The query object.
 * @return WP_Query Modified query result.
 */
add_filter( 'bricks/query/result', function ( WP_Query $result, object $query_obj ): WP_Query {
    // Return early if not the target element or not a post query
    if ( $query_obj->element_id !== 'hpkldp' || $query_obj->object_type !== 'post' ) {
        return $result;
    }

    $desired_count = 13; // Set this to the desired number of items

    if ( $result->have_posts() ) {
        $posts = $result->posts;

        // Sort by post title (ascending)
        // usort( $posts, function ( $a, $b ) {
        //     return strcmp( $a->post_title, $b->post_title );
        // } );

        // Ensure we have exactly the desired number of items
        $adjusted_posts = [];
        $original_count = count( $posts );

        // If we already have 13 or more items, return the original result
        if ( $original_count >= $desired_count ) {
            return $result;
        }

        for ( $i = 0; $i < $desired_count; $i++ ) {
            $index = $i % $original_count;
            $adjusted_posts[] = $posts[$index];
        }

        $result->posts = $adjusted_posts;
        $result->post_count = $desired_count;
        $result->found_posts = $desired_count;
    }

    return $result;
}, 10, 2 );