Fixing oEmbed with a Custom Provider

The story of my blogging career over the past few years could be summed up as, “How I Learned to Stop Worrying and Love the Reblog.” There’s something that’s so much fun about finding something cool and sharing it on my blog without worrying about saying something poignant or ultimately meaningless in an effort to “add to the conversation.” Sometimes it’s enough just to amplify the conversation, or share that video.

This is why I’m so excited about oEmbed. It’s a standard API that takes a given link and turns it into an embeddable… thing. It’s most commonly known as “that thing that turns a YouTube link into a video,” but the underlying technology can be used for any web page. This includes sites like Reddit, Twitter, and Imgur, as well as blogging sites like Tumblr and, yes, WordPress.

Mice performing Destiny Supers

WordPress has built-in support for oEmbed, both as a consumer and a provider. This means that not only can you embed other posts into your WordPress post, but other people can embed your posts into their posts!

WordPress already has built-in support for several sites. If you want to branch out of those, it’s a simple matter of adding an oEmbed provider in your theme’s functions.php file or a plugin, except when it isn’t.

For a past Five For the Future day, I wanted to write a plugin to connect WordPress to DeviantArt’s oEmbed API. Normally, this would be a one-line plugin to call wp_oembed_add_provider to match DeviantArt’s fav.me short links to their API endpoint:

wp_oembed_add_provider( 'http://fav.me/*', 'https://backend.deviantart.com/oembed', false );

But when is life web development ever that easy?

Block Editor error saying "this content could not be embedded"

In this particular case, I had to dive a little deeper. It turns out DeviantArt had two things going against it:

  1. DeviantArt’s response did not include an html element, electing only to provide the basic image data. This is allowed by oEmbed rules, but it makes things a little more difficult for WordPress.
  2. After much trial, error, more trials, and even more errors, I eventually learned that DeviantArt’s API will fail with a 403 error if the User-Agent is not set.

All this means that, instead of piggybacking on WordPress’ built-in oEmbed support, I had to go a little lower on the stack and use wp_embed_register_hashndler. With this function, you provide a regular expression and a callback function. When WordPress sees a URL matching the regular expression, it will provide the URL as well as the individual matches from the regular expression to your callback function. This allows you to turn most URLs into rich HTML code for your website.

In the case of DeviantArt, there is already an API endpoint that can provide information for a URL, which makes the whole thing much simpler. The plan in short:

  1. Provide a regular expression to match fav.me links to my callback function.
  2. In the callback function, set the User-Agent and use wp_remote_get to hit DeviantArt’s API.
  3. Parse the JSON object returned.
  4. Output an HTML template populated with information from the API.

My goal in this case is to be able to take a DeviantArt post and embed it into a WordPress post while keeping attribution obvious. Artists use sites like DeviantArt in order to get exposure and share their art with a larger audience. If I’m going to share a work on my website, it’s only right for me to credit the artist and link back to the page so others can find and share the work as well.

Did I succeed? Basically:

Screenshot of a deviant art post embedded into a WordPress post.

I’ve included a sample of my code so far below (via oEmbed, no less), and you can see the whole thing on GitHub. There’s still a few issues to iron out, especially with the current WordPress Block Editor and the general look and feel of the final code. But I’m excited to dive further into this technology that makes sharing cool stuff so much more fun!


Have a comment?

Your email address will not be published. Required fields are marked *

accessibilityadminaggregationanchorarrow-rightattach-iconbackupsblogbookmarksbuddypresscachingcalendarcaret-downcartunifiedcouponcrediblecredit-cardcustommigrationdesigndevecomfriendsgallerygoodgroupsgrowthhostingideasinternationalizationiphoneloyaltymailmaphealthmessagingArtboard 1migrationsmultiple-sourcesmultisitenewsnotificationsperformancephonepluginprofilesresearcharrowscalablescrapingsecuresecureseosharearrowarrowsourcestreamsupporttwitchunifiedupdatesvaultwebsitewordpress