Category: Wordpress


Responsive Vimeo and Youtube embed in WordPress

By kristoffer,

A couple of days ago, i published a post on how to do responsive video embeds in a WordPress loaded with Bootstrap. This post is a continuation of that process. If you read the other post you might remember that getting the aspect ratio of the video is what I didn’t do. So, that is what I’ll do today – and it will lead to the best practice way to properly responsively embed videos in WordPress. The code relies on the CSS from the Bootstrap-component Responsive Embed – if you are not using Bootstrap, simply include that code in your CSS.

Starting with oEmbed

WordPress relies on oEmbed when embedding external video content onto your site.

oEmbed is a format for allowing an embedded representation of a URL on third party sites. The simple API allows a website to display embedded content (such as photos or videos) when a user posts a link to that resource, without having to parse the resource directly.

That’s pretty neat. The oEmbed code is contained within the file class-oembed.php. It handles oEmbed recognition, calls, processing and more. And within it is what we need to make the best responsive video embed for WordPress. On line 501 there is a function data2html that turns oEmbed data into html code. And the best part is that it applies a filter hook at the end,  apply_filters( 'oembed_dataparse', $return, $data, $url ). And it passes the oEmbed data to the filter – and that is what we need.

oEmbed data

So, what does this oEmbed data look like? Lets look at a couple of sample results from YouTube and Vimeo (click the links to see what the oEmbed call receives).

From Vimeo:

{
    "type": "video",
    "version": "1.0",
    "provider_name": "Vimeo",
    "provider_url": "https://vimeo.com/",
    "title": "Michael Jackson - Thriller",
    "author_name": "Michael Jackson",
    "author_url": "http://vimeo.com/user2691078",
    "is_plus": "0",
    "html": "<iframe src=\"\/\/player.vimeo.com\/video\/7806742\" width=\"624\" height=\"448\" frameborder=\"0\" title=\"Michael Jackson - Thriller\" webkitallowfullscreen mozallowfullscreen allowfullscreen><\/iframe>",
    "width": 624,
    "height": 448,
    "duration": 822,
    "description": "",
    "thumbnail_url": "http://i.vimeocdn.com/video/34694433_295x166.jpg",
    "thumbnail_width": 295,
    "thumbnail_height": 212,
    "video_id": 7806742,
    "uri": "/videos/7806742"
}

From YouTube:

{

    "provider_url": "http://www.youtube.com/",
    "title": "Ylvis - The Fox (What Does The Fox Say?) [Official music video HD]",
    "thumbnail_url": "http://i.ytimg.com/vi/jofNR_WkoCE/hqdefault.jpg",
    "thumbnail_width": 480,
    "author_name": "TVNorge",
    "height": 270,
    "version": "1.0",
    "thumbnail_height": 360,
    "width": 480,
    "author_url": "http://www.youtube.com/user/tvnorge",
    "provider_name": "YouTube",
    "html": "<iframe width=\"480\" height=\"270\" src=\"http://www.youtube.com/embed/jofNR_WkoCE?feature=oembed\" frameborder=\"0\" allowfullscreen><\/iframe>",
    "type": "video"
}

As seen, the response is pretty much the same. The important parts are the typewidth and height data. We can then calculate the aspect ratios, and they turn out to be 1.78:1 (or better known as 16:9) for the Vimeo video and 1.39:1 (close to either 7:5 ratio or the ISO paper size ratio sqrt(2):1 ) for the Youtube video.

WordPress filter for responsive embed

This is what we are going to do:

  1. Hook onto the oembed_dataparse filter hook.
  2. Verify that there are oEmbed data
  3. Decide on aspect ratio modifier
  4. Add a data attribute for the aspect ratio
  5. Return the code wrapped in the needed divs (as done in the previous post)

