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; }