cute robot

TimNash.co.uk

Dev/Sec/Ops with a splattering of humour

Becoming an oEmbed Provider

Really old post – This post is from 4 years, 10 months and has not been updated, some if not all of the information maybe out of date. Proceed with caution.

oEmbed has been in the WordPress ‘news’ a fair amount recently. With WordPress core supporting a couple of new providers as of WordPress 3.9, and with new services like CodePen supporting oEmbed and providing plugins, it’s like all the cool kids are getting on the oEmbed bandwagon.

So what is oEmbed?

Well it’s an open format to allow websites to have limited control over how their content is displayed on other sites. Or when they are selling the idea to others, it’s a way to provide rich content to their site.

It works like this, the publisher creates an end point on their site /oembed/?url=blah. Then, whenever a call is made to the end point with a valid url that they want to provide content for, they return an XML or JSON document with some information about the URL and additional content. For example, Youtube implementation of oEmbed returns a video when you point at it, while the Codepen implementation returns an iframe with the pen inside.

All sorts of sites support oEmbeds, from places like Twitter to Kickstarter, including any site hosted on WordPress.com. However, most of these sites are not supported by WordPress core by default (at time of writing just 24), and interestingly WordPress.com is not one of the oEmbed providers on the list.

The oEmbed specification includes the concept of discovery by placing a link in a page’s HTML head to the oEmbed for the relative page.


<link rel="alternate" type="application/json+oembed" href="https://timnash.co.uk/wp-json/oembed/?url=https://timnash.co.uk/structuring-next-wordpress-project/"
title="Structuring your next WordPress project" />

In theory this means any site which has an oEmbed consumer (like any WordPress site) could automatically pull in this rich content. Of course there are nefarious people out there who could take advantage and insert inappropriate content on other peoples sites, so most implementations of oEmbed consumers (including WordPress built-in) work using an approved white list rather than accepting any oEmbed offered.

So how does this all work in practice in WordPress?

Youtube oEmbed Example

In WordPress visual editor when you add a url from an approved white listed provider and save/publish the post, WordPress grabs the URL, looks up the oEmbed end point and makes a call to that end point, which will return a jSON or XML document. Within this return is normally a HTML element, which is then rendered to the screen. Obviously a lot more things are going on, caching etc, but you get the general idea.

Extending the WordPress white list

If you want to add a provider to the white list on your copy of WordPress then you need to add wp_ombed_add_provider via a plugin or in the functions file in your theme. You can try it now by adding:


wp_oembed_add_provider('https://timnash.co.uk/*', 'https://timnash.co.uk/wp-json/oembed/');

The function has two variables. The first is the path of URLS to match against with * being wild card, so in this case any time you add https://timnash.co.uk/anything-after-here/ it will send a request to ‘https://timnash.co.uk/wp-json/oembed/?url=https://timnash.co.uk/anything-after-here/’ which in this case would return a 404 as that isn’t a post on the blog. If you put a real URL blog post such as this one it will return some “rich content”.

Of course, with the exception of whitelisting timnash.co.uk, you probably don’t want to add lots of individual sites. Most oEmbed providers will provide plugins to add themselves to your WordPress white list and there are aggregator-like services such as embed.ly and noembed that can provide convenient end points and even offer access to services who don’t have a native oEmbed support.

Becoming a provider yourself

So up till now it’s all about how to consume other peoples content, so how do you become a provider?

As oEmbed is an open format, becoming a provider is simply a matter of providing a suitable end point and response. For the above demo I created my own little service, which simply takes a link and returns a nicely formatted link – you could get far more creative.

When you call the API it makes a check if the post exists and it’s a post. If it’s not then it simply returns a 404 as the oEmbed API allows users to get the return in JSON and XML. I have also added a check for format, so if you ask for the XML version you get a 501. This follows the oEmbed specification, though really if you were building out a fully fledged oEmbed end point you would want to support both.

Assuming everything went ok and we found a suitable post, you will probably get a response similar to this.


{
   "success":"true",
   "type":"rich",
   "version":"1.0",
   "provider_name":"TimNash.co.uk",
   "provider_url":"https:\/\/timnash.co.uk",
   "title":"Structuring your next WordPress project",
   "author_name":"Tim Nash",
   "author_url":"https:\/\/timnash.co.uk",
   "width":"300",
   "height":"500",
   "html":"<a href=\"https:\/\/timnash.co.uk\/structuring-next-wordpress-project\/\">Structuring your next WordPress project<\/a>"
}

Breaking this down for a rich type oEmbed:

  • Success – Fairly obvious. Given you would send a 404 if you didn’t find something, a false statement is only going to occur if there is an error.
  • Type – Includes Photo, Video, Link and Rich, it’s worth noting a lot of video and photo sites set their type to Rich rather than video or photo as it allows them to insert an iFrame rather than simply providing a video object.
  • Version – The version of the spec you are using, so currently this will always be 1.0
  • Provider Name and URL – These are optional but identify who is providing the oEmbed resource, very useful if the oEmbed resource is being provided by a third party.
  • Title – title of the resource
  • Author Name and URL – Similar to the provider except it’s the information about the owner
  • Width and Height – The dimensions of the payload
  • html – The payload we will insert on the page

