NoEmbed: Embedding What’s Not oEmbed

Instead of a shortcode, how about a URL?

We all love oEmbed with WordPress. Want to include a YouTube video? Paste in the URL and call it a day!

The magic is that WordPress sends data to the YouTube oembed endpoint (i.e. a special app on YouTube that translates URLs to embed things) and says “Hi, I have this video URL here, what can I use to embed it?” And YouTube replies back “This javascript, my fine friend!” WordPress tips it hat and carries on, swapping the URL out for javascript on the fly.

Awesome.

Except when it doesn’t work because it can’t because there isn’t an oEmbed endpoint.

What Now?

Usually I make a shortcode. But my man Otto always grumbles and tells me to make an embed instead.

The concept of the embed is that we register a ‘fake’ oembed. It’s not an endpoint, it’s just saying “Hey, WordPress. When you see this kind of URL all alone, let’s make magic.”

It’s surprisingly straightforward. All we need to know are two things:

  1. What is the URL people are going to paste in?
  2. What is the output supposed to look like?

Since we’ve already done this as a shortcode, we’re ready to go.

Register the Handler

First we have to tell it that we’re making a new handler, called indiegogo and this is the kind of URL to expect:

wp_embed_register_handler( 'indiegogo', '#https?://www\.indiegogo\.com/projects/.*#i', 'indiegogo_embed_handler' );

The first part, indiegogo, is the name. It should be unique.

The second part, '#https?://www\.indiegogo\.com/projects/.*#i' is saying “http OR https” and “as long as the URL starts with www.indigogo.com/projects” — it’s ‘basic’ regex.

The last bit, indiegogo_embed_handler is the function name we’re going to need.

Write the Embed Function

This is very similar to the shortcode. We take the data, make sure it’s formatted correctly, and output the (in this case) iFrame:

function indiegogo_embed_handler( $matches, $attr, $url, $rawattr ) {
	$url   = esc_url( $matches[0] );
	$url   = rtrim( $url, "#/");
	$url   = str_replace( 'projects/', 'project/', $url );
	$embed = sprintf( '<iframe src="%1$s/embedded" width="222" height="445" frameborder="0" scrolling="no"></iframe>', $url );
	return apply_filters( 'indiegogo_embed', $embed, $matches, $attr, $url, $rawattr );
}

I’ve left the filters in place in case I decide I want to do more weird things to it, without having to edit the core part of my code.

A GutenGotcha

For some reason, this doesn’t work in Gutenberg, and it tells me it cannot embed the content. Except when you visit the page, everything is embedded perfectly.

%d bloggers like this: