Easy Embeds For WordPress 2.9

This post needs updating — some things have changed since it was initially written. The Codex article is more up to date.

See the bottom of this post for the list of changes made to this post since it was initially published. Handy if you’ve read it previously and want to see what I’ve since changed.

I’ve been working on some code for WordPress 2.9 for a while now that is designed to make embedding remote content (namely videos) into your blog a lot easier. Today the code went into the WordPress core.

If you’re into testing alpha code and would like to try it out, just checkout a copy of the WordPress trunk via SVN. You can also just wait until later this month for when the more stable WordPress 2.9 beta is planned to be released.

Using The Feature

Once you’re running the code, you’ll first want to visit Settings -> Media and check out the new “Embeds” section. The default options will work perfectly fine, but you can tweak them if you wish.

Embed Settings

To embed something, such as a video, you have two options:

  1. Paste a plain-text (i.e. not hyperlinked with a <a> tag) URL on it’s own line (that’s important) somewhere within your post. Obviously this will not work for all URLs, but more on that in a moment.
  2. Wrap your URL in the new [embed] shortcode. (there’s a UI for this — click the “Add Video” icon and then “From URL”)

In order for the URL to actually turn into an embed, one of three conditions needs to be true:

  1. An internal handler has been supplied by the WordPress core or a plugin.
  2. The site hosting the external content supports the oEmbed API and the URL to the site’s provider service is know by WordPress, either via the predefined list or added by a plugin.
  3. There is an oEmbed discovery <link> tag in the <head> of the entered URL which contains the URL to the site’s oEmbed provider. This option is only available to authors with the unfiltered_html capability.

If all goes well, then it’ll embed like this:

Note that no plugins were used in the above embed and the HTML was pulled directly off of Vimeo’s servers. All I did was paste this on to it’s own line: http://www.vimeo.com/240975 WordPress connected to the URL, found the discovery tag in the <head>, and used it to get the HTML back from Vimeo’s servers. It’s then cached to the post meta to avoid slow page loads (editing a post clears the cache).

Another example is Flickr. Just paste the URL to the image’s page (the page where people can leave comments, etc.) into your post. For example, here’s a picture by Donncha: http://www.flickr.com/photos/donncha/4008546362/

waterfall walk 26.jpg

Default Supported Sites

The following sites are supported out of the box for all users — you can easily add more via plugins (see below) and admins can use other sites that use the oEmbed discovery tag.

  • YouTube (via oEmbed)
  • Blip.tv (via oEmbed)
  • Flickr images and videos (via oEmbed)
  • Hulu (via oEmbed)
  • Viddler (via oEmbed)
  • Qik.com (via oEmbed) — never heard of this site, but it was listed on oEmbed’s website, so…
  • Revision3 (via oEmbed)
  • Google Video (via an internal handler)
  • PollDaddy (via an internal handler)
  • DailyMotion (via an internal handler)

Using Plugins To Add Support For More Media Types/Sites

This feature can be used to embed literally any type of content from any website that supports embedding it’s content. If the site supports oEmbed and has a discovery tag to their oEmbed provider URL in the <head> of their pages, then you’re good to go — you can embed their content without doing anything extra.

However if they don’t have an oEmbed discovery tag or don’t support oEmbed period, then you’ll need to use/write a plugin to tell WordPress about the site. You may also want to do this for sites that support oEmbed and has a discovery tag, but that WordPress doesn’t specifically know about. The reason for this is that oEmbed discovery is disabled for non-administrators for security purposes (otherwise those users would be able to import arbitrary HTML via the oEmbed protocol).

Registering new URL formats with WordPress is relatively easy and there are two methods for doing so:

Adding Support For A Site That Supports oEmbed

If the site is cool enough to support oEmbed, then it’s dead simple. All you have to do is tell WordPress the URL format to match and what the URL to the site’s oEmbed provider is:

wp_oembed_add_provider( 'http://site.com/watchvideo/*', 'http://site.com/oembedprovider' );

Note the underscore after “add”. This was not there when this post was originally written — the function name was changed before WordPress 2.9’s release.

The first parameter is the format of the content URLs with asterisks used as wildcards. For YouTube for example, it could be http://*.youtube.com/watch*. The second parameter is the base URL of oEmbed provider. You can use {format} if the format (JSON or XML) is explicitly a part of the URL rather than just a query variable (which will be added automatically). This is however somewhat rare and most sites use the same provider URL for both JSON and XML requests.

