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.

151 thoughts on “Easy Embeds For WordPress 2.9

  1. I’m an admin of 2 wordpress sites on 2 different servers. On the first, embeds work perfectly. But on the second it only works when I log as super-admin. Others users cannot embed anything. Both have the same version of wordpress (3.0). However the second has an older version of php (4.3.9).
    Is there a special php requirement?

  2. Pingback: Embeds in einem Text Widget

  3. Pingback: Are you using Embed.ly? If not, you should. | WordPress (Multi Site) & BuddyPress Tips

  4. Pingback: WordCast 75: WordPress 2.9 and Beyond | WordCast Podcast

  5. Pingback: The ultimate guide to embedding HTML and iframes in WordPress | WP Garage

  6. Pingback: WordPress - Embedding Media using OEmbed | Spenser Baldwin

  7. Pingback: The ultimate guide to embedding HTML and iframes in WordPress | WebDino.net

  8. Pingback: Wordpress Embed youtube videos | This is not Me!

  9. Pingback: Twitter Blackbird Pie review, discussions, does it work, and ratings on Loadwp.com | Loadwp.com

  10. Hi there, good code.I have question: how do you modify the wmode parameter of the embedded object (or add wmode attribute to the embed tag)? Right now, the video (youtube) scrolls over my fixed menu on top of the page while the rest of the content stays behind.
    Thanks

  11. I know its an old post, but I haven’t found this anywhere (it’s not in the codex); is there a way of using vimeo’s options? like title=0 or portrait=0 so the title doesn’t appear over the video.
    Tryed everything I can think of (like adding [embed title="0"], or at the end of the url, etc) but it doesn’t seem to work.
    Maybe it’s just not an option?

      • Thanks, I think the same. Googling I came across forum post a way around it, I’ll post it here in case anyone else is looking for something like this.

        jQuery(‘#MyContainerID iframe’).attr(‘src’, function() {
        return this.src + ‘?title=0&byline=0&portrait=0&color=ffffff’
        });

        Basically you add this jquery script at the bottom of the page or whatever and the #MyContainerID is the container where you load that oembed (i.e )

        the jquery gets the iframe url, adds whatever options you want (you can see them in vimeo’s universal player code) and loads the iframe with that options. Works pretty well :)

  12. Pingback: oEmbed

  13. Pingback: Just testing things om wp

  14. Pingback: Super Easy To Embed Videos, Images, And Other Content Into Your WordPress Site - V10

  15. Hi! As it said in the oEmbed documentation, the query returns also
    Some Title
    of the Youtube video. Can I get it in wordpress using your feature and add in a post before a player?

  16. Pingback: Tip: Super Easy To Embed Videos, Images, And Other Content Into Your WordPress Site - Blur Brain

  17. Hi Alex,

    thanks for the insights. Sorry to bother you with this, but you seem the most competent around regarding oembed in WordPress ;)

    It seems if I register a new handler for my own video service (like here: https://gist.github.com/Otto42/5854277) the wp_oembed_get function returns nothing if I use it in my template. However it works when I insert a plain url in my posts. Any Idea how this is happening?

    Would be greatful for any hint!

    Cheers Sascha

Leave a Reply