I have been struggling with the different YouTube plugins available for WordPress. You have probably read an article about incorporating those into your WordPress site over here. However I was not really satisfied with what I have found so far. Now that could be because I was not willing to pay for a premium product. In all honesty I strongly believe that for a product such as WordPress, there must be a free satisfying way to get this implemented. So, I have decided to take it on me and started looking for ways to incorporate YouTube videos into Genesis.

It took me some time to get the code to where it is today. So I hope this gets handy to whomever wants to do the same. I have to give special thanks to Gary Jones who has been very helpful on guiding me to get the code lighter.

There is a different way of implementing this by using ACF Pro which has been written by Sridhar Katakam. The difference between the two is that I will be using CPT to manage the videos whereas Sridhar is using a page template to handle all the videos.

This is the final result

I have kept it simple, so its just a matter to tweaking the CSS code to improve the way the page looks.

Please note that this was implemented on a fresh install of Genesis Sample child theme.

Let us start

1. Create a custom post type for YouTube videos

functions.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 <?php // Only include the code below this line add_action ( 'init' , 'register_cpt_youtube_videos' ) ; /** * Create YouTube videos custom post type */ function register_cpt_youtube_videos ( ) { $labels = array ( 'name' = > __ ( 'YouTube Videos' , 'youtube_videos' ) , 'singular_name' = > __ ( 'YouTube Video' , 'youtube_videos' ) , 'add_new' = > __ ( 'Add New Video' , 'youtube_videos' ) , 'add_new_item' = > __ ( 'Add New YouTube Video' , 'youtube_videos' ) , 'edit_item' = > __ ( 'Edit YouTube Video' , 'youtube_videos' ) , 'new_item' = > __ ( 'New YouTube Video' , 'youtube_videos' ) , 'view_item' = > __ ( 'View YouTube Video' , 'youtube_videos' ) , 'search_items' = > __ ( 'Search YouTube Videos' , 'youtube_videos' ) , 'not_found' = > __ ( 'No youtube videos found' , 'youtube_videos' ) , 'not_found_in_trash' = > __ ( 'No youtube videos found in Trash' , 'youtube_videos' ) , 'parent_item_colon' = > __ ( 'Parent YouTube Video:' , 'youtube_videos' ) , 'menu_name' = > __ ( 'YouTube Videos' , 'youtube_videos' ) , ) ; $args = array ( 'labels' = > $labels , 'hierarchical' = > false , 'description' = > 'Custom Post Types for YouTube Videos Only.' , 'supports' = > array ( 'title' ) , 'public' = > true , 'show_ui' = > true , 'show_in_menu' = > true , 'menu_position' = > 20 , 'menu_icon' = > 'dashicons-video-alt3' , 'show_in_nav_menus' = > true , 'publicly_queryable' = > true , 'exclude_from_search' = > true , 'has_archive' = > true , 'query_var' = > true , 'can_export' = > true , 'rewrite' = > true , 'capability_type' = > 'post' ) ; register_post_type ( 'youtube_videos' , $args ) ; } add_action ( 'genesis_entry_content' , 'io_youtube_singlaur_post' ) ; /** * Add video to post content, if post has youtube video assigned. */ function io_youtube_singlaur_post ( ) { $video_id = io_get_youtube_video_id ( ) ; if ( ! $video_id ) { return ; } if ( is_singular ( $post_types = 'youtube_videos' ) ) { printf ( '<iframe width="800" height="450" src="https://www.youtube.com/embed/%s" frameborder="0" allowfullscreen></iframe>' , $video_id ) ; } } /** * Get YouTube video ID from URL in current post meta. * * Empty string if not found. * * @return string Video ID, or empty string if not found for current post. */ function io_get_youtube_video_id ( ) { $video_id = '' ; $link = get_post_meta ( get_the_ID ( ) , 'youtube_url' , true ) ; if ( preg_match ( io_get_youtube_url_regex ( ) , $link , $match ) ) { $video_id = $match [ 1 ] ; } return $video_id ; } /** * Get YouTube URL pattern. * * @return string Regex pattern. */ function io_get_youtube_url_regex ( ) { return '%(?:youtube(?:-nocookie)?\.com/(?:[\w\-?&!#=,;]+/[\w\-?&!#=/,;]+/|(?:v|e(?:mbed)?)/|[\w\-?&!#=,;]*[?&]v=)|youtu\.be/)([\w-]{11})(?:[^\w-]|\Z)%i' ; }

The above code will create a custom post type for YouTube videos and also add the videos into the singular view of the posts.

2. Create a custom field using ACF

We are creating a custom field that will take a YouTube URL and hook it to the newly created custom type created in the step above.

3. Create a page template