Adding Support For A Site That Does NOT Support oEmbed

This is more complicated, but still rather easy. You’ll need to register the URL format that you want to match and then define the callback function that will be returning the content (usually some embed HTML).

For example, here’s the handler for Google Video that’s built into WordPress:

/**
 * The Google Video embed handler callback. Google Video does not support oEmbed.
 *
 * @see WP_Embed::register_handler()
 * @see WP_Embed::shortcode()
 *
 * @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}.
 * @param array $attr Embed attributes.
 * @param string $url The original URL that was matched by the regex.
 * @param array $rawattr The original unmodified attributes.
 * @return string The embed HTML.
 */
function wp_embed_handler_googlevideo( $matches, $attr, $url, $rawattr ) {
	// If the user supplied a fixed width AND height, use it
	if ( !empty($rawattr['width']) &amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp; !empty($rawattr['height']) ) {
		$width  = (int) $rawattr['width'];
		$height = (int) $rawattr['height'];
	} else {
		list( $width, $height ) = wp_expand_dimensions( 425, 344, $attr['width'], $attr['height'] );
	}

	return apply_filters( 'embed_googlevideo', '&amp;amp;amp;amp;amp;amp;lt;embed type=&amp;amp;amp;amp;amp;amp;quot;application/x-shockwave-flash&amp;amp;amp;amp;amp;amp;quot; src=&amp;amp;amp;amp;amp;amp;quot;http://video.google.com/googleplayer.swf?docid=' . esc_attr($matches[2]) . '&amp;amp;amp;amp;amp;amp;amp;amp;hl=en&amp;amp;amp;amp;amp;amp;amp;amp;fs=true&amp;amp;amp;amp;amp;amp;quot; style=&amp;amp;amp;amp;amp;amp;quot;width:' . esc_attr($width) . 'px;height:' . esc_attr($height) . 'px&amp;amp;amp;amp;amp;amp;quot; allowFullScreen=&amp;amp;amp;amp;amp;amp;quot;true&amp;amp;amp;amp;amp;amp;quot; allowScriptAccess=&amp;amp;amp;amp;amp;amp;quot;always&amp;amp;amp;amp;amp;amp;quot;&amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;lt;/embed&amp;amp;amp;amp;amp;amp;gt;', $matches, $attr, $url, $rawattr );
}
wp_embed_register_handler( 'googlevideo', '#http://video\.google\.([A-Za-z.]{2,5})/videoplay\?docid=([\d-]+)(.*?)#i', 'wp_embed_handler_googlevideo' );

The last line is the important one as registers the new handler. Here’s the parameters:

  1. The handler ID. This is just used to identify it internally and if you need to unregister it later. It needs to unique, but other than that, it doesn’t matter what it is.
  2. The regex that should be used to check a URL to see if it should be handled by this handler.
  3. The callback function name.

The callback function will receive 4 parameters (as described in the phpdocs in the above example). Which your function uses is entirely up to you. The function should return the resulting content or HTML, or false to abort handling the URL and to let other handlers potentially handle it.

wp_expand_dimensions() is a new function that will return the largest dimensions possible given an example width and height (to determine the ratio) and the maximum overall dimensions. For example, what’s the biggest we can make a 400×300 pixel video without going over 600×600 pixels?

list( $width, $height ) = wp_expand_dimensions( 400, 300, 600, 600 );

echo $width; // 600
echo $height; // 450

If you have any questions or feedback about this new feature, feel free to leave them via the comments form below.

Update 5:39 PST: Added list of default sites handled by WordPress that all users can use.

