Hi,
I’m working on a client project that requires a CPT “tour”.
The “tour” CPT supports the native “Featured Image”.
The “tour” CPT as also an ACF Gallery to add other images.
Now in templates I want to render a “Bricks Carousel” that contains all tour image, so featured + acf gallery images.
- 1 - My first attempt was to create a new “Query Loop” Object Type , but the Carousel did not recognize it (other elements successfully recognized it) , so i moved on.
Further details of this attempt will be included on a later comment of this post becuase the main scope is not about this.
- 2 - My second attempt was to create a “Dynamic Data” tag and use that in Carousel source > Media > Dynamic Data.
Following the official docs i made this script (script #1 ) that doesn’t work and triggers an error.
Then , after a little debug session i modified the code like so (script #2).
Now it works, but becuase is not official I would like to have a feedback on this from core devs, to ensure that I will ship a production-ready solution.
Details about the error are in the code comments, but mainly:
- the carousel requires an array of integers (array of attachment id).
- the docs sugget to uses
bricks/dynamic_data/render_tag
with callback priority10
(as in script#1) , but in this case your callback cannot returns an array of things, only a string, due to the next filters callback that expects a string as input. - If you instead use priority
11
(as in script#2 )you can return other types, but you must add “curly braces” to the “check if this is my dynamic tag” part of the callback
Which is the production ready path i should follow ???
Thanks.
script #1
// Add a new "Dynamic Data" selectable in the dropdown
add_filter('bricks/dynamic_tags_list', function ($tags) {
// Ensure your tag is unique (best to prefix it)
$tags[] = [
'name' => '{bc__tour__all_images}',
'label' => 'BC - Tour - All Images (Featured + ACF Gallery)',
'group' => 'BC',
];
return $tags;
});
// Replace Dynamic Data Tag with real value
// TODO: How this hook is different to "bricks/dynamic_data/render_content" ???
// TODO: How this hook is different to "bricks/frontend/render_data" ???
add_filter(
'bricks/dynamic_data/render_tag',
function ($tag, $post, $context = 'text') {
// $tag is the tag name without the curly braces
//
// NOTE: 👈
// THIS CALLBACK IS INVOKED WITH PRIORITY 10, AS IN THE BRICKS DOCS,
// BUT IT WILL NOT WORK BECAUSE BRICKS COMPLAINS THAT THE RETURNED VALUE
// MUST BE STRING, AND HERE WE RETURNS AN ARRAY OF INTEGERS
if ($tag !== 'bc__tour__all_images') {
return $tag;
}
// Do your custom logic here, you should define run_my_dd_tag_logic() function
$my_value = get_value("UNRESOLVED", $post, $context);
if ($my_value === "UNRESOLVED") return $tag;
return $my_value;
},
10, // 👈
3
);
// Replace Dynamic Data Tag with real value
// TODO: How this hook is different to "bricks/dynamic_data/render_tag" ???
add_filter('bricks/dynamic_data/render_content', 'render_my_tag', 10, 3);
add_filter('bricks/frontend/render_data', 'render_my_tag', 10, 2);
function render_my_tag($content, $post, $context = 'text') {
// $content might consists of HTML and other dynamic tags
// Only look for dynamic tag {my_dd_tag}
if (strpos($content, '{bc__tour__all_images}') === false) {
return $content;
}
return $content;
// Do your custom logic here, you should define run_my_dd_tag_logic() function
$my_value = get_value("UNRESOLVED", $post, $context);
if ($my_value === "UNRESOLVED") return $content;
// Replace the tag with the value you want to display
$content = str_replace('{bc__tour__all_images}', $my_value, $content);
return $content;
}
/**
* Get all images of a "tour" CPT.
* Returns an array of "attachment ids" ( [ 24, 56, 4634, ... ] ).
* The array contains the "featured_image" followed by the ACF Gallery items
* of the ACF Field named "image_gallery".
*
* @param string $fallback
* @param \WP_Post $post
* @param "text"|"image"|"media" $context
* @return int[]
*/
function get_value($fallback, $post, $context) {
// we handle only "image" context
if ($context !== 'image') return $fallback;
// initialize an array that will contains "attachment_id" of all images
$output_images_ids = [];
// get featured image from "tour"
// and also "acf gallery images" of the "tour"
$featured_image_id = get_post_thumbnail_id($post);
$acf_gallery = \get_field("image_gallery", $post->ID);
// populate the output array
if ($featured_image_id) $output_images_ids[] = $featured_image_id;
foreach ($acf_gallery as $gallery_item_index => $gallery_item) {
if (is_int($gallery_item)) {
$output_images_ids[] = $gallery_item;
continue;
}
if (is_array($gallery_item)) {
$output_images_ids[] = $gallery_item['id'];
continue;
}
}
return $output_images_ids;
}
script #2
// Add a new "Dynamic Data" selectable in the dropdown
add_filter('bricks/dynamic_tags_list', function ($tags) {
// Ensure your tag is unique (best to prefix it)
$tags[] = [
'name' => '{bc__tour__all_images}',
'label' => 'BC - Tour - All Images (Featured + ACF Gallery)',
'group' => 'BC',
];
return $tags;
});
// Replace Dynamic Data Tag with real value
// TODO: How this hook is different to "bricks/dynamic_data/render_content" ???
// TODO: How this hook is different to "bricks/frontend/render_data" ???
add_filter(
'bricks/dynamic_data/render_tag',
function ($tag, $post, $context = 'text') {
// $tag is the tag name without the curly braces
//
// NOTE: 👈
// BECAUSE THIS CALLBACK IS INVOKED WITH PRIORITY 11
// WE CHECK FOR "{bc__tour__all_images}" , NOT "bc__tour__all_images
//
// IF THIS CALLBACK IS INVOKED WITH PRIORITY 10,
// BRICKS COMPLAINS BECAUSE THE RETURN VALUE OF THIS FUNCTION MUST BE STRING
// BUT HERE WE RETURN AN ARRAY OF INT
if ($tag !== '{bc__tour__all_images}') {
return $tag;
}
// Do your custom logic here...
$my_value = get_value("UNRESOLVED", $post, $context);
if ($my_value === "UNRESOLVED") return $tag;
return $my_value;
},
11, // 👈
3
);
// Replace Dynamic Data Tag with real value
// TODO: How this hook is different to "bricks/dynamic_data/render_tag" ???
add_filter('bricks/dynamic_data/render_content', 'render_my_tag', 10, 3);
add_filter('bricks/frontend/render_data', 'render_my_tag', 10, 2);
function render_my_tag($content, $post, $context = 'text') {
// $content might consists of HTML and other dynamic tags
// Only look for dynamic tag {bc__tour__all_images}
if (strpos($content, '{bc__tour__all_images}') === false) {
return $content;
}
return $content;
// Do your custom logic here, you should define run_my_dd_tag_logic() function
$my_value = get_value("UNRESOLVED", $post, $context);
if ($my_value === "UNRESOLVED") return $content;
// Replace the tag with the value you want to display
$content = str_replace('{bc__tour__all_images}', $my_value, $content);
return $content;
}