• Hi Team, This is regarding a Youtube video player implementation inside a regular wordpress page. For a site, we have a custom post type created which keeps Youtube video urls in the admin dashboard (pic in below).

    For the YT video player implementation, some custom code is used which includes a php template file and a jquery.

    The php template page is as below :

    <?php
        // get ***** TRAINING VIDEOS
        $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    
        $args = array(
            'post_type' => 'tv',
            'post_status' => 'publish',
            'caller_get_posts' => 1,
            'posts_per_page'    => 6,
            'paged' => $paged,
            'orderby' => array( 'wpcf-feature-video' => 'DESC', 'date' => 'DESC' ),
            'meta_key'=> 'wpcf-feature-video'
        );
        $my_query = new WP_Query($args); 
    ?>
    <?php get_header(); ?>
        <div class="breadcrumb-area">
            <div class="row">
                <div class="small-12 column">
                    <p>How Can We Help You?</p>
                </div>
            </div>
        </div>
    
        <div class="row support-main-content">
            <div class="small-12 medium-12 large-9 column">
    			<div id="top"></div>
                <!-- tabs -->
                <div class="custom-tabs clearfix">
                    <div class="tab left"><a href="/kb">Support Center</a></div>
                    <div class="tab tab-active right">***** Training Videos</div>
                </div>
    
                <!-- tabs content -->
                <div class="custom-tab-content">
    
                    <?php if ( $my_query->have_posts() ) :
    
                            $my_query->the_post();
                            $first = true;
    
                            $videoUrl   =  get_field('wpcf-video-url');
                            $videoDesc  =  get_field('wpcf-video-description');
                            $videoCode = 'Q8TXgCzxEnw'; // default code
    
                            if(!empty($videoUrl)):
                                //preg_match("#([\/|\?|&]vi?[\/|=]|youtu\.be\/|embed\/)(\w+)#", $videoUrl, $matches);
    							preg_match("#(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\-nocookie\.com\/embed\/|youtube\.com\/(?:embed\/|v\/|e\/|\?v=|shared\?ci=|watch\?v=|watch\?.+&v=))([-_A-Za-z0-9]{10}[AEIMQUYcgkosw048])\S*#s", $videoUrl, $matches);
                                $videoCode  = $matches[1];
                            endif;
    
                            $videoEmbed = "https://www.youtube.com/embed/{$videoCode}?rel=0";
                            $videoImage = "https://img.youtube.com/vi/{$videoCode}/0.jpg";
    
                            $pages_count = ceil($wp_query->found_posts / 6);
    
                            $total_results = $pages_count >= 10 ? $pages_count : 0 . $pages_count ;
    
                            if($first): $first = false; ?>
                                <div id="featured-video" class="row support-featured-training-video">
    
                                    <div class="small-12 medium-8 column">
                                        <iframe width="560" height="315" src="<?php echo $videoEmbed; ?>" frameborder="0" allowfullscreen></iframe>
                                    </div>
    
                                    <div class="small-12 medium-4 column">
                                        <h3 class="video-name"><a href="#"><?php the_title(); ?></a></h3>
                                        <p class="video-description"><?php echo $videoDesc; ?></p>
                                        <ul class="support-social-links">
                                            <li>
                                                <a href="#" class="share-facebook" data-title="<?php the_title(); ?>" data-url="<?php echo 'https://' .$_SERVER[HTTP_HOST] . $_SERVER[REQUEST_URI] ?>%23/<?php the_ID(); ?>"><span class="icon-social-network"></span> <span class="visually-hidden">Facebook</span></a>
                                            </li>
                                            <li>
                                                <a href="#" class="share-twitter" data-title="<?php the_title(); ?>" data-url="<?php echo 'https://' .$_SERVER[HTTP_HOST] . $_SERVER[REQUEST_URI] ?>%23/<?php the_ID(); ?>"><span class="icon-twitter"></span> <span class="visually-hidden">Twitter</span></a>
                                            </li>
                                            <li>
                                                <a href="#" class="share-linkedin" data-title="<?php the_title(); ?>" data-url="<?php echo 'https://' .$_SERVER[HTTP_HOST] . $_SERVER[REQUEST_URI] ?>%23/<?php the_ID(); ?>"><span class="icon-linkedin"></span> <span class="visually-hidden">LinkedIn</span></a>
                                            </li>
                                        </ul>
                                    </div>
    
                                </div>
    
                            <?php endif; ?>
    
                                <div class="row">
    
                                    <div class="small-12 column support-related-training-videos">
    
                                        <ul id="video-list" class="small-block-grid-2 medium-block-grid-3">
    
                                            <!-- show first video on list -->
                                            <?php get_template_part( 'content', 'tv'); ?>
    
                                            <?php while ( $my_query->have_posts() ) : $my_query->the_post();?>
                                                <?php get_template_part( 'content', 'tv'); ?>
                                            <?php endwhile; ?>
    
                                        </ul>
    
                                        <ul class="pagination videos-pagination">
                                            <li>
                                                <a href="#" class="page-icon-first unavailable">
                                                    <span class="visually-hidden">First</span>
                                                </a>
                                            </li>
                                            <li>
                                                <a href="#" class="page-icon-prev unavailable">
                                                    <span class="visually-hidden">Previous</span>
                                                </a>
                                            </li>
                                            <li class="page-number">01</li>
                                            <li class="text">of</li>
                                            <li class="page-total"><?php echo $total_results; ?></li>
                                            <li>
                                                <a href="#" class="page-icon-next">
                                                    <span class="visually-hidden">Next</span>
                                                </a>
                                            </li>
                                            <li>
                                                <a href="#" class="page-icon-last">
                                                    <span class="visually-hidden">Last</span>
                                                </a>
                                            </li>
                                        </ul>
    
                                    </div><!-- end support related training videos -->
                                </div><!-- end row -->
    
                    <?php endif; ?>
    
                    <script type="text/x-handlebars-template" id="large-video-template">
    
                        <div class="small-12 medium-8 column">
                            {{#if video}}
                            <iframe width="560" height="315" src="https://www.youtube.com/embed/{{ video }}" frameborder="0" allowfullscreen></iframe>
                            {{else}}
                            <iframe width="560" height="315" src="https://www.youtube.com/embed/{{ getVideoCode custom_fields.wpcf-video-url }}" frameborder="0" allowfullscreen></iframe>
                            {{/if}}
                        </div>
    
                        <div class="small-12 medium-4 column">
                            <h3 class="video-name"><a href="#">{{ title }}</a></h3>
                            <p class="video-description">{{ content }}</p>
                            <ul class="support-social-links">
                                <li>
                                    <a  data-title="{{ title }}" data-url="<?php echo 'https://' .$_SERVER[HTTP_HOST] . $_SERVER[REQUEST_URI] ?>%23/{{ id }}"><span class="icon-social-network"></span> <span class="visually-hidden">Facebook</span></a>
                                </li>
                                <li>
                                    <a {{ title }}" data-url="<?php echo 'https://' .$_SERVER[HTTP_HOST] . $_SERVER[REQUEST_URI] ?>%23/{{ id }}"><span class="icon-twitter"></span><span class="visually-hidden">Twitter</span></a>
                                </li>
                                <li>
                                    <a  class="share-linkedin"data-title="{{ title }}" data-url="<?php echo 'https://' .$_SERVER[HTTP_HOST] . $_SERVER[REQUEST_URI] ?>%23/{{ id }}"><span class="icon-linkedin"></span> <span class="visually-hidden">LinkedIn</span></a>
                                </li>
                            </ul>
                        </div>
    
                    </script>
    
                    <script type="text/x-handlebars-template" id="small-video-template">
                        {{#each this}}
                        <li data-id="{{ id }}" data-title="{{ title }}" data-description="{{ custom_fields.wpcf-video-description }}" data-video="{{ getVideoCode custom_fields.wpcf-video-url }}">
    						<a href="#top">
    							<figure class="video-player">
    							{{#if custom_fields.wpcf-video-url}}
    								<img src="https://img.youtube.com/vi/{{getVideoCode custom_fields.wpcf-video-url}}/0.jpg"; alt="{{ title }}">
    
    							{{else}}
    								<img src="<?php bloginfo( 'template_url' ); ?>/img/video-default-thumb.png" alt="{{ title }}">
    							{{/if}}
    							</figure>
    							<h4 class="video-name">{{ title }}</h4>
    						</a>
                        </li>
                        {{/each}}
                    </script>
    
                </div><!-- end custom tab content -->
    
            </div>
    
            <div class="small-12 medium-12 large-3 column">
                <?php get_template_part( 'partials/content', 'sidebar' ); ?>
    <?php dynamic_sidebar( 'sidebar-magazine-summary' ); ?>
            </div>
    
        </div>
    
    <?php wp_reset_query();  // Restore global post data stomped by the_post(). ?>
    
    <?php get_footer(); ?>

    A jquery function is also being used as an asset js file:

    (function ($, window, undefined) {
    
        $(document).foundation();
    
    
        $('#mobile-menu, .exit-off-canvas').on('click', function(e) {
            e.preventDefault();
            $('.off-canvas-wrap').foundation('offcanvas', 'toggle', 'move-right');
        });
    
        // add dropdown alignment for ipad 1 / 2 / mini
        if (jQuery(window).width() <= 1024) {
            $('.js-alignment').attr('data-options', 'align:left');
        }
    
        // reinitialize foundation to update the dropdown alignment
        $(document).foundation('dropdown', 'reflow');
    
        // external links open in new tab
        $('a[rel="external"]').click( function() {
            window.open( $(this).attr('href') );
            return false;
        });
    
        $('.home-slider').slick({
            slide: '.home-slide-item',
            infinite: true,
    		autoplay: true,
    		slidesToShow: 1,
      		slidesToScroll: 1,
    		autoplaySpeed: 4000,
    		fade: true,
            dots: true,
            arrows: true,
            responsive: [
                {
                    breakpoint: 1140,
                    settings : {
                        arrows: false
                    }
                },
                {
                    breakpoint: 481,
                    settings : {
                        arrows: false,
                        dots: false,
                        autoplay: true
                    }
                },
            ]
        });
    
        $('.slider-products-category').slick({
            dots: false,
            arrows: true,
            responsive: [
                {
                    breakpoint: 479,
                    settings: {
                        slidesToShow: 1,
                        slidesToScroll: 1,
                        arrows: false,
                        autoplay: true,
                        infinite: false
                    }
                }
            ]
        });
    
        $('.slider-segment').slick({
            arrows: true,
            dots: false,
            infinite: false,
            slidesToShow: 5,
            slidesToScroll: 1,
            //variableWidth: true,
            responsive: [
                {
                    breakpoint: 1190,
                    settings: {
                        slidesToShow: 4,
                        slidesToScroll: 1,
                    }
                },
                {
                    breakpoint: 970,
                    settings: {
                        slidesToShow: 3,
                        slidesToScroll: 1,
                    }
                },
                {
                    breakpoint: 750,
                    settings: {
                        slidesToShow: 2,
                        slidesToScroll: 1,
                    }
                }
            ]
        });
    
        window.***** = window.***** || {};
    
        *****.videos = {
    
            init: function() {
                this.page        = 1;
                this.$container  = $('#video-list');
                this.$pagination = $('.videos-pagination'),
                this.total       = Number( this.$pagination.find('.page-total').text() );
    
                this.helpers();
                this.router();
                this.events();
            },
    
            events: function() {
                var _this = this;
    
                this.$pagination.on('click', 'a', function(e) {
                    e.preventDefault();
    
                    var $this = $(this),
                        dir   = $this[0].classList.toString().split(" ")[0].split("page-icon-")[1]
    
                    if ( $this.hasClass('unavailable') || $this.hasClass('loading')) { return false; }
    
                    _this.page = (dir === 'prev') ? _this.page -= 1 : _this.page += 1;
    
                    if ( dir === 'first' ) { _this.page = 1; }
                    else if ( dir === 'last' ) { _this.page = _this.total; }
    
                    _this.get();
    
                });
    
                this.$container.on('click', 'li', function(e) {
                    e.stopPropagation();
    
                    var $this = $(this),
                        data = {
                        id: $this.data('id'),
                        title: $this.data('title'),
                        content: $this.data('description'),
                        video: $this.data('video'),
                    };
    
                    _this.render(data, $('#large-video-template'), $('#featured-video') );
    
                    window.location.hash = '/' + data.id;
    
                });
            },
    
            helpers: function() {
    
                Handlebars.registerHelper('getVideoCode', function(url) {
    
                    if ( !url ) { return false; }
    
                    var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
                    var match = url.match(regExp);
    
    
                    if ( match && match[7].length === 11 ){
    
                        return match[7];
    
                    } else {
    
                        return false;
    
                    }
                });
    
            },
    
            get: function() {
                var _this = this;
    
                $.ajax({
    
                    url: '/?json=get_posts&post_type=tv&count=6&page=' + this.page,
    
                    beforeSend: function() {
    
                        _this.$pagination.find('a').addClass('loading');
    
                    }
    
                }).done(function(data) {
    
                    _this.render(data.posts, $('#small-video-template'), _this.$container);
    
                    _this.$pagination.find('a').removeClass('loading');
    
                    _this.updateNav();
    
                }).fail(function() {
    
                    console.log("error");
    
                });
    
            },
    
            render: function(data, $source, $container) {
                var source   = $source.html(),
                    template = Handlebars.compile(source);
    
                $container.html( template(data) );
    
            },
    
            updateNav: function() {
                var page = this.page < 10 ? '0' + this.page : this.page;
    
                this.$pagination.find('.page-number').text( page );
                this.$pagination.find('.unavailable').removeClass('unavailable');
    
                if ( this.page === 1 ) {
    
                    this.$pagination.find('.page-icon-first, .page-icon-prev').addClass('unavailable');
    
                } else if ( this.page === this.total ) {
    
                    this.$pagination.find('.page-icon-last, .page-icon-next').addClass('unavailable');
    
                }
    
            },
    
            router: function() {
    
                var id    = window.location.hash.split('#/')[1],
                    _this = this;
    
                if ( !id ) { return false; }
    
                $.ajax({
                    url: '?json=get_post&post_type=tv&post_id=' + id
                })
                .done(function(data) {
    
                    data.post.content = data.post.custom_fields["wpcf-video-description"];
    
                    _this.render(data.post, $('#large-video-template'), $('#featured-video') );
    
                })
                .fail(function() {
                    console.log("error");
                })
                .always(function() {
                    console.log("complete");
                });
            }
    
        };
    
        *****.storeLocator = {
            init: function() {
                this.$widget   = $('.widget-distributor-locator');
                this.$input    = this.$widget.find('input[type="text"]');
                this.$btn      = this.$widget.find('.button');
                this.$template = $('#store-locator-template').html();
    
                this.events();
    
            },
    
            events: function() {
                var _this = this;
    
                this.$btn.on('click', function(e) {
                    e.preventDefault();
                    var text = _this.$input.val();
    
                    if ( text ) {
    
                        _this.find(text);
                        _this.reset();
    
                        $(this).off('click');
    
                    }
    
                });
    
            },
    
            reset: function() {
                this.$widget.find('.locator-info').remove();
            },
    
            find: function(val) {
                var _this = this;
    
                $.ajax({
                        url: '/distributor/?zip=' + val,
                    })
                    .done(function(d) {
                        var data = JSON.parse(d);
    
                        if ( data[0].status && data[0].status === 'error' ) {
    
                            _this.error();
    
                        } else {
    
                            _this.render(data);
    
                        }
    
                    })
                    .fail(function() {
                        console.log("error");
                    })
                    .always(function() {
                        _this.events();
                    });
    
            },
    
            render: function(data) {
                var template = Handlebars.compile(this.$template);
    
                this.$widget.find('.widget-content').append( template(data) );
    
            },
    
            error: function() {
                $('.locator-error-template').clone().appendTo( this.$widget.find('.widget-content') ).show();
            }
        }
    
        *****.videos.init();
        *****.storeLocator.init();
    
        // replace input checkbox in product filter
        function setupLabel() {
            if ($('.label_check input').length) {
                $('.label_check').each(function(){
                    $(this).removeClass('c_on');
                });
                $('.label_check input:checked').each(function(){
                    $(this).parent('label').addClass('c_on');
                });
            };
        }
    
        $('body').addClass('has-js');
    
        $('.label_check').on('click', function(){
            setupLabel();
        });
    
        setupLabel();
    
        $('.open-search').on('click', function(e){
            console.log(e)
            $('.menu-search').toggleClass('hide');
            $('.fake-overlay').toggleClass('hide');
        });
    
        $('.fake-overlay').on('click', function(){
            $(this).toggleClass('hide');
            $('.menu-search').toggleClass('hide');
        });
    
        $(document).on('click', '.share-facebook', function(e) {
            e.preventDefault();
            var $this = $(this),
                title = $this.data('title'),
                url   = $this.data('url');
    
            window.open('https://www.facebook.com/sharer/sharer.php?u=' + url +'&t=' + title, 'facebook_share', 'height=320, width=640, toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, directories=no, status=no');
        });
    
        $(document).on('click','.share-twitter', function(e) {
            e.preventDefault();
            var $this = $(this),
                title = $this.data('title'),
                url   = $this.data('url');
    
            window.open('https://twitter.com/intent/tweet?text=' + title + ' ' + url, 'twitter_share', 'height=320, width=640, toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, directories=no, status=no');
        });
    
        $(document).on('click','.share-linkedin', function(e) {
            e.preventDefault();
            var $this = $(this),
                title = $this.data('title'),
                url   = $this.data('url');
    
            window.open('https://www.linkedin.com/shareArticle?mini=true&url=' + url + '&title=' + title +'&summary=%20&source=' + url, 'linkedin_share', 'height=320, width=640, toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, directories=no, status=no');
        });
    
        $('.js-backto').on('click', function(e) {
            e.preventDefault();
    
            window.history.back()
    
        });
    
        $(".accordion-navigation label input:checkbox").click(function () {
            $(this).parent().next('.content').find('input:checkbox').prop('checked', this.checked);
        });
    
        if ($(window).width() <= 800) {
            $(function(){
                $(".js-category-name").each(function(i){
                    len=$(this).text().length;
                    if(len>22) {
                        $(this).text($(this).text().substr(0,20)+'...');
                    }
                });
            });
        }
    
    })(jQuery, window);
    

    ISSUE ::

    This setup is configured from long back and it was working as expected. But it is only working when the Youtube video code is normal 11 characters (e:g; https://www.youtube.com/watch?v=aerw2SPwizo and https://www.youtube.com/watch?v=KdBiKL66mL4). But the YT videos are not getting played if there is a hyphen / Dash (-) in the Youtube video url (e:g; https://www.youtube.com/watch?v=Hyf3kWR-jg0). If a video id has hyphen in it, then our code setup is not generating any thumbnail nor, its playing the video. The broken gallery looks as below.

    Any help is deeply appreciated.

    Thanks in Advance

    The page I need help with: [log in to see the link]

Viewing 4 replies - 1 through 4 (of 4 total)
  • The reason is definitely the function “getVideoCode”. Because in the attribute data-video, which you fill with it, the code is only up to the character before the “-“. Maybe this has something to do with the “Handlebars” script you are using: https://handlebarsjs.com/guide/

    Also have a look at the generated code. There is a lot more wrong – a bunch of meta-elements that don’t make sense there.

    Thread Starter reactivehappy

    (@reactivehappy)

    Thanks @threadi for having a look into this. Indeed I had also doubted the same getVideoCode function in the app.js. But when I tested that functionality I am getting expected video id.

    Just open this url : https://www.w3schools.com/php/phptryit.asp?filename=tryphp_intro And replace the whole code snippet with below isolated GetVideoCode function in the code window.

    <!DOCTYPE html>
    <html>
    <head>
    <script>
    function extractVideoID(url) {
      var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
      var match = url.match(regExp);
      if (match && match[7].length == 11) {
        return match[7];
      } else {
        alert('Could not extract video ID.');
      }
    }
    </script>
    </head>
    <body>
    <script>
    var x = extractVideoID('https://www.youtube.com/watch?v=Hyf3kWR-jg0&t=5s');
    alert(x);
    </script>
    
    </body>
    </html>
    

    This regExp filters expected result i:e; Hyf3kWR-jg0 from the Youtube url ‘https://www.youtube.com/watch?v=Hyf3kWR-jg0&t=5s‘ .

    That’s why I am still struggling to get to the bottom of it on what exatly causing this issue?

    Then it may also have to do with the way the function is included via Handlebars.registerHelper. I do not know this library further, it also has nothing to do with wordpress. You would have to debug this more closely to see the cause or turn to a forum where this library is used by more people.

    Thread Starter reactivehappy

    (@reactivehappy)

    yes, that might be an issue. Also strangely, in the same page, if we are traversing to the next pagination by clicking on “NEXT” button, then there is no issue loading the thumbnails or, playing video. Same is happening, if we come back again to the first (1) pagination. All the videos are loading fine.

    Thus I highly doubt, while loading for the first time, while setting up the Gallery, the video codes are getting stripped somewhere.

Viewing 4 replies - 1 through 4 (of 4 total)
  • The topic ‘Error in Embedding Youtube video with custom coding for wp page’ is closed to new replies.