Please remember that we are still using the Bootstrap component Responsive Embed. Here goes the code (it belongs in functions.php. Follow the comments to see what happens.

// Hook onto 'oembed_dataparse' and get 2 parameters
add_filter( 'oembed_dataparse','responsive_wrap_oembed_dataparse',10,2);

function responsive_wrap_oembed_dataparse( $html, $data ) {
 // Verify oembed data (as done in the oEmbed data2html code)
 if ( ! is_object( $data ) || empty( $data->type ) )
 return $html;

 // Verify that it is a video
 if ( !($data->type == 'video') )
 return $html;

 // Calculate aspect ratio
 $ar = $data->width / $data->height;

 // Set the aspect ratio modifier
 $ar_mod = ( abs($ar-(4/3)) < abs($ar-(16/9)) ? 'embed-responsive-4by3' : 'embed-responsive-16by9');

 // Strip width and height from html
 $html = preg_replace( '/(width|height)="\d*"\s/', "", $html );

 // Return code
 return '<div class="embed-responsive '.$ar_mod.'" data-aspectratio="'.number_format($ar, 5, '.').'">'.$html.'</div>';
}

NOTE: Cached embeds

So, turns out that the oEmbed html is cached by WP. This makes sense – we don’t want to ask for and process oEmbed data for every page call. So, for now, you have to update all posts/pages that has oEmbed to cache the new data.

A little jQuery magic

Since I’ve passed the aspect ratio as a data-attribute to the wrapping div, we can use jQuery to set the aspect ratio to match perfectly. Use this little jQuery snippet.

$( function() {
 // Run code for each element
 $('.embed-responsive').each( function (){

 // Get ar
 var ar = $(this).attr('data-aspectratio');

 // Check for existance and set padding-bottom
 if (typeof ar !== typeof undefined && ar !== false ) {
   $(this).css('padding-bottom', (1/ar)*100+'%');
 }

 });
});

Results

Here is the result from Youtube.

And Vimeo

https://vimeo.com/7806742

Pretty neat, huh?

  Category: Code, Wordpress
  Comments: Comments Off on Responsive Vimeo and Youtube embed in WordPress

Responsive YouTube or Vimeo embed with Bootstrap or Roots.io in WordPress

By kristoffer,

I thought I’d share a WordPress filter that I just wrote for this site. I was going to embed a Vimeo video for my up-coming Heading Numbers add-on for Google Docs and needed a nice way to embed it responsively. I am currently running my site on the Roots.io WordPress starter theme. Roots is loaded with Bootstrap front end framework. This blog-post will cover how to responsively embed video and other content into your Bootstrap-powered WordPress. If you just want the code for the responsive embed filter, scroll to the bottom of the post. Now I’ll explain how its done, step by step.

How Bootstrap does responsive video embed

Bootstrap is shipped with a component called Responsive Embed. It is not much code that makes up the component. The following code is from the Bootstrap-sass Repo.

// Embeds responsive
// Credit: Nicolas Gallagher and SUIT CSS.

.embed-responsive {
  position: relative;
  display: block;
  height: 0;
  padding: 0;
  overflow: hidden;

  .embed-responsive-item,
  iframe,
  embed,
  object,
  video {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    height: 100%;
    width: 100%;
    border: 0;
  }

  // Modifier class for 16:9 aspect ratio
  &.embed-responsive-16by9 {
    padding-bottom: 56.25%;
  }

  // Modifier class for 4:3 aspect ratio
  &.embed-responsive-4by3 {
    padding-bottom: 75%;
  }
}

As seen from this code, and the documentation, we need to wrap the embedded item (e.g. iframe in a container that has the class .embed-responsive and add a modifier class based on the aspect ratio. And it turns out that the aspect ratio is just a simple padding to the bottom. So the next thing is to figure out how WordPress handles embeds.

WordPress and embedding video

WordPress is actually pretty awesome when it comes to embedding content. To embed a video, all one has to do is to add the video url in the post/page.

http://www.youtube.com/watch?v=dQw4w9WgXcQ

You can check out the embed documentation to find out which sites are included. The WordPress documentation is however pretty limited as to how one can interact with the embed feature. So – we have to head on over to the WordPress source code. And, there we go, on line 165 of class-wp-embed.php we find the filter hook embed_oembed_html. If you are not familiar with WordPress filters, it think this would be a nice place to start. Anyways, here is the documentation for the filter.

/**
* Filter the cached oEmbed HTML.
*
 * @since 2.9.0
 *
* @see WP_Embed::shortcode()
*
* @param mixed $cache The cached HTML result, stored in post meta.
* @param string $url The attempted embed URL.
* @param array $attr An array of shortcode attributes.
* @param int $post_ID Post ID.
*/
return apply_filters( 'embed_oembed_html', $cache, $url, $attr, $post_ID );

So, what I want to know now is what the values in $attr is. So, I simply set up a test filter that var_dump‘ed the contents of $atts for a Vimeo and a Youtube video. Here’s the sample code.

function var_dump_embed_oembed_html_attr($html, $url, $attr){
 var_dump($attr);
 return $html;
}
add_filter( 'embed_oembed_html','var_dump_embed_oembed_html_attr',10,3); // Need three input parameters

The output is pretty disappointing. First of all, it only contains a width and a height parameter. to begin with, this would be nice to know (for aspect ratio calculations), but it only contains default values from the pretty annoying function wp_embed_defaults. So, it has no use to us. That means we are left with the html and the url.

The WordPress filter

So this is my plan for the filter:

  1. Remove width and height attributes from the html.
  2. Decide what aspect ratio to use
  3. Wrap the embed html in a div with the proper css classes
  4. Return the html

The problem here is number 2 – how to decide on aspect ratio. I’ll leave that for another post (soon, I promise). And then just stick with one aspect ratio. I’ll choose 16by9 for now. And here goes the code:

function bootstrap_wrap_oembed( $html ){
  $html = preg_replace( '/(width|height)="\d*"\s/', "", $html ); // Strip width and height #1
  return'<div class="embed-responsive embed-responsive-16by9">'.$html.'</div>'; // Wrap in div element and return #3 and #4
}
add_filter( 'embed_oembed_html','bootstrap_wrap_oembed',10,1);

And voilá, you have yourself a pretty, responsive, video embed. I’ve borrowed the widht/height remover from Css-tricks.

  Category: Code, Wordpress
  Comments: Comments Off on Responsive YouTube or Vimeo embed with Bootstrap or Roots.io in WordPress