If you want to embed a YouTube video in a WordPress post or page, it’s pretty easy. For a while now, WordPress has been able to detect when you put the URL for the video on it’s own line in a post. Simply entering

https://www.youtube.com/watch?v=T7kdqFHP-g0

on its own line in your post is all you need. WordPress does the rest automatically.

Behind the scenes, what WordPress is doing is detecting that a URL is on it’s own line and that it matches a pre-determined list of video sites. Then it inserts that URL into an [embed] shortcode and processes the shortcode.

Not too long ago, you had to actually write in the whole shortcode like this:

[embed]https://www.youtube.com/watch?v=T7kdqFHP-g0[/embed]

You still find quite a bit of this around the web if you Google “WordPress Embed YouTube” or similar. And doing it this way still works.

All that’s great, but what if you want your video in a sidebar (widget area)? Entering that same URL on its own line doesn’t work. And neither does the embed shortcode itself. Bummer.

So next, you Google “WordPress shortcode in sidebar”, and you’ll find a lot of tutorials about how to make that happen. It’s pretty easy. Just add this single line of code into your theme’s functions.php file:

add_filter( 'widget_text', 'do_shortcode' );

Once you do that, you can use just about any shortcode in a text widget and have it work the same as in a normal post or page. Just about!

It turns out that the embed shortcode is the exception. It won’t work. Why?

It’s because the embed shortcode has to run on its own and before any other shortcode processing. If it tries to process alongside all the other registered shortcodes, it fails and displays a blank.

Fortunately, there is a way to make this happen – the same way it happens in ordinary posts. WordPress adds two filters to its own processing of post content, running it through a couple of methods in its WP_Embed class. All we need to do is attach the same two filters to the widget text. An instance of the WP_Embed class is already stored in a global $wp_embed variable. We attach the filters with a priority of 8 so they run before any of the other shortcodes (which normally run on priority 10).

So let’s wrap all our sidebar shortcode stuff into a function (which we can run from anywhere in our functions.php) file:

function iCaspar_add_shortcodes_to_text_widgets() {
    global $wp_embed;

    add_filter( 'widget_text', [ $wp_embed, 'run_shortcode' ], 8 );
    add_filter( 'widget_text', [ $wp_embed, 'autoembed' ], 8 );
    add_filter( 'widget_text', 'do_shortcode' );
}

iCaspar_add_shortcodes_to_text_widgets();

Now you can enter your YouTube URL or use the embed shortcode with a text widget as you would in a normal post.