Creating Simple oEmbed-Based WordPress Shortcodes

Say you wanted to create a shortcode like this: [youtube id="991WcoEPwb8"]

And instead of manually creating the HTML yourself, you wanted to use YouTube’s oEmbed provider to get the HTML. While that’s easy to do using WordPress’ existing functions (wp_oembed_get() for example), you must implement your own caching of the result as WordPress’ oEmbed class does not include any caching of it’s own.

However, WordPress comes with an [embed] shortcode that’s also secretly used for the shortcode-less embeds. A cool trick is to make that shortcode’s existing code (complete with caching) work for you! This post explains how to do it.

First, the code:

add_shortcode( 'youtube', 'my_youtube_shortcode' );

function my_youtube_shortcode( $atts ) {

	// We need to use the WP_Embed class instance
	global $wp_embed;

	// The "id" parameter is required
	if ( empty($atts['id']) )
		return '';

	// Construct the YouTube URL
	$url = 'http://www.youtube.com/watch?v=' . $atts['id'];

	// Run the URL through the  handler.
	// This handler handles calling the oEmbed class
	// and more importantly will also do the caching!
	return $wp_embed->shortcode( $atts, $url );
}

We start by gaining access to the WP_Embed instance that we’ll be making use of and then making sure we have the required video ID (you can do whatever you want here). We then create the full URL to the video that oEmbed will need. Lastly the real time saver — we pass the attributes (“id” will be ignored) and the constructed URL to the [embed] shortcode handler which will fetch the result and cache it.

Simple, huh?

One thing to note though: if you’re using this along with a non-default oEmbed provider, you’ll also need to whitelist it using wp_oembed_add_provider().

Tracking WordPress Remote HTTP Requests

UPDATE: You can find improved code in this newer blog post. Use that instead.

I thought I’d share a bit of code that I run on my local WordPress test install to see when WordPress is contacting another website. I originally wrote this to help debug my oEmbed code, but it’s useful for a wide variety of purposes. 🙂

<?php

if ( !defined('DOING_AJAX') )
	add_filter( 'http_request_args', 'debug_http_api', 10, 2 );

function debug_http_api( $r, $url ) {
	echo '<p style="text-align:left">HTTP API was used to fetch <code>' . esc_html( $url ) . '</code></p>';

	return $r;
}

?>

The above code will output something like this any time a HTTP request is made using the HTTP API, but only if the request was not made from an AJAX handling script (as it will break the AJAX response):

HTTP API was used to fetch http://www.google.com/

While I’m using a filter to do this, I’m actually using the filter much like an action as I’m not modifying the passed data but merely using the filter as a place to hook in and catch the URL.

New Plugin: Enable oEmbed Discovery

For security reasons, the UI to enable oEmbed’s discovery ability was removed from WordPress today. It’d be too easy for a novice to accidentally embed some bad HTML into their blog if they posted the URL to a malicious website.

However if you know what you’re doing, feel free to install my Enable oEmbed Discovery plugin which will re-enable the feature. 🙂