functions.php code.
bricks builder tag for single product.
this code gets the all images as a ul li list very simple implementation.
// {product_image_list}
add_filter( 'bricks/dynamic_tags_list', 'register_product_image_list' );
function register_product_image_list( $tags ) {
$tags[] = [
'name' => '{product_image_list}',
'label' => 'Product Image List',
'group' => 'Custom Tags',
];
return $tags;
}
// 2. Render the custom tag
add_filter( 'bricks/dynamic_data/render_tag', 'render_product_image_list', 10, 3 );
function render_product_image_list( $tag, $post, $context = 'text' ) {
// Stop if it's not our custom tag
if ( $tag !== 'product_image_list' ) {
return $tag;
}
// Ensure it's a WooCommerce product
if ( 'product' !== $post->post_type ) {
return 'Not a product.';
}
// Get the product object from the post
$product = wc_get_product( $post->ID );
// Ensure the product actually exists
if ( ! $product ) {
return 'Invalid product.';
}
// Prepare an array to store all image URLs
$image_urls = [];
// Get the main (featured) product image
$featured_image_id = $product->get_image_id();
$featured_image_url = $featured_image_id ? wp_get_attachment_url( $featured_image_id ) : '';
// If the product has a featured image, let's add it first
if ( $featured_image_url ) {
$image_urls[] = $featured_image_url;
}
// Get any additional gallery images (beyond the featured image)
$gallery_image_ids = $product->get_gallery_image_ids();
if ( ! empty( $gallery_image_ids ) ) {
foreach ( $gallery_image_ids as $gallery_id ) {
$gallery_image_url = wp_get_attachment_url( $gallery_id );
if ( $gallery_image_url ) {
$image_urls[] = $gallery_image_url;
}
}
}
// If it's a variable product, also collect the variation images
if ( $product->is_type( 'variable' ) ) {
$variations = $product->get_available_variations();
$variation_image_urls = [];
foreach ( $variations as $variation ) {
// Get the variation product object
$variation_product = wc_get_product( $variation['variation_id'] );
$variation_image_id = $variation_product ? $variation_product->get_image_id() : 0;
// First, try the variation's featured image (if set)
if ( $variation_image_id ) {
$variation_image_urls[] = wp_get_attachment_url( $variation_image_id );
}
// If there's no featured image on the variation, try the variation's default image
elseif ( ! empty( $variation['image']['src'] ) ) {
$variation_image_urls[] = $variation['image']['src'];
}
}
// Merge variation images with our main array
$image_urls = array_merge( $image_urls, $variation_image_urls );
}
// Remove any duplicates (just in case)
$image_urls = array_unique( $image_urls );
// Build the HTML list of images
if ( ! empty( $image_urls ) ) {
$list_html = '<ul class="product-image-list">';
foreach ( $image_urls as $url ) {
$url = esc_url( $url );
$list_html .= '<li><img src="' . $url . '" alt="Product Image"></li>';
}
$list_html .= '</ul>';
return $list_html;
}
return 'No product images available.';
}
// 3. Replace the custom tag in content dynamically
add_filter( 'bricks/dynamic_data/render_content', 'render_product_image_list_in_content', 10, 3 );
function render_product_image_list_in_content( $content, $post, $context = 'text' ) {
// Only proceed if our custom tag is found in the content
if ( strpos( $content, '{product_image_list}' ) !== false ) {
$product_image_list = render_product_image_list( 'product_image_list', $post, $context );
// Replace the tag with the generated HTML
$content = str_replace( '{product_image_list}', $product_image_list, $content );
}
return $content;
}
and here is the optional one you can choice what to show with this tag.
{product_image_list} for Featured Image + Gallery
{product_image_list:variations} for Featured Image + Variation images.
// {product_image_list}
// {product_image_list:variations}
add_filter( 'bricks/dynamic_tags_list', 'register_product_image_list' );
function register_product_image_list( $tags ) {
// Tag for featured + gallery
$tags[] = [
'name' => '{product_image_list}',
'label' => 'Product Image List (Featured + Gallery)',
'group' => 'Custom Tags',
];
// Tag for featured + variations
$tags[] = [
'name' => '{product_image_list:variations}',
'label' => 'Product Image List (Featured + Variations)',
'group' => 'Custom Tags',
];
return $tags;
}
// 2. Render the custom tag
add_filter( 'bricks/dynamic_data/render_tag', 'render_product_image_list', 10, 3 );
function render_product_image_list( $tag, $post, $context = 'text' ) {
// Stop if it's not our custom tag
// (i.e. if it's neither {product_image_list} nor {product_image_list:variations})
if ( $tag !== 'product_image_list' && $tag !== 'product_image_list:variations' ) {
return $tag;
}
// Ensure it's a WooCommerce product
if ( 'product' !== $post->post_type ) {
return 'Not a product.';
}
// Get the product object from the post
$product = wc_get_product( $post->ID );
// Ensure the product actually exists
if ( ! $product ) {
return 'Invalid product.';
}
// Prepare an array to store all image URLs
$image_urls = [];
// Get the main (featured) product image
$featured_image_id = $product->get_image_id();
$featured_image_url = $featured_image_id ? wp_get_attachment_url( $featured_image_id ) : '';
// If the product has a featured image, let's add it first
if ( $featured_image_url ) {
$image_urls[] = $featured_image_url;
}
// If the user used {product_image_list} (no variations), include the gallery images
if ( $tag === 'product_image_list' ) {
// Get any additional gallery images (beyond the featured image)
$gallery_image_ids = $product->get_gallery_image_ids();
if ( ! empty( $gallery_image_ids ) ) {
foreach ( $gallery_image_ids as $gallery_id ) {
$gallery_image_url = wp_get_attachment_url( $gallery_id );
if ( $gallery_image_url ) {
$image_urls[] = $gallery_image_url;
}
}
}
}
// If the user used {product_image_list:variations} and the product is variable, collect variation images
if ( $tag === 'product_image_list:variations' && $product->is_type( 'variable' ) ) {
$variations = $product->get_available_variations();
$variation_image_urls = [];
foreach ( $variations as $variation ) {
// Get the variation product object
$variation_product = wc_get_product( $variation['variation_id'] );
$variation_image_id = $variation_product ? $variation_product->get_image_id() : 0;
// First, try the variation's featured image (if set)
if ( $variation_image_id ) {
$variation_image_urls[] = wp_get_attachment_url( $variation_image_id );
}
// If there's no featured image on the variation, try the variation's default image
elseif ( ! empty( $variation['image']['src'] ) ) {
$variation_image_urls[] = $variation['image']['src'];
}
}
// Merge variation images with our main array
$image_urls = array_merge( $image_urls, $variation_image_urls );
}
// Remove any duplicates (just in case)
$image_urls = array_unique( $image_urls );
// Build the HTML list of images
if ( ! empty( $image_urls ) ) {
$list_html = '<ul class="product-image-list">';
foreach ( $image_urls as $url ) {
$url = esc_url( $url );
$list_html .= '<li><img src="' . $url . '" alt="Product Image"></li>';
}
$list_html .= '</ul>';
return $list_html;
}
return 'No product images available.';
}
// 3. Replace the custom tags in content dynamically
add_filter( 'bricks/dynamic_data/render_content', 'render_product_image_list_in_content', 10, 3 );
function render_product_image_list_in_content( $content, $post, $context = 'text' ) {
// First replace {product_image_list:variations} (so it doesn't get overshadowed by {product_image_list})
if ( strpos( $content, '{product_image_list:variations}' ) !== false ) {
$product_image_list_variations = render_product_image_list( 'product_image_list:variations', $post, $context );
$content = str_replace( '{product_image_list:variations}', $product_image_list_variations, $content );
}
// Then replace {product_image_list}
if ( strpos( $content, '{product_image_list}' ) !== false ) {
$product_image_list = render_product_image_list( 'product_image_list', $post, $context );
$content = str_replace( '{product_image_list}', $product_image_list, $content );
}
return $content;
}
and here is another alternative this has some style fixes and add auto .active class to the thumbnails depending on active big image on right so you can style it with css easily.
same as before {product_image_list_gallery} gets the featured+gallery
{product_image_list_gallery:variations} gets the featured+variation images
// {product_image_list_gallery} {product_image_list_gallery:variations}
add_filter( 'bricks/dynamic_tags_list', 'register_product_image_list_gallery' );
function register_product_image_list_gallery( $tags ) {
// Tag for featured + gallery
$tags[] = [
'name' => '{product_image_list_gallery}',
'label' => 'Product Image List Gallery (Featured + Gallery)',
'group' => 'Custom Tags',
];
// Tag for featured + variations
$tags[] = [
'name' => '{product_image_list_gallery:variations}',
'label' => 'Product Image List Gallery (Featured + Variations)',
'group' => 'Custom Tags',
];
return $tags;
}
// 2. Render the custom tag
add_filter( 'bricks/dynamic_data/render_tag', 'render_product_image_list_gallery', 10, 3 );
function render_product_image_list_gallery( $tag, $post, $context = 'text' ) {
// Stop if it's not our custom tag
if ( $tag !== 'product_image_list_gallery' && $tag !== 'product_image_list_gallery:variations' ) {
return $tag;
}
// Ensure it's a WooCommerce product
if ( 'product' !== $post->post_type ) {
return 'Not a product.';
}
// Get the product object
$product = wc_get_product( $post->ID );
if ( ! $product ) {
return 'Invalid product.';
}
// Prepare an array to store all image URLs
$image_urls = [];
// Get the main (featured) product image
$featured_image_id = $product->get_image_id();
$featured_image_url = $featured_image_id ? wp_get_attachment_url( $featured_image_id ) : '';
// If the product has a featured image, add it first
if ( $featured_image_url ) {
$image_urls[] = $featured_image_url;
}
// If the user used {product_image_list_gallery} (no variations), include the gallery images
if ( $tag === 'product_image_list_gallery' ) {
$gallery_image_ids = $product->get_gallery_image_ids();
if ( ! empty( $gallery_image_ids ) ) {
foreach ( $gallery_image_ids as $gallery_id ) {
$gallery_image_url = wp_get_attachment_url( $gallery_id );
if ( $gallery_image_url ) {
$image_urls[] = $gallery_image_url;
}
}
}
}
// If the user used {product_image_list_gallery:variations} and the product is variable, collect variation images
if ( $tag === 'product_image_list_gallery:variations' && $product->is_type( 'variable' ) ) {
$variations = $product->get_available_variations();
$variation_image_urls = [];
foreach ( $variations as $variation ) {
$variation_product = wc_get_product( $variation['variation_id'] );
$variation_image_id = $variation_product ? $variation_product->get_image_id() : 0;
// Variation's featured image
if ( $variation_image_id ) {
$variation_image_urls[] = wp_get_attachment_url( $variation_image_id );
}
// Variation default image
elseif ( ! empty( $variation['image']['src'] ) ) {
$variation_image_urls[] = $variation['image']['src'];
}
}
// Merge variation images
$image_urls = array_merge( $image_urls, $variation_image_urls );
}
// Remove duplicates
$image_urls = array_unique( $image_urls );
// Build the simple gallery HTML (left thumbnails, right big image) if we have images
if ( ! empty( $image_urls ) ) {
// Re-index the array to easily get the first item
$image_urls = array_values( $image_urls );
$first_image_url = esc_url( $image_urls[0] );
// Start building HTML
$list_html = '<div class="product-image-gallery" style="width:100%; display: flex; gap: 10px;">';
// Unique class & function names based on product ID
$thumbnail_wrapper_class = 'left-thumbnails-' . $post->ID;
$update_function_name = 'updateActiveThumbnail' . $post->ID;
// Left thumbnails
$list_html .= '<div class="' . $thumbnail_wrapper_class . '" style="width: 100px;">';
$list_html .= '<ul style="list-style: none; margin: 0; padding: 0;">';
foreach ( $image_urls as $index => $url ) {
$url_escaped = esc_url( $url );
$active_class = ( $index === 0 ) ? ' active' : ''; // The first thumbnail is active by default
$list_html .= '<li style="margin-bottom: 10px;">';
$list_html .= '<img
src="' . $url_escaped . '"
alt="Product Image"
class="thumb' . $active_class . '"
style="width: ; height: ; cursor:pointer;"
onclick="' . $update_function_name . '(this)"
/>';
$list_html .= '</li>';
}
$list_html .= '</ul>';
$list_html .= '</div>';
// Right big image
$list_html .= '<div class="right-big" style="width:auto; flex:1">';
$list_html .= '<img
id="mainImage' . $post->ID . '"
src="' . $first_image_url . '"
alt="Product Image"
style=""
/>';
$list_html .= '</div>';
// Close wrapper
$list_html .= '</div>';
// Inline JS to handle active class switching
// Note: If you have multiple products on one page, each will have its own function
// named uniquely by the product ID to avoid conflicts.
$list_html .= '
<script>
function ' . $update_function_name . '(clickedImg) {
// Update main image source
document.getElementById("mainImage' . $post->ID . '").src = clickedImg.src;
// Remove .active from all thumbnails
var thumbnails = document.querySelectorAll(".' . $thumbnail_wrapper_class . ' img.thumb");
thumbnails.forEach(function(img) {
img.classList.remove("active");
});
// Add .active to the clicked thumbnail
clickedImg.classList.add("active");
}
</script>
';
return $list_html;
}
return 'No product images available.';
}
// 3. Replace the custom tags in content dynamically
add_filter( 'bricks/dynamic_data/render_content', 'render_product_image_list_gallery_in_content', 10, 3 );
function render_product_image_list_gallery_in_content( $content, $post, $context = 'text' ) {
// First replace {product_image_list_gallery:variations}
if ( strpos( $content, '{product_image_list_gallery:variations}' ) !== false ) {
$product_image_list_gallery_variations = render_product_image_list_gallery( 'product_image_list_gallery:variations', $post, $context );
$content = str_replace( '{product_image_list_gallery:variations}', $product_image_list_gallery_variations, $content );
}
// Then replace {product_image_list_gallery}
if ( strpos( $content, '{product_image_list_gallery}' ) !== false ) {
$product_image_list_gallery = render_product_image_list_gallery( 'product_image_list_gallery', $post, $context );
$content = str_replace( '{product_image_list_gallery}', $product_image_list_gallery, $content );
}
return $content;
}