Dynamic Post-specific Templates in Bricks using Meta Box/ACF Select Field

Update on 23 Aug 2023: Added steps for ACF.


Bricks builder v1.8.4 introduced an pretty useful filter called bricks/active_templates that flew under the radar.

This enables us to programmatically apply Bricks templates to pages.

Consider a common scenario where the site has a Service Custom Post Type. You want to provide your client (or yourself) the ability to select the template that should be used when a post of service type is viewed on the front end.

We, as site admins can now use the bricks/active_templates filter in conjunction with a custom fields plugin like ACF or Meta Box and add logic to load the corresponding Bricks template based on the chosen value.

This Pro tutorial provides a step-by-step walk-through on how to set this up.

Step 1

Install and activate Meta Box and Meta Box AIO.

Create your service CPT.

Resave permalinks.

Step 2

Create a field titled called say, “Service Fields” having a Select type of field like this:

List the allowable Choices one below the other.

Set the Location to be the service post type.

Step 3

Add/edit the Service CPT items and select the desired service template from the select menu dropdown.

Step 4

Go to Bricks → Templates.

Create a Template of “Single” type for each of the Services having the titles in this format:

Service Template - <choice>

Ex.:

  • Service Template – Plumbing
  • Service Template – Carpentry
  • Service Template – Electrical
  • Service Template – Renovations

Note: Copying and pasting the titles from above might result in hyphens appearing as fancy hyphens that are wider than normal hyphens. Just to be on the safe side, you might want to delete the pasted character and type a hyphen.

Edit the templates as needed.

Also create a default/fallback template titled “Service” (of “Single” type). In its template conditions, set this to be applied to all singular items of service post type. This will be used by all Service CPT entries by default and in the context of what we are setting up here, by those that do not have a template selected or when there is no matching template present.

Next, we need to ensure that when a specific value is selected from our Meta Box custom field, the corresponding Bricks template is applied.

Ex.: “Service 1” post has “Carpentry” selected and thus when it is viewed, it should be rendered using the “Service Template – Carpentry” Bricks template.

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

// Avoid Undefined Function Error when Meta Box is not active.
if ( ! function_exists( 'rwmb_meta' ) ) {
	function rwmb_meta( $key, $args = '', $post_id = null ) {
		return false;
	}
}

add_filter( 'bricks/active_templates', function ( $active_templates, $post_id, $content_type ) {
	// Return if not the frontend or $content_type is not 'content' or current post type is not 'service'
	if ( ! bricks_is_frontend() || $content_type !== 'content' || get_post_type( $post_id ) !== 'service' ) {
		return $active_templates;
	}
	
	// Prepare an array with keys being Bricks template IDs and values being Bricks template titles
	$templates = get_posts( [
		'post_type' => 'bricks_template',
		'numberposts' => -1
	] );
	
	$templatesArr = [];
	
	foreach ( $templates as $template ) {
		$templatesArr[$template->ID] = $template->post_title;
	}
	// Sample $templatesArr: https://d.pr/i/gP1TEl

	// Get the Bricks template ID based on the chosen template via Meta Box custom field
	$value = absint( array_search( 'Service Template - ' . rwmb_meta( 'service_template' ), $templatesArr ) );

	// Value not empty: Set $active_templates['content'] to the value
	if ( $value > 0 ) {
		$active_templates['content'] = $value;
	}

	return $active_templates;
}, 10, 3 );

That’s it!

Go ahead and test.

ACF

If you use ACF instead of Meta Box, the setup is similar to the above but make these changes.

In the Validation tab for the Select field, you may want to enable “Allow Null?”. Otherwise, the first choice value will appear to be the active/selected one when editing service entries. Enabling this setting will show “- Select -” in the dropdown.

Replace the code with:

add_filter( 'bricks/active_templates', function ( $active_templates, $post_id, $content_type ) {
	// Return if not the frontend or $content_type is not 'content' or current post type is not 'service' or if ACF is not active
	if ( ! bricks_is_frontend() || $content_type !== 'content' || get_post_type( $post_id ) !== 'service' || ! class_exists( 'ACF' ) ) {
		return $active_templates;
	}
	
	// Prepare an array with keys being Bricks template IDs and values being Bricks template titles
	$templates = get_posts( [
		'post_type' => 'bricks_template',
		'numberposts' => -1
	] );
	
	$templatesArr = [];
	
	foreach ( $templates as $template ) {
		$templatesArr[$template->ID] = $template->post_title;
	}
	// Sample $templatesArr: https://d.pr/i/gP1TEl

	// Flip the array so that the Bricks template titles become the keys and the Bricks template IDs become the values
	$templatesArr = array_flip( $templatesArr );

	$serviceTemplate = get_field( 'service_template' );

	if ( empty( $serviceTemplate ) ) {
		return $active_templates;
	}

	$key = 'Service Template - ' . get_field( 'service_template' );

	// Get the Bricks template ID for the given key from the $templatesArr array
	$value = $templatesArr[$key];

	// Value not empty: Set $active_templates['content'] to the value
	if ( $value > 0 ) {
		$active_templates['content'] = $value;
	}

	return $active_templates;
}, 10, 3 );