In my above example it will create a link like – Structuring your next WordPress Project

How am I doing this?

Important! This was a quick hack to demo oEmbed, so it’s possibly not the best base for doing it yourself.

For this example, I built the oEmbed end point using WP JSON API, which is a fantastic plugin written as part of the Google Summer of Code but with the aim of becoming a core component of core in the future. It’s a RESTful implementation and made it easily to knock up the demo code in a couple of minutes. I’m not going to go through how to use the plugin but to highlight a few steps:

To get started I created a oEmbed provider class and a function to register a route:


function register_routes( $routes )
	{
		$routes['/oembed'] = array(
            array( array( $this, 'get_url'), WP_JSON_Server::READABLE )
         );

		return $routes;
	}

This basically tells the API that anything using GET going to wp-json/oembed/ should be handed of to the get_url function in the class.

The get_url function basically checks and dumps the payload.


function get_url( $url = FALSE, $format = 'json', $context = 'view' )
	{
		//Start by checking format
		if( $format == 'xml'){
			//throw an error as we don't support it
			return new WP_Error( 'oembed_lack_support', __( 'only JSON supported for oEmbed' ), array( 'status' => 501 ) );
		}
//IF YOU ARE COPY AND PASTING DO MORE ROBUST CHECKING HERE - Tim
		$post_id = url_to_postid( $url );

		if( $post_id === 0 && !is_single( $post_id )){
			//throw an error as we have nothing to return
			return new WP_Error( 'oembed_no_resource', __( 'Resource not found - Only Posts Supported for oEmbed' ), array( 'status' => 404 ) );
		}
....

The URL and format variable are being populated by GET variables from the API, with defaults if they are empty.

Our first step is to check the format variable, and throw an error if they put in XML. Really this should be a check to confirm they didn’t specify or they specified JSON rather than assuming that XML and JSON are the only options.

Next grabbing the URL and trying to find a relevant post ID. In this example I’m just throwing it straight to url_to_postid, but you will want to do some more robust checks. Once we have a post ID we check it’s not 0 meaning it’s not in the posts table and is_single so it’s not a page or attachment – if it is we throw a nice 404.

Next up we create the payload which is basically just an array Then we send the array back to the API for it to handle the response to the requester.


//create response
		$response = new WP_JSON_Response();
		$response->set_data( $oembed );

		return $response;

The full example gist can be found here.

This example produces possibly the least interesting result, but provides a nice demonstration of how to build your own provider and what you choose to display to users is up to you. A few ideas for people running WordPress sites:

  • A nice rich snippet summary of your posts, maybe your excerpt + thumbnail and title, number of comments.
  • Photography and Video bloggers could provide video embeds of their pictures and content. If you already provide an ’embed this here’ service for your images, infographics etc then oEmbed as an option may make sense to you as well.
  • If you provide content that is normally behind a paywall, you could provide exclusive access to some of the content or the whole article in a similar way to first click free.
  • For WooCommerce and E-Commerce users, creating nice marked up products

Because oEmbed allows a site to insert HTML directly into a post, you can do pretty much anything you want. This leads to the warning, with great power comes great responsibility. If you are creating embedable iframe content which you are hosting, you are going to be responsible for it, just like any other embed options out there. The difference is when someone copies and pastes an embed code they make a conscious choice to add the embed code, whereas with oEmbed this happens automatically, and the author may not even know that what they are doing will result in content being embedded, which is why most systems white list.

One thing not talked about much is using oEmbed internally, so consuming your own oEmbed provider. This is something I have started trialing with a client, but normally any situation where oEmbed is suitable a shortcode would probably work just as well.

If you are looking for a real basic way to become an oEmbed provider on your site but don’t fancy getting your hands dirty then you might want to look at the oEmbed Provider plugin, I haven’t played with it but it has some active development.

Finally as a bit of an experiment I have enabled oEmbed for comments. When I set this up I hit a bit of a stumbling block as this site runs over SSL meaning if you embed iFrames calling not https results most browsers will block the content by default. The oEmbed for Youtube returns the embed as http regardless so I have had to filter the youtube payload using the ‘oembed_result’ filter and replacing http for https. The result…

Rick Rolls for all!!!

To finish, it’s worth re-emphasing that if you are thinking oEmbed is a sneaky way to get links on sites with anchor text of your choice or to put something actually useful on another persons site, they have to be using a CMS supporting oEmbed such as WordPress and you will almost certainly need to be whitelisted. However it could be a really valuable tool for sites, which already have options for people to embed your content elsewhere especially for video and photobloggers.


Have your say?

Sorry Comments are now closed, feel free to tweet me!