Heartbeat API oEmbed

The problem:

The reason why this isn’t working, is this part of the WP_Embed::shortcode() method:

 if( $post_ID ) {
    .... cut ...

    // Use oEmbed to get the HTML
    $html = wp_oembed_get( $url, $attr );

    ... cut ...
 }

When trying to autoembed with the Heartbeat API the $post_ID is null, so wp_oembed_get() is never activated.

No Caching:

When you autoembed the Twitter link in the post editor, for a given $post_ID, the oembed HTML is cached in the post meta table under a key like this: _oembed_7bc759c5dcea2e4b77c939fc109996fb and a value like this:

<blockquote class="twitter-tweet" width="550">
   <p>
      WordPress 3.9 “Smith” is now available with a smoother media editing experience, 
      live widget previews, and more: 
      <a href="http://t.co/mEbgUFdpyG">http://t.co/mEbgUFdpyG</a>
   </p>
   &mdash; WordPress (@WordPress) 
   <a href="https://twitter.com/WordPress/statuses/456502643738030080">April 16, 2014</a>  
</blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Each oembed link gets it’s own row in the post meta table, well if it’s not part of the default oembed handlers.

This caching mechanism is skipped when the $post_ID is missing, so you might want to consider some caching for your setup.

Possible workarounds:

i) You need to take all the matches of '|^\s*(https?://[^\s"]+)\s*$|im', within your string, and run it through the wp_oembed_get() function and replace the links from the original string.

ii) We could also associate it with a given post, within the test_heartbeat_received callback:

global $wp_embed, $post;
$post = get_post( 3147 ); // Post ID: 3147

$content = $wp_embed->autoembed( $content );
$response['test_heartbeat'] = $content;

to get around the missing $post_ID part and use the default caching for that post. You just have to remember that the oembed cache clears when you update that post.

If you try for example two Twitter links, with the above method:

$content = "
    <div>
        
    </div>
    <div> 
         
    </div>
    ";

then after the autoembed process, you get two rows in the post meta table, assigned to post_id: 3147:

oembed rows

Leave a Comment