Inserting Random Ad Between Posts in Bricks

Updated on 5 Feb 2024

This Pro tutorial provides the steps to insert a random post of ad post type in between regular posts on the Posts page (blog posts index) whilst ensuring that pagination is not broken in Bricks.

We shall use ACF (a different plugin like Meta Box can also be used) to create a URL-type of custom field for entering the webpage that the ads should link to.

Single Tutorial Purchase Option

Lifetime access to this single tutorial can be purchased for $39 here.

Step 1

Create ad CPT.

Create an associated field group having a URL type of field.

Add as many ad CPT entries as needed.

Step 2

Edit the Page set as the Posts page (at Settings → Reading) with Bricks.

Copy the following JSON and paste to paste the entire pre-built Section from our test site:

JSON link

Click Save.

Step 3

Bricks → Settings → General → Tick “Generate custom image sizes”.

Save settings.

Step 4

Add the following in child theme‘s functions.php or a code snippets plugin:

// Function to get a random post ID of the given post type.
function bl_get_random_post_id( $post_type = 'post' ): int {
	$args = [
			'post_type'      => $post_type,
			'posts_per_page' => 1,
			'orderby'        => 'rand',
			'fields'         => 'ids',
	];

	$posts = get_posts( $args );

	return $posts[0];
}

add_filter( 'bricks/query/result', function( $result, $query_obj ) {
	if ( $query_obj->element_id !== 'qnnzch' ) {
		return $result;
	}

	if ( $result->have_posts() ) {
		// array of post IDs from the result object
		$postIDs = wp_list_pluck( $result->posts, 'ID' );

		// insert a random post ID of "ad" post type in the above array after the 4th element
		array_splice( $postIDs, 4, 0, bl_get_random_post_id( 'ad' ) );
		
		// array of post objects from the above post IDs
		$posts = array_map( function( $post_id ) {
			return get_post( $post_id );
		}, $postIDs );

		// set the posts property of the result object to the above array of post objects
		$result->posts = $posts;
	}

	return $result;
}, 10, 2 );

add_action( 'pre_get_posts', function( $query ) {
	// make sure this is the right query
	if ( ! $query->is_home() ) {
		return;
	}

	$ppp = 8; // 1 less than the number of Posts per page set in Bricks query
	
	// get the current page number - will be 1 for the first page, 2 for the second page, etc.
	$paged = $query->query_vars[ 'paged' ];

	// detect and handle pagination
	if ( $query->is_paged ) { // pages 2, 3..
		$offset = $ppp + ( ( $paged - 2 ) * $ppp );
		// for page 2, offset = 8
		// for page 3, offset = 16...

		// apply offset
		$query->set( 'offset', $offset );
	}
} );

// Correct WordPress's query result count.
add_filter( 'found_posts', function( $found_posts, $query ) {
	// make sure this is the right query
	if ( is_admin() || ! $query->is_home() ) {
		return $found_posts;
	}

	$ppp = 8; // 1 less than the number of Posts per page set in Bricks query
	
	$number_of_ads = round( ( $found_posts / $ppp ) * ( 1 + ( 1 / ( $ppp - 1 ) ) ) );
	
	return $found_posts + $number_of_ads;
}, 10, 2 );

Replace qnnzch with the Bricks ID of the Block element on which query loop is enabled or select block.

Check the front end.