Background
I’m the marketing manager over at Horner APG, a global industrial automation control company, currently responsible for the design and development of our new website.
It’s no secret that I’m huge fan of WooCommerce. The Woo team is simply creating a wonderful product backed by a great community of support. I may have stepped out a bit from the norm by choosing it to power our corporate store but I think it’ll pay off in the long run.
While building our new site I noticed our old store included links to product videos powered by YouTube. By default, as designed by WordPress, videos are not supported by the WordPress image gallery. As a result, I started looking for a solution that would modify the default behavior to accept external links. Below is the solution I used to make that happen.
Solution
Eventually, I found some code shared by Geekee Media that adds a “custom link” input box in the WordPress “Add Media panel.”
Geekee Media has since updated the code below and it’s freely available on Github if you’d like to grab the latest version which I haven’t tested yet. Hit me up in the comments below if this process works with his latest code submission.
- Add the first block of code below to your functions.php file.
- Add the second block of code below to your functions.php file.
- I’ve modified it to include a unique link ID (id=”tip4″) that’s being called in my footer with specific Fancybox settings. I know it’s not the cleanest process but I’ll leave it to you to tidy it up.
- Add the third block of code to your footer (Fancybox settings).
- How to include a video in the product gallery:
- Edit your product and upload an image ( ex: video player ) that signifies the gallery link will be of a video. You’ll see from my screenshot that I’ve included a link to YouTube where my video is hosted.
Demo: Horner XLt Industrial Automation Controller
First block of code
Adds a custom field to your image gallery that you’ll use to include your video link.
/* ------------------------------- CUSTOM LINK PER GALLERY IMAGE WHICH ALLOWS US TO DISPLAY VIDEO in WP GALLERY ------------------------------- */ function rt_image_attachment_fields_to_edit($form_fields, $post) { $form_fields["rt-image-link"] = array( "label" => __("Custom Link"), "input" => "text", // default "value" => get_post_meta($post->ID, "_rt-image-link", true), //"helps" => __("To be used with special slider added via [rt_carousel] shortcode."), ); return $form_fields; } add_filter("attachment_fields_to_edit", "rt_image_attachment_fields_to_edit", null, 2); function rt_image_attachment_fields_to_save($post, $attachment) { // $attachment part of the form $_POST ($_POST[attachments][postID]) // $post['post_type'] == 'attachment' if( isset($attachment['rt-image-link']) ){ // update_post_meta(postID, meta_key, meta_value); update_post_meta($post['ID'], '_rt-image-link', $attachment['rt-image-link']); } return $post; } add_filter("attachment_fields_to_save", "rt_image_attachment_fields_to_save", null , 2); /* ------------------------------- MODIFIED CORE FUNCTION ------------------------------- */ add_shortcode('gallery', 'geekee_gallery_shortcode'); /** * The Gallery shortcode. * * This implements the functionality of the Gallery Shortcode for displaying * WordPress images on a post. * * @since 2.5.0 * * @param array $attr Attributes attributed to the shortcode. * @return string HTML content to display gallery. */ function geekee_gallery_shortcode($attr) { global $post, $wp_locale; static $instance = 0; $instance++; // Allow plugins/themes to override the default gallery template. $output = apply_filters('post_gallery', '', $attr); if ( $output != '' ) return $output; // We're trusting author input, so let's at least make sure it looks like a valid orderby statement if ( isset( $attr['orderby'] ) ) { $attr['orderby'] = sanitize_sql_orderby( $attr['orderby'] ); if ( !$attr['orderby'] ) unset( $attr['orderby'] ); } extract(shortcode_atts(array( 'order' => 'ASC', 'orderby' => 'menu_order ID', 'id' => $post->ID, 'itemtag' => 'dl', 'icontag' => 'dt', 'captiontag' => 'dd', 'columns' => 3, 'size' => 'thumbnail', 'include' => '', 'exclude' => '' ), $attr)); $id = intval($id); if ( 'RAND' == $order ) $orderby = 'none'; if ( !empty($include) ) { $include = preg_replace( '/[^0-9,]+/', '', $include ); $_attachments = get_posts( array('include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); $attachments = array(); foreach ( $_attachments as $key => $val ) { $attachments[$val->ID] = $_attachments[$key]; } } elseif ( !empty($exclude) ) { $exclude = preg_replace( '/[^0-9,]+/', '', $exclude ); $attachments = get_children( array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); } else { $attachments = get_children( array('post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); } if ( empty($attachments) ) return ''; if ( is_feed() ) { $output = "\n"; foreach ( $attachments as $att_id => $attachment ) $output .= wp_get_attachment_link($att_id, $size, true) . "\n"; return $output; } $itemtag = tag_escape($itemtag); $captiontag = tag_escape($captiontag); $columns = intval($columns); $itemwidth = $columns > 0 ? floor(100/$columns) : 100; $float = is_rtl() ? 'right' : 'left'; $selector = "gallery-{$instance}"; $gallery_style = $gallery_div = ''; if ( apply_filters( 'use_default_gallery_style', true ) ) $gallery_style = " <style type='text/css'> #{$selector} { margin: auto; } #{$selector} .gallery-item { float: {$float}; margin-top: 10px; text-align: center; width: {$itemwidth}%; } #{$selector} img { border: 2px solid #cfcfcf; } #{$selector} .gallery-caption { margin-left: 0; } </style> <!-- see gallery_shortcode() in wp-includes/media.php -->"; $size_class = sanitize_html_class( $size ); $gallery_div = "<div id='$selector' class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'>"; $output = apply_filters( 'gallery_style', $gallery_style . "\n\t\t" . $gallery_div ); $i = 0; foreach ( $attachments as $id => $attachment ) { $link = isset($attr['link']) && 'file' == $attr['link'] ? wp_get_attachment_link($id, $size, false, false) : wp_get_attachment_link($id, $size, true, false); /* ------------------------------- MODIFICATION ################ ------------------------------- */ $image = wp_get_attachment_image($id, $size, false); $attachment_meta = get_post_meta($id, '_rt-image-link', true); if($attachment_meta){ if($attr['link'] == 'custom_url'){ $link = $attachment_meta; } } $output .= "<{$itemtag} class='gallery-item'>"; $output .= "<{$icontag} class='gallery-icon'>"; /* ------------------------------- MODIFICATION ################ ------------------------------- */ if($attachment_meta){ $output .= "<a href='$link'>$image</a>"; } else { $output .= $link; } $output .= "</{$icontag}>"; if ( $captiontag && trim($attachment->post_excerpt) ) { $output .= "<{$captiontag} class='gallery-caption'>" . wptexturize($attachment->post_excerpt) . "</{$captiontag}>"; } $output .= "</{$itemtag}>"; if ( $columns > 0 && ++$i % $columns == 0 ) $output .= '<br style="clear: both;" />'; } $output .= "<br style='clear: both;' /></div>\n"; return $output; }
Second block of code
Then I assigned a specific ID to the video link. This class triggered the Fancybox plugin that currently powers the WooCommerce product image gallery.
if (!function_exists('woocommerce_show_product_thumbnails')) { function woocommerce_show_product_thumbnails() { global $_product, $post; echo '<div class="thumbnails">'; $thumb_id = get_post_thumbnail_id(); $small_thumbnail_size = apply_filters('single_product_small_thumbnail_size', 'shop_thumbnail'); $args = array( 'post_type' => 'attachment', 'order' => 'ASC', 'orderby' => 'menu_order ID', 'numberposts' => -1, 'post_status' => null, 'post_parent' => $post->ID, 'post__not_in' => array($thumb_id), 'post_mime_type' => 'image', 'meta_query' => array( array( 'key' => '_woocommerce_exclude_image', 'value' => '1', 'compare' => '!=' ) ) ); $attachments = get_posts($args); if ($attachments) : $loop = 0; $columns = apply_filters('woocommerce_product_thumbnails_columns', 3); foreach ( $attachments as $attachment ) : $loop++; $_post = & get_post( $attachment->ID ); $url = wp_get_attachment_url($_post->ID); $post_title = esc_attr($_post->post_title); $image = wp_get_attachment_image($attachment->ID, $small_thumbnail_size); $attachment_meta = get_post_meta($_post->ID, '_rt-image-link', true); $link = $attachment_meta; if (isset($attachment_meta['true'])) { echo '<a href="'.$link.'" title="'.$post_title.'" rel="thumbnails" id="tip4" class=" '; if ($loop==1 || ($loop-1)%$columns==0) echo 'first'; if ($loop%$columns==0) echo 'last'; echo '">'.$image.'</a>'; } else { echo '<a href="'.$url.'" title="'.$post_title.'" rel="thumbnails" class="zoom '; if ($loop==1 || ($loop-1)%$columns==0) echo 'first'; if ($loop%$columns==0) echo 'last'; echo '">'.$image.'</a>'; } endforeach; endif; wp_reset_query(); echo '</div>'; } }
Third block of code.
This snippet of code is to trigger the Fancybox plugin. Edit the settings for your purposes.
<script type="text/javascript"> $("#tip4").click(function() { $.fancybox({ 'padding' : 0, 'autoScale' : false, 'transitionIn' : 'none', 'transitionOut' : 'none', 'title' : this.title, 'width' : 680, 'height' : 495, 'href' : this.href.replace(new RegExp("watch\\?v=", "i"), 'v/'), 'type' : 'swf', 'swf' : { 'wmode' : 'transparent', 'allowfullscreen' : 'true' } }); return false; }); </script>
Final Thoughts
I’m by no means the strongest coder. So if you cook up a better solution please share it with the rest of us. Maybe I don’t need the full second block of code? I know I was having issues a few months ago with product image order so part of the second block of code probably includes my fix. It might not be needed any longer or an issue specific to my project.
May 27, 2012
Steve
Hey Ben. It appears as though you are the only person on the internet trying to add video to WooTheme products! I tried what you posted here (looks like you have a ton of other cool stuff as well!), but, unfortunately, when I click on the thumbnail it takes me directly to the Youtube video, bypassing fancybox… Any ideas?
Jun 1, 2012
Benny
Whaddup Steve
Apologies for the late reply. Any JS errors showing up in firebug console? Sounds like it’s not triggering fancybox for some reason. I can help you figure this out. Feel free to hit me up on twitter @benvblanco. I’m usually more responsive.
Edit: Also, make sure to grab the latest code/plugin from Github. I recently updated to the plugin and with the fancybox trigger it works great.
Sweet site by the way! Really like the design. God Bless 🙂
May 7, 2013
Joseph Orr
Steve, did you ever get this to work? I’d love to get this working, but the having the same problem you are.
Jun 22, 2012
Benny
Hey Everyone —
Forgot to add to make sure you use the old youtube video link from the old embed code. There’s a checkbox available on YouTube to grab it.
Example: http://www.youtube.com/v/DQyluJq6FQI
I don’t think their new short-links work with the scripts.
Cheers!
Benny
May 7, 2013
Joseph Orr
Think this would work with Vimeo as well?
May 7, 2013
Joseph Orr
If anybody can help me to get this working with Vimeo, I would be extremely grateful. I have a client who wants to leverage Vimeos capabilities, but when I try to get this all working, it doesn’t have a player in it. The fancybox comes up fine, the video just doesn’t play 🙁
May 7, 2013
Ben Blanco
Hi Joe,
I’ll setup a test install with Woocommerce and this plugin. I’m sure we can get Vimeo to work. I’ll try to help out the best I can. Feel free to hit me up on Twitter or via email.
Are you running the latest version of Woocommerce?
Cheers!
Ben
May 7, 2013
Joseph Orr
Hey Ben,
I got it all working! I copied your code from the demo website and instead of using the YouTube link, stripped the iFrame link in Vimeo and used that (http://player
Here was my final Javascript:
jQuery(document).ready(function($){
$(“#tip4”).click(function() {
$.fancybox({
‘padding’ : 0,
‘autoScale’ : false,
‘transitionIn’ : ‘none’,
‘transitionOut’ : ‘none’,
‘title’ : this.title,
‘width’ : 680,
‘height’ : 495,
‘content’ : ‘static/common_structure.html’,
‘href’ : this.href.replace(new RegExp(“watch\\?v=”, “i”), ‘v/’),
‘type’ : ‘iframe’,
‘iframe’ : {
‘scrolling’ : ‘auto’,
‘preload’ : ‘true’
}
});
return false;
});
$(“.pop”).fancybox({
‘width’ : 600,
‘height’ : 600,
‘autoScale’ : false,
‘transitionIn’ : ‘none’,
‘transitionOut’ : ‘none’,
‘type’ : ‘iframe’
});
$(“.webinar”).fancybox({
‘width’ : 600,
‘height’ : 400,
‘autoScale’ : false,
‘transitionIn’ : ‘none’,
‘transitionOut’ : ‘none’,
‘type’ : ‘iframe’
});
$(“.sizing”).fancybox({
‘width’ : 800,
‘height’ : 800,
‘autoScale’ : false,
‘transitionIn’ : ‘none’,
‘transitionOut’ : ‘none’,
‘type’ : ‘iframe’
});
$(“.colcontent”).hide();
//toggle the componenet with class msg_body
$(“.coltitle”).click(function()
{
$(this).next(“.colcontent”).slideToggle(200);
});
});
Now if you can just help me get a PNG play button to overlay over the image!!! Seriously though, do you think you could help me do that? I know it takes having 2 divs, but thats the extent of my trying 🙁
May 8, 2013
Joseph Orr
Ben,
Let me know if you could help me get a ‘Play’ icon to overlay on top of that thumbnail. I would be indebted to you forever! I’m just not sure how to accomplish this, but I’m guessing some kind of function or edit to a PHP and CSS file would do the trick? Any help is welcome here 🙂
May 9, 2013
Timi
Hi,
Is there any problem? When I paste code 1 & 2 into function.php I get to see huge text in my website & dashboard. Whats the wrong? AND I didn’t get any footer.php in my theme. Please help.
May 10, 2013
Ben Blanco
Hi Timi,
I haven’t tested this code with the latest version of WooCommerce in a long time. My best advise is to use the latest version of this plugin instead of copying the code above.
Link: https://github.com/brewern/gallery-custom-link
Let me know if that helps. I’ll test again soon and update this post accordingly.
Cheers
Ben
Oct 1, 2013
julia
Hi, I’m so frustrated. Your code works, but it opens the youtube video across the entire browser. I tried the new code you pointed to, but that doesn’t seem to work for the woocommerce gallery. So, I don’t know what I’m doing wrong. First I tried to put your 3rd piece of code in footer.php, but that screwed up the site. Then I added a php widget to the footer and pasted your code in there, but that doesn’t seem to do anything irregardless of the format of the YouTube code I use.
I then tried to use the vimeo guy’s code, but I guess I’m putting this code in the wrong place, because that didn’t do anything either.
I also installed a fancybox plugin, but maybe I need a specific one?
So far, I’ve got the video loading when I hit the image (thanks to your first 2 pieces of code) … THANK YOU! … but I can’t seem to get the formatting right.
Any help would be very much appreciated!
Sep 21, 2015
Kency
If you want to embed Youtube and Vimeo videos to product image gallery, a new plugin will be very helpful to all which is free and does not require to edit any core files of WooCommerce. https://wordpress.org/plugins/woocommerce-embed-videos-to-product-image-gallery/