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:

[php gutter=”false” autolinks=”false”]wp_oembed_add_provider( ‘http://site.com/watchvideo/*’, ‘http://site.com/oembedprovider’ );[/php]

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:

[php autolinks=”false”]/**
* 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’ );[/php]

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?

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

echo $width; // 600
echo $height; // 450[/php]

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. Pingback: Embedding video in WordPress will get easier, thanks to Portland’s Viper007Bond « Silicon Florist

  2. This is huge!

    >An internal handler has been supplied by the WordPress core

    Can we get the list (in your blog post) of the ones with internal handlers?

    > 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

    Can we get the list of this as well for testing? Also how is additions nominated?

    Thank you.

  3. [quote comment=”228551″]Can we get the list (in your blog post) of the ones with internal handlers?[/quote]

    Oh, good thinking. 🙂

    [quote comment=”228551″]Can we get the list of this as well for testing? Also how is additions nominated?[/quote]

    Sure. I basically added all of the ones listed on the oEmbed website:

    (and apparently I’ve found fixed an encoding bug in SyntaxHighlighter one of the old plugins I use)

    [php]$this->providers = apply_filters( ‘oembed_providers’, array(
    ‘http://*.youtube.com/watch*’ => ‘http://www.youtube.com/oembed’,
    ‘http://youtube.com/watch*’ => ‘http://www.youtube.com/oembed’,
    ‘http://blip.tv/file/*’ => ‘http://blip.tv/oembed/’,
    ‘http://*.flickr.com/*’ => ‘http://www.flickr.com/services/oembed/’,
    ‘http://www.hulu.com/watch/*’ => ‘http://www.hulu.com/api/oembed.{format}’,
    ‘http://*.viddler.com/*’ => ‘http://lab.viddler.com/services/oembed/’,
    ‘http://qik.com/*’ => ‘http://qik.com/api/oembed.{format}’,
    ‘http://*.revision3.com/*’ => ‘http://revision3.com/api/oembed/’,

    // Vimeo uses the discovery <link>, so leave this commented to use it as a discovery test
    //’http://www.vimeo.com/*’ => ‘http://www.vimeo.com/api/oembed.{format}’,
    ) );[/php]

    Sites added to this list should be trusted to not use malicious HTML (as all users on the blog, even those without unfiltered_html capabilities, can embed content from these sites) and should probably be considered popular (as we can’t include every site under the sun). Plugins can add additional providers as well as non-oEmbed handlers.

  4. Pingback: Starting a Blog — Multimedia Content Plugins – Brent Logan

  5. Awesome. Tried it on my test site, works brilliantly. Super duper thumbs up.

    This is just the sort of thing needed in core. Totally eliminates the need for a whole swath of plugins.

  6. Pingback: WordPress 2.9 ? oEmbed | ?????

  7. Pingback: Noch einfacher Videos & Bilder einbinden mit oEmbed in WordPress 2.9 - zu dt “automatische Erkundung”, Zu WordPress 29 Nightly-Builds, Weitere Informationen zu diesem Thema, Offizielle Seite von oEmbed, Technische Details zu oEmbed auf Deutsch, WordPr

  8. Pingback: oEmbeds And Post Thumbnails « Weblog Tools Collection

  9. Pingback: WordPress 2.9 Features - WordPress Tavern Forum

  10. Pingback: WordPress 2.9 Features

  11. Pingback: WordPress 2.9 Features List | TheTechJournal.com

  12. [quote comment=”228576″]Hi

    While it supports Flickr, why not support Picasaweb too! (since I use it extensively)

    S.K[/quote]

    That’s the whole point of this — it’s an API rather than adding support for only specific sites. Flickr is supported and used in my post as an example because they support oEmbed, which makes it stupidly easy to embed their images into posts.

    Sites that don’t support oEmbed can be added one-by-one using a plugin and my API.

  13. Pingback: WordPress 2.9 just around the corner – Alex Leonard’s Blog

  14. 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.

    I know WordPress have their own player, but it is heavily branded and aimed for use with WP.com or Videopress

  15. Pingback: Web Design Blog » Wordpress Blog 2.9 Features - Designbit - Blog Design, Web Design, Wordpress and Shopify Blog

  16. Hello, I have been using your plugin for a long time and it is a great piece of code, I have modified it to support a couple extra video providers that I needed, but I don’t see them mentioned here, so I would be more than glad to share the code, just contact me and let me know to get it to you.

  17. Pingback: Wordpres 2.9 nuevas funciones | Denken Über

  18. [quote comment=”228598″]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.[/quote]

    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.

  19. [quote comment=”228600″]Hello, I have been using your plugin for a long time and it is a great piece of code, I have modified it to support a couple extra video providers that I needed, but I don’t see them mentioned here, so I would be more than glad to share the code, just contact me and let me know to get it to you.[/quote]

    Unless the video sites are very popular, support for them should be added via a plugin that uses this new API.

  20. Pingback: Worpdress 2.9 nuevas funcionalidades « RSS2Blogs

  21. Pingback: Wordpress 2.9 – Features, Tips and Screenshots (Updated)

  22. This is awesome! I’ve already converted all my embeds over to the new format.

    I would love the ability to embed Amazon product thumbnails instead of having to use the associate widgets that Amazon offers. (The oohEmbed.com site suggests this is possible.) See my books page for an example:

    http://blogan.net/blog/im-reading/

    Also, is there any way to enable CSS styling? In other words, how could I apply float:left to the embeds?

    Thanks for all your work in this! 🙂

  23. [quote comment=”228609″]I would love the ability to embed Amazon product thumbnails instead of having to use the associate widgets that Amazon offers. (The oohEmbed.com site suggests this is possible.)[/quote]

    oohEmbed.com is an oEmbed proxy basically. They provide oEmbed support for sites that don’t support it themselves.

    It’d be VERY easy to add Amazon support — just write a plugin that uses the new wp_oembed_addprovider() function. 🙂

  24. [quote comment=”228610″]It’d be VERY easy to add Amazon support — just write a plugin that uses the new wp_oembed_addprovider() function. :)[/quote]

    This is clearly a case where “ease” is in the eye of the beholder. 😉

  25. Thanks! Now I’m having problems (no good deed goes unpunished…).

    I downloaded your sample plugin file, saved it with a php extension, and uploaded it to my plugins folder. When I attempted to activate it, I got the following error message:

    Plugin could not be activated because it triggered a fatal error.

    Fatal error: Call to undefined function wp_oembed_addprovider() in /home/blogan/public_html/blog/wp-content/plugins/amazon_embeds.php on line 11

    I’m running the latest version of WP (SVN 12078) and embedding of YouTube videos is working fine using [embed].

    Should I be able to find wp_oembed_addprovider() in wp-includes/class-oembed.php?

  26. //Fatal error: Call to undefined function wp_oembed_addprovider()//

    A dumb question: should it be capitalized like: “wp_oEmbed_addprovider()”?

    S.K

  27. [quote comment=”228616″]Thanks! Now I’m having problems (no good deed goes unpunished…).

    I downloaded your sample plugin file, saved it with a php extension, and uploaded it to my plugins folder. When I attempted to activate it, I got the following error message:[/quote]

    I guess I’m doing it too early. Try this: (also untested)

    http://viper007bond.pastebin.com/f2451e9b7

  28. [quote comment=”228617″]//Fatal error: Call to undefined function wp_oembed_addprovider()//

    A dumb question: should it be capitalized like: “wp_oEmbed_addprovider()”?

    S.K[/quote]

    PHP function names are case insensitive, plus it’s defined as all lowercase.

  29. The blank screen may be a side effect of oohEmbed.com. Clicking on the Amazon product example results in a *long* wait, while the other examples immediately provide JSON files.

  30. Pingback: The Audi S(F)4 | The Woodwork

  31. And until today, wp_oembed_add_provider() didn’t support regex for the first parameter. If you set the new third parameter to true, then it’ll know the first parameter is regex instead of just asterisks for wildcards.

  32. Pingback: WordPress Picks for the week [10/25] | Techtites

  33. [quote comment=”228655″]An example of how to add additional oEmbed providers: http://wordpress.org/extend/plugins/oohembed/ [/quote]

    I tried installing and using it.

    Hmm. I didn’t expect the Amazon link to work. I did expect the xkcd link to. Neither did. Youtube embeds are working for me.

    I am running WP 2.9-rare (latest SVN as of today).

    But then again, I appear to be somewhat special. I can’t even get the quote function to work here. It shows my entire comment as a quote, even though only your quote is within the quote “quick codes.”

  34. There should be backwards compatibility for the numerous plugins that use shortcodes such as: [youtube] [/youtube]. Otherwise, if you want to use the native oEmbed features you’ll need to go back and re-edit a ton of posts.

  35. [quote comment=”228663″]There should be backwards compatibility for the numerous plugins that use shortcodes such as: [youtube] [/youtube]. Otherwise, if you want to use the native oEmbed features you’ll need to go back and re-edit a ton of posts.[/quote]

    It’s up to the plugin authors to provide that functionality.

    Or if they don’t, they’ll work fine side by side with this new code.

Comments are closed.