4

I have to display three videos (custom post type) on my first page. When clicking on the link, the post is displayed and video should be in default width.

Can you help to find out how to change width of videos (like youtube)?

This is how I display info now, and this displays all content (including video). I need somehow to show just the_excerpt + small video.

<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
    <li>
        <?php the_title(
            '<h2 class="entry-title">
                <a href="' . get_permalink() . '"
                title="' . the_title_attribute( 'echo=0' ) . '"
                rel="bookmark">',
            '</a></h2>' );
        ?>          
        <div class="entry-content">
            <?php the_content(); ?>
        </div>
    </li>
<?php endwhile; ?>
  • How is the URL or embed code of the video stored? In a custom field or in the post content? – engelen Jun 22 '14 at 10:26
  • Provide demo link. – shahpranaf Jun 23 '14 at 7:01
  • @renathy, please provide answers to the questions in these comments. – engelen Jun 23 '14 at 7:35
7
+50

I'm assuming you are using WordPress' Embeds feature. Generally speaking wp_embed_defaults() gives you the information you need. A look at the source discloses the possibilities you have:

2017    /**
2018     * Create default array of embed parameters.
2019     *
2020     * The width defaults to the content width as specified by the theme. If the
2021     * theme does not specify a content width, then 500px is used.
2022     *
2023     * The default height is 1.5 times the width, or 1000px, whichever is smaller.
2024     *
2025     * The 'embed_defaults' filter can be used to adjust either of these values.
2026     *
2027     * @since 2.9.0
2028     *
2029     * @return array Default embed parameters.
2030     */
2031    function wp_embed_defaults() {
2032            if ( ! empty( $GLOBALS['content_width'] ) )
2033                    $width = (int) $GLOBALS['content_width'];
2034    
2035            if ( empty( $width ) )
2036                    $width = 500;
2037    
2038            $height = min( ceil( $width * 1.5 ), 1000 );
2039    
2040            /**
2041             * Filter the default array of embed dimensions.
2042             *
2043             * @since 2.9.0
2044             *
2045             * @param int $width  Width of the embed in pixels.
2046             * @param int $height Height of the embed in pixels.
2047             */
2048            return apply_filters( 'embed_defaults', compact( 'width', 'height' ) );
2049    }  

As you can see the global variable $content_width - $GLOBALS['content_width'] - is the first approach to determine the default width, if it isn't empty it will be used. The theme feature Content Width can be used by adding the following to your functions.php:

if ( ! isset( $content_width ) ) {
    $content_width = 1200;
}

Which sets up the width you need. If you don't do that the width defaults to 500px, as you can see above. The height defaults either to 1.5 times the width or - if that is less - to 1000px.

The specified width is a maximum, so your embed won't be wider then that, but will scale down in size. You can possibly support this behavior via CSS, with the following parameters:

max-width: 100%;
height: auto;

Which is generally a recommendation, but not necessarily needed.

The above should normally be enough to scale your embedded contents to the size of the container they are in.

However the look into the source shows another way of modifying the width (and height) value. Which would be by hooking into the embed_defaults filter. More general information about this functionality can be found via the WordPress codex page Plugin API, which is a good start to learn more about the topic. A specific example on how to apply this possibility to the embed_defaults filter looks like this:

add_filter( 'embed_defaults', 'wpse150029_change_embed_defaults' );
function wpse150029_change_embed_defaults() {
    return array(
        'width'  => 1200, 
        'height' => 800
    );
}

The code would be part of your functions.php or a plugin. Theoretically you can use conditional tags to differentiate the values, but it is unlikely needed.

This should cover the possibilities of setting up the width of your embedded content. The rest depends on your templates and the CSS of the theme you are using.

As your goal is to show the_excerpt() and the video on your home, front- or overview page you have to create your own function to extract the video URL from the post content and use wp_oembed_get() to fetch the embed HTML. For example like this:

function wpse150029_fetch_youtube_return_embed_html( $content ) {
    // Regex example+explanation can be found here: http://regex101.com/r/vZ6bX6/3
    // note: the first youtube link will be extracted
    $pattern  = '/(?<=(?:\[embed\])|(?:\[embed\]\s)|(?:))';
    $pattern .= '(https?:\/\/)';
    $pattern .= '(:?www\.)?';
    $pattern .= '(:?youtube\.com\/watch|youtu\.be\/)';
    $pattern .= '([\w\?\=\&(amp;)]+)';
    $pattern .= '(?=(?:\[\/embed\])|(?:\s\[\/embed\])|(?:))';
    $pattern .= '/ims';
    preg_match( $pattern, $content, $matches );
    $url = $matches[0];
    $embed_code = wp_oembed_get( $url );
    return $embed_code;
}

The above code goes into your functions.php. Exemplary usage in your template like shown below:

$video_loop = new WP_Query( $args );
if ( $video_loop->have_post() ) :
    while ( $video_loop->have_posts() ) : $video_loop->the_post();
        the_title();         
        the_excerpt();
        echo wpse150029_fetch_youtube_return_embed_html( $post->post_content );
    endwhile;
    wp_reset_postdata();
else :
endif;

For a detailed description on that take a look at the WP_Query documentation.

If you are actually want to have thumbnails for your embedded videos, you should take a look at those Q&A's on here:

  • +1 for such an informative and complete answer. – Pieter Goosen Jun 24 '14 at 7:26
  • 1
    @PieterGoosen Thanks, trying to do my best as always :) – Nicolai Jun 24 '14 at 10:37
  • Regexp $pattern has some error, I have found another pattern. And $post->content is not defined, what should be instead there? – renathy Jun 25 '14 at 17:24
  • As said, should be $post->post_content. I did an additional rework on the regex, its more flexible now. Also a quick test on the setup, as far as I can tell it works fine for me. @renathy – Nicolai Jun 25 '14 at 23:10
  • It should be $video_loop->post instead of $post. – renathy Jun 29 '14 at 9:49
3

I think that a better option will be re-size the video with CSS, supposing you have the container .video_index for the index of videos and .video_single for a single video entry, here is an example.

.video_index iframe{ width: 250px; height: 170px; } .video_single iframe{ width: 500px; height: 360px; }

3

Yeah, the old story with (O)embeds and content width. As soon as there is repsonsiveness, the whole system falls apart. A solution, that might be of use is what we do in our themes:

/**
 * Change the embed code, so we can apply awesome css shit
 * Called by filter "oembed_result"
 *
 * @author Hendrik Luehrsen
 * @since 1.0
 *
 * @param $html string The oembed html to edit
 *
 * @return string The edited html
 */
function change_oembed($html, $url, $args){
    $video_pattern = "#(\W|^)(youtube|vimeo)(\W|$)#";

    if(preg_match($video_pattern, $url)){
        $new_html = '<div class="clearfix"></div><div class="oembed-wrapper"><img src="'.WP_THEME_URL.'/img/16x9_placeholder.png" />'.$html.'</div>';
    } else {
        $new_html = $html;
    }

    return $new_html;
}
add_filter( 'oembed_result', array($this, 'change_oembed'), 999, 3 );

A bit of explanation: The constant WP_THEME_URL is what it claims to be, the URL to the theme. 16x9 placeholder.png is a 16 by 9 pixel transparent PNG. The rest is done in CSS/LESS.

.oembed-wrapper {
    width: 100%;
    height: auto;
    position: relative;
    margin: 30px 0;

    img {
        width: 100%;
        height: auto;
        margin: 0 !important;
    }

    iframe {
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        margin: 0;
        width: 100%;
        height: 100%;
    }
}

So what this does, it always scales the embedded video to 100% of the container by keeping the 16x9 aspect ratio. That way you can drop the oembed where ever you want.

I know there are methods out there to drop the image (with pseudo-selectors on .oembed-wrapper) to retain aspect ratio, but I've never read into those. This works in 99% of the cases.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.