153 thoughts on “Easy Embeds For WordPress 2.9

  1. I had no idea wordpress 2.9 was available yet. Thanks for all the tips and thanks to all fo teh commenters as well…..

  2. Pingback: WordPress 2.9 ?????? | detlog.org

  3. oohEmbed maintainer here. I noticed a couple of comments that oohEmbed support for Amazon & xkcd is broken. I think it was a temporary thing since both sites are working right now.

    I really appreciate the work you are doing in getting oEmbed support into WP! If you find any issues in future with oohEmbed, please file a bug report: http://code.google.com/p/oohembed/issues/list

  4. Pingback: OohEmbed Plugin Test – Brent Logan

  5. Pingback: Funktioner i kommande 2.9 | WP-Support Sverige

  6. Pingback: Mobypicture announces oEmbed support – Mathys van Abbe

  7. Pingback: WordPress 2.9 a chystané novinky (2): Jednoduché vkládání médií z externích služeb (nap?. YouTube) do p?ísp?vk? prost?ednictvím oEmbed | Separatista


  8. Viper007Bond:

    Andy Beard on October 19th, 2009 at 5:44 AM wrote:

    Is there likely to be a player included for flash videos from your own doamin other than JWPlayer. JWPlayer is great, but isn’t free for any kind of commercial use, including blogs that just have a little advertising.

    Embedding of FLV will not be supported out of the box, nor would it be possible for JWPlayer to be bundled with WordPress due to it’s license.

    How hard would it be for a site owner to add this ability? Our system hosts an MU site for our teachers and 99% of the content is ours. Our upgrade to 2.8 has been a little painful due to our old video plugin no longer working properly so we’ve switched to your plugin but we have a lot of links that need updating. 😉

  9. My plugin will continue working into 2.9 (it works side by side with this new code).

    However to support using the new API, you’d want to use code based on the big block above under “Adding Support For A Site That Does NOT Support oEmbed”. Just use regex that matches *.flv or whatever.

  10. Pingback: WordCast 75: WordPress 2.9 and Beyond | WordCast - The #1 WordPress Podcast, with WordPress News, WordPress Tips, WordPress Plugins, WordPress Themes, Blogging News, Blogging Tips, and more! | Bitwire Media

  11. Gonna sound like a strange question, but the code on my site dictates that our OEmbed discovery links are not in the head of the document, as is recommended in the spec. I know most places don’t seem to limit their grep of the page to the head, but wanted to know if you knew off hand how you guys were doing it, as I only added it in to work with WordPress.
    Thanks!

    • Yes, for performance reasons WordPress only looks before the </head> tag (the less HTML to search the better). If your <link> tag is outside the head, then WordPress won’t find it, not to mention I think you’ll break your site’s validation.

  12. Pingback: WordPress 2.9 på norsk « neppe.no

    • Ooo, I didn’t know they supported that!

      No though, however my Viper’s Video Quicktags plugin will be doing exactly that, as well as things that aren’t supported. For example YouTube’s oEmbed provider doesn’t allow you to control the colors as far as I’m aware, but my plugin will regex in the parameters.

  13. Great feature but I wonder why the white list of video hosting sites has not been made editable with a configuration panel (without touch the code). For me looks a little bit of wall-gardening the users specially now that WP2.9 rolled out. My2c.

  14. Pingback: WordPress 2.9: The Bloggers Gift for the Holidays | WordCast - The #1 WordPress Podcast, with WordPress News, WordPress Tips, WordPress Plugins, WordPress Themes, Blogging News, Blogging Tips, and more! | Bitwire Media

  15. I noticed on the trac, you briefly mentioned that YouTube isn’t using the Oembed service. Are they now? I am looking at modifying the output to make XHTML Strict. Does class-oembed.php do the main job or are there any other files I should know of?

    • Yes, YouTube is oEmbed enabled, complete with discovery tags. They rock.

      If you want to modify the returned HTML, the filter to use is oembed_dataparse. Look at the strip_scribd_newlines() function inside of class-oembed.php for an idea of how to go about doing it (look at $url to see if it’s YouTube, then modify $html and return it).

      Note that this will modify the result from YouTube’s servers and before it goes into the cache (stored in the post meta). This means it won’t affect existing embeds unless you edit and save the post (this flushes that post’s cache). The embed_oembed_html filter could be used instead (runs between the cache and insertion into the post), but that’d mean more regex on every page load. Better to do it on it’s way into the cache.

  16. Could you please tell me how to change the size of the image embedded from Flickr? I tried adding maxwidth and maxheight but no joy.

    S.K

  17. Awesome work!

    How can one pull video thumbnails via oEmbed? Looked trough the code but couldn’t figure it out 🙂

    I’d use Vimeo for most of ’em and maybe youtube a few times.

  18. Pingback: Reflections » WordPress 2.9 Enhancements Every Developer Must Know

  19. This oEmbed is a huge and fantastic update. I am using it in my main blog.

    But I have a weird Bug with some YouTube and Dailymotion videos.

    My settings in “Media” are set to: Width: 624 Height: 0

    Every video should be resized to width= 624px, this sometimes happens but other times it resizes to width=”384″ (maybe a default from youtube).

    For Example:

    This video (with URL http://www.youtube.com/watch?v=CeTa7YYkMcE ) doesn’t resize to my personalized width… but to 384, here is the post:

    http://www.aeromental.net/2009/12/25/video-of-the-pope-benedict-xvi-being-attacked-by-a-woman-during-christmas-eve-celebration/

    But in other posts the width attribute works perfect:

    http://www.aeromental.net/2009/12/29/walking-with-dinosaurs-the-live-experience-triceratops-versus-tyrannosaurus/

    How can I fix this?

  20. Hi

    I embedded a Dailymotion video by this method. But additional metadata gets added below the video like this:

    “Bianca Castafiore : Animation. Uploaded by quiestce88. — Independent web videos”.

    A reader can always get this kind of info from the video page on clicking the “menu” icon. I want to avoid display of such details underneath the video.

    Could you please guide me how to do this.

    Thanks.

    S.K

  21. Hi

    This is the extra line that is added by Dailymotion beyond the “embed” and “object” enclosure (just before the closing of the “div”) as found in the oEmbed response:

    <b><a href="http:\/\/www.dailymotion.com\/video\/x7q2g1_bianca-castafiore-animation_creation" rel="nofollow">Bianca Castafiore : Animation<i>Uploaded by <a href="http:\/\/www.dailymotion.com\/quiestce88" rel="nofollow">quiestce88. - <a href="http:\/\/www.dailymotion.com\/in\/channel\/creation" rel="nofollow">Discover more animation and arts videos.</code>

    Could you please tell me how to remove rendering of such extra HTML line.

    Thanks

    S.K

    • Yes, I’m aware of the line. It is being added by DailyMotion, not by WordPress. If you wish to remove it, you’ll need to use or write a little plugin that filters the HTML that DailyMotion provides.

  22. Hi, I updated one of my blogs to WP 2.9 but can´t see this feature anywhere. In Settings > Media I don’t have the option for embed like you show it in the first screen shot. I updated the system twice (1st time automatically and 2nd time manually) and no changes.
    Any idea what could be the problem? Thanks for your help!

  23. I was talking about a different blog, it’s not online yet. and I checked in the sourcecode – there it says wp 2.9.

    • Hi,

      same problem with me: Updates to WP 2.9, the Feature in Settings -> Media is not shown. Any ideas ?

      regards

      Frank

  24. I post the Youtube width bug again, but showing the responses given from youtube:

    Lets consider maxwidth: 620 and maxheight: 700

    Bug: (width changes to 384)
    http://www.youtube.com/oembed?format=xml&maxwidth=620&maxheight=700&url=http:%2f%2fwww.youtube.com%2fwatch?v=CeTa7YYkMcE

    Correct width:
    http://www.youtube.com/oembed?format=xml&maxwidth=620&maxheight=700&url=http:%2f%2fwww.youtube.com%2fwatch?v=H5UmoD9ReXU

    Is there a fix to this?

    PD.- None of the Dailymotion videos obey the width parameter.

    • I don’t have any control over YouTube, however my guess is that YouTube won’t return an embed size that’s larger than the original video’s size. But that’s only a guess.

  25. Pingback: WordPress 2.9: The Bloggers Gift for the Holidays | WordCast - Blogging news, WordPress help, WordPress plugins, WordPress themes, WordPress news

  26. Pingback: WordCast 75: WordPress 2.9 and Beyond | WordCast - Blogging news, WordPress help, WordPress plugins, WordPress themes, WordPress news

  27. Pingback: Learning oEmbed

  28. Hi Viper007Bond?

    Thanks for the work, it is great to have this feature in wordpress 2.9.

    Just a question, I wonder if there is a way to center the image, instead of floating left?

    Also, I tried to use the {embed] code to resize the image. It only works to reduce size but not when I want to have a large size (>500px). I wonder if is a way for this ?

    Thanks for your help 🙂

    • This should do the trick:

      <div style="text-align:center">[embed]...[/embed]</div>

      As for the size, it’s somewhat up to the remote site, but the max width and max height parameters as set at Settings -> Media are passed along to the remote site. Flickr has preset image sizes and will return the largest preset size it has that fits within your dimensions for example.

      • Thanks for the codes. It works like magic !

        As for the size, ummm….my wordpress media setting is set to 1024px. So it is flickr who presets it to max 500px. Well, nothing I can do.

        Thanks for your help ! Really appreciate.

    • Depends on the video site. WordPress gives them the max width and max height, but many opt to provide smaller videos. For example YouTube will not upscale videos to larger than their original size.

  29. Hi Viper

    First of all congrat to have joined the automatic team.. that’s a kick ass news

    is there a way you would be aware of to have the youtube video displayed directly in 720?

    thank you in advance

    Steffy

  30. Hey Alex, you’ve got a strong grip of this Oembed stuff. I’m wondering if you know how to embed YouTube URL’s without related content using the Oembed feature in WordPress?

    If you paste a URL into a WordPress post it will default to showing related content. Even if you add “&rel=0” to the end of the URL it still shows related content when you hover over the video. Is there a way to alter the way WordPress uses Oembed for Youtube?

    Thanks!

    • It’s 100% on YouTube’s oEmbed provider as it provides the HTML. It doesn’t have the ability to accept configuration arguments.

      However, you’ll be happy to know that the next version of my Video Quicktags plugin will be built on top of the oEmbed feature. It will basically filter the results of the supported oEmbed results and expand upon them. With YouTube for example, it’ll get the HTML back from them, save the width/height (so you don’t get any black bars) and video ID, and then ditch the rest of it. It’ll then create XHTML valid embed code and append on some query strings based on your settings (colors, related content, etc. etc.). In short, same usage as now (URL-on-it’s-own-line) but much better results. It’s already in action on my blog for example (the plugin is still super-alpha though).

  31. Thanks Alex, plugin looks perfect. I get what you’re saying about the Oembed feedback from YouTube not being able to manipulate the data. Thanks! Btw: love the little flags for the comments. Is this available as a plugin? Cheers

  32. I’m trying to build a little plugin to support local .flv files…
    Your article is a great resource!

    Unfortunately I’m unable to find a regular expression that can match the local uploaded flash files… I tried a lot but don’t knowing regex aven the online tutorial are like “old greek” for me.

    I think the regex expression would trigger if it finds something like this:
    [any text]

    anyone can help?
    Stefano

  33. Pingback: Per oEmbed Videos und Bilder in Wordpress einbinden » F!XMBR

  34. I’m sorry, but I failing at using this solution with the BBC.co.uk/mundo videos. I just cannot see how to use it. Do some of you guys know how to convert the object embed code in order to make a proper wp-handler?

    This is the code for sharing and embedding any BBC video:

    <object width="448" height="364"><param name="movie" value="http://www.bbc.co.uk/emp/external/player.swf"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><param name="FlashVars" value="playlist=http%3A%2F%2Fwww%2Ebbc%2Eco%2Euk%2Fmundo%2Fmeta%2Fdps%2F2010%2F09%2Femp%2F100927%5Fvideo%5Fmuseo%5Fcarcel%5Furuguay%5Fsao%2Eemp%2Exml&config_settings_showPopoutButton=true&config_settings_language=es&config_settings_showFooter=true&"></param><embed src="http://www.bbc.co.uk/emp/external/player.swf" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="448" height="364" FlashVars="playlist=http%3A%2F%2Fwww%2Ebbc%2Eco%2Euk%2Fmundo%2Fmeta%2Fdps%2F2010%2F09%2Femp%2F100927%5Fvideo%5Fmuseo%5Fcarcel%5Furuguay%5Fsao%2Eemp%2Exml&config_settings_showPopoutButton=true&config_settings_language=es&config_settings_showFooter=true&"></embed></object>

    As you can see, there’s no single url line for the video itself.

  35. I am building a plugin that puts posts/pages into a slider. I use strip_tags with some user defined allowed html tags in the strip_tags call. The user places the slider in a posts/page with a shortcode. I get multiple shortcode callbacks and I believe it is being caused by the embed shortcode. How can I temporarily disable the embed shortcode, while I prepare the slider pages, and then reenable it?

    • Yes, the embeds code does call do_shortcode() earlier than normal, but when it calls it only the embed shortcode should be registered.

      global $wp_embed;
      remove_filter( 'the_content', array(&$wp_embed, 'run_shortcode'), 8 );
  36. Thank you Alex, The problem is not with your new embed shortcode. I traced it down to a strip_tags call that has an allowed tag of

    <li>

    . When I strip a post/page allowing the

    <li>

    I get nine shortcode callbacks from a page with three shortcodes on it. Very strange!! Looks like I will have to keep digging to find the true cause.
    Thanks again for taking the time to reply.

Comments are closed.