WooCommerce产品画廊添加视频时链接误批量应用问题求助
WooCommerce产品画廊添加视频时链接误批量应用问题求助
Hey Xavier, let's dig into why your video link is getting applied to all gallery images! After looking over your code, I spotted a few potential issues that could be causing this unexpected behavior:
Possible Root Causes
- Array pointer interference: The
end()function moves the internal pointer of the$attachment_idsarray to the last element. Since thewoocommerce_single_product_image_thumbnail_htmlfilter runs for every thumbnail in the gallery, this can lead to wonky behavior when WordPress processes subsequent thumbnails—even if you're fetching the array each time, edge cases might make$last_attachment_idreturn incorrect values. - Empty gallery edge case: If a product has no gallery images,
$attachment_idswill be empty.end($attachment_ids)returnsfalse, and if$attachment_id(passed to the filter) also evaluates tofalsein some contexts, your video code will get appended to every element. - Fancybox grouping overlap: Your video link uses
data-fancybox="gallery", which matches the default WooCommerce gallery attribute. This means Fancybox will lump your video into the same gallery set as the product images—so clicking any image will cycle through all items, including the video. If you wanted the video to open independently, this isn't the right setup.
Fixed Code
Here's a revised version of your code that addresses these issues:
add_filter( 'woocommerce_single_product_image_thumbnail_html', 'add_video_to_product_gallery', 99, 2 ); function add_video_to_product_gallery( $html, $attachment_id ) { global $product; // Ensure we have a valid product object before proceeding if ( ! $product ) { return $html; } $attachment_ids = $product->get_gallery_image_ids(); // Exit early if there are no gallery images (adjust if you want to add video anyway) if ( empty( $attachment_ids ) ) { return $html; } // Get last attachment ID without messing with array pointers $last_attachment_id = $attachment_ids[count($attachment_ids) - 1]; if ( $attachment_id == $last_attachment_id ) { $video_url = 'https://player.vimeo.com/video/12345678'; $thumbnail_url = 'https://test.com/Thumbnail.png'; // Use a unique Fancybox group for the video to keep it separate from image gallery $html .= '<div class="product-video-thumbnail">'; $html .= '<a href="' . esc_url( $video_url ) . '" data-fancybox="product-video">'; $html .= '<img src="' . esc_url( $thumbnail_url ) . '" alt="' . esc_attr__( 'Video Thumbnail', 'your-text-domain' ) . '" />'; $html .= '</a>'; $html .= '</div>'; } return $html; }
What Changed?
- Safer last ID retrieval: Instead of
end(), we usecount($attachment_ids) - 1to grab the last array index. This avoids altering the array's internal pointer, so there's no weird behavior across filter runs. - Safety checks: We now verify that
$productexists and the gallery isn't empty, preventing the video code from being added when it shouldn't be. - Security best practices: Added
esc_url()andesc_attr()to sanitize dynamic values—this helps avoid security risks and ensures your code follows WordPress/WooCommerce standards. - Separate Fancybox group: Changed
data-fancybox="gallery"todata-fancybox="product-video"so the video opens in its own Fancybox instance. If you want the video to be part of the same image slideshow, just revert this attribute back to"gallery".
If your original goal was to replace the last gallery image with the video thumbnail (instead of adding it after), just change $html .= to $html = inside the if block—this will overwrite the last image's HTML with your video thumbnail.
备注:内容来源于stack exchange,提问作者xavierde
相关产品推荐
相关产品推荐