io-youtube-page.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 <?php // Template Name: YouTube Videos add_filter ( 'body_class' , 'io_youtube_videos_page_body_class' ) ; /** * Adds a css class to the body element * * @param array $classes the current body classes * @return array $classes modified classes */ function io_youtube_videos_page_body_class ( $classes ) { $classes [ ] = 'youtube-page' ; return $classes ; } // Force full width content add_filter ( 'genesis_pre_get_option_site_layout' , '__genesis_return_full_width_content' ) ; // Remove the entry title (requires HTML5 theme support) remove_action ( 'genesis_entry_header' , 'genesis_do_post_title' ) ; // Remove post info remove_action ( 'genesis_entry_header' , 'genesis_post_info' , 12 ) ; // Remove entry meta from entry footer remove_action ( 'genesis_entry_footer' , 'genesis_post_meta' ) ; function io_youtube_video_title ( ) { echo '<div class="youtube-page-title"><h1><span class="line-center">' ; echo the_title ( ) ; echo '</span></h1></div>' ; } add_action ( 'genesis_after_header' , 'io_youtube_video_title' ) ; remove_action ( 'genesis_loop' , 'genesis_do_loop' ) ; add_action ( 'genesis_loop' , 'io_youtube_videos_do_loop' ) ; /** * Outputs a custom loop * * @global mixed $paged current page number if paginated * @return void */ function io_youtube_videos_do_loop ( ) { global $paged ; // accepts any wp_query args $args = ( array ( 'post_type' = > 'youtube_videos' , 'order' = > 'DESC' , 'orderby' = > 'date' , 'paged' = > $paged , 'posts_per_page' = > 9 ) ) ; genesis_custom_loop ( $args ) ; } add_action ( 'genesis_entry_content' , 'io_video_custom_field' ) ; /** * Outputs a grid of YouTube videos using custom fields */ function io_video_custom_field ( ) { $link = get_field ( 'youtube_url' ) ; if ( preg_match ( '%(?:youtube(?:-nocookie)?\.com/(?:[\w\-?&!#=,;]+/[\w\-?&!#=/,;]+/|(?:v|e(?:mbed)?)/|[\w\-?&!#=,;]*[?&]v=)|youtu\.be/)([\w-]{11})(?:[^\w-]|\Z)%i' , $link , $match ) ) { $video_id = $match [ 1 ] ; } // Get transient $ioCachedVideos = get_transient ( 'ioCachedVideos_' . $video_id ) ; //Check if transient exist if ( false === $ioCachedVideos ) { //content doesn't exist //start output buffering ob_start ( ) ; $content = file_get_contents ( 'http://youtube.com/get_video_info?video_id=' . $video_id ) ; // Save content $ioCachedVideos = ob_get_contents ( ) ; // empty and stop output buffering ob_end_clean ( ) ; //Save the transient for 1 week set_transient ( 'ioCachedVideos_' . $video_id , $ioCachedVideos , WEEK_IN_SECONDS ) ; } $video_thumbnail = '<img src="http://img.youtube.com/vi/' . $video_id . '/hqdefault.jpg" alt="' . get_the_title ( ) . '"/>' ; $video_link = 'http://www.youtube.com/watch?v=' . $video_id ; printf ( '<div class="video"><a href="https://www.youtube.com/embed/%s" data-featherlight="iframe" data-featherlight-iframe-width="640" data-featherlight-iframe-height="440"> %s </div><div class="video-link">%s</div></a>' , $video_id , $video_thumbnail , get_the_title ( ) ) ; } // Enqueue featherlight add_action ( 'wp_enqueue_scripts' , 'io_enqueue_scripts' ) ; function io_enqueue_scripts ( ) { wp_enqueue_style ( 'featherlight-css' , get_stylesheet_directory_uri ( ) . '/css/featherlight.min.css' ) ; wp_enqueue_script ( 'featherlight' , get_stylesheet_directory_uri ( ) . '/js/featherlight.min.js' , array ( 'jquery' ) , '1.5.0' , true ) ; } genesis ( ) ;

In this step we are creating the full code that will output the actual page along with the videos from YouTube.

4. Upload featherlight.min.js and featherlight.min.css files to your /js and /css respectively.

Ensure that you do have /js and /css subfolders under your child theme and upload those files into those subfolders. Those files will make your videos play in a popup.

5. Add the following code to your style.css file

style.css 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 /* # YouTube Videos Page ---------------------------------------------------------------------------------------------------- */ .youtube-page-title { display : block ; padding-top : 60px ; } .line-center { margin : 0 ; padding : 0 10px ; background : #eee ; display : inline-block ; } .youtube-page-title h1 { text-align : center ; position : relative ; z-index : 2 ; } .youtube-page-title h1:after { content : "" ; position : absolute ; top : 50% ; left : 10% ; right : 10% ; border-top : solid 1px #dadada ; z-index : -1 ; } .youtube-page .content { display : -webkit-box ; /* OLD - iOS 6-, Safari 3.1-6 */ display : -moz-box ; /* OLD - Firefox 19- (doesn't work very well) */ display : -ms-flexbox ; /* TWEENER - IE 10 */ display : -webkit-flex ; /* NEW - Chrome */ display : flex ; /* NEW, Spec - Opera 12.1, Firefox 20+ */ -ms-flex-flow : row wrap ; flex-flow : row wrap ; -webkit-flex-flow : row wrap ; margin-bottom : 60px ; } .youtube-page .entry { padding : 0 ; margin : 0 ; -webkit-flex-basis : 33.333333% ; -ms-flex-preferred-size : 33.333333% ; flex-basis : 33.333333% ; border : 10px solid #eee ; } @media only screen and (max-width: 860px) { .youtube-page .entry { -webkit-flex-basis : 50% ; -ms-flex-preferred-size : 50% ; flex-basis : 50% ; } } @media only screen and (max-width: 550px) { .youtube-page .entry { -webkit-flex-basis : 100% ; -ms-flex-preferred-size : 100% ; flex-basis : 100% ; } } .youtube-page .pagination { width : 100% ; } .youtube-page .video { line-height : 0 } .youtube-page .video:hover { opacity : .8 ; } .video-link { font-size : 18px ; padding : 20px ; } .youtube-page .featherlight:last-of-type { background : rgba ( 0,0,0,.9 ) !important ; } .youtube-page .featherlight .featherlight-close-icon { position : fixed !important ; line-height : 45px !important ; width : 45px !important ; height : 45px !important ; background : #000 !important ; color : #fff !important ; font-size : 25px ; }

Finally start creating your video posts.

P.S. The code can still be optimized by reusing bits and pieces of it in separate functions.