Some of you may have noticed recently that has started displaying OpenGraph meta information at the head of link-type posts (e.g. this post).

I admit I stole this idea from Tumblr, or rather I stole it from updating my (unreleased) WordPress-to-Tumblr crossposter plugin to support Tumblr’s support (“support”) of OG cards.1 I figured the idea would be cool to implement locally as well, and when I couldn’t find an existing plugin that did exactly what I wanted, I decided to write my own.

function oglinks_do_og_header($content) {
  // is this a link-type post?
  if(get_post_format() == 'link'){
        // get the first link in the post
        $output = preg_match_all( '/<a href=[\'"]([^\'"]+)[\'"].*>/i', $content, $m );
        // do we already have opengraph info cached for this post?
        $ogmeta = get_post_meta(get_the_ID(), '_ogmeta', true);
        // if not, try and find some...
        // also refresh this stuff if we're hitting the single page
        if(!$ogmeta || (is_single() && current_user_can('author', get_the_ID()))) {
            // get opengraph info for the link, if it exists
            $graph = OpenGraph::fetch($m[1][0]);
            $ogmeta['title'] = sanitize_text_field($graph->title);
            $desc = sanitize_text_field($graph->description);
            $ogmeta['description'] = (strlen($desc) > 500) ? substr($desc, 0, 500) .'...' : $desc;
                // should do something with this aye
                $wxh = getimagesize($graph->image);
                if($wxh[0] && $wxh[1]){
                    $ogmeta['image'] = array(
                            'src'    => sanitize_text_field($graph->image),
                            'width'  => $wxh[0],
                            'height' => $wxh[1]
            // add or update the info to the database
            update_post_meta(get_the_ID(), '_ogmeta', $ogmeta);
        // okay, if we have at least a title and/or description, display a card...
        // but don't do this if the post already has a thumbnail
        if(($ogmeta['title'] || $ogmeta['description']) && !has_post_thumbnail()) {
            $imgclass = ''; $img = '';
            // do we have an image?
            if(array_key_exists('image', $ogmeta) && $ogmeta['image']['src'] && $ogmeta['image']['width'] > 600) {
                $imgclass = ' og-link-box-img';
                $img = '<img src="'. esc_url($ogmeta['image']['src']) .'" style="max-width: 100%;">';
        $content = '<div class="og-link-box'. $imgclass .'" style="width: 600px; max-width:100%">'. $img .'<a href="'. esc_url($m[1][0]) .'"><h4>'. esc_html($ogmeta['title']) .'</h4><p>'. esc_html($ogmeta['description']) .'</p></a></div>' . $content;

  return $content;

add_filter( 'the_content', 'oglinks_do_og_header', 20 );

This assumes this OpenGraph library, and you’ll have to DIY your own CSS to format the output. I may eventually turn it into a Proper Real WordPress Plugin, but probably not until I figure out some better way to handle metadata caching, specifically around images (at the moment they’re directly linked from the source, which is kinda meh). It’s also kind of a bit ugly in RSS, and I’m still deciding if I care about that or not.2

Anyway. For a crappy little filter—and also the first thing I’ve coded in like five years—it does the job.

  1. I say “support” because Tumblr doesn’t auto-populate OG cards for link posts created by the API because… reasons, I guess. Also, I still can’t get it to accept the photos property, because… fuck you Tumblr, I guess. []
  2. Probably not. []