52°F

Aaron Parecki

  • Articles
  • Notes
  • Photos
  • Experimenting with auto-embedding content

    May 9, 2013

    As part of expanding the functionality of the software my site runs on, I thought it was about time to start showing inline content when I post links in notes.

    You are probably already familiar with this idea from Twitter's implementation of "Twitter Cards" as well as how Facebook displays content inline in the News Feed.

    For my own site, I wanted to auto-embed more than just photos and video, so I went and found content I had linked to in the past and wrote some simple pattern matchers to look for those links. Below are the various types of content I am now providing inline previews for! I've also provided the source code I used to find the URLs as well as how I translate that to the appopriate embed code.

    My notes contain only plain text and a URL, and p3k will auto-detect any URLs it knows about and render the appropriate embed code for the media. I chose to put the embedded media below the entier post content to keep the flow of the "plaintext" note.

    My next step is to parse arbitrary URLs looking for an h-entry, and display a mini preview of the content linked to.

    Gist

    Gist

    Code

    if(preg_match_all('/gist\.github\.com\/([^\/]+\/[0-9a-f]+)/i', $this->body, $matches)) {
      foreach($matches[1] as $m)
        $embedded[] = '<script src="https://gist.github.com/' . $m . '.js"></script>';
    }
    

    SoundCloud

    SoundCloud

    Code

    SoundCloud provides an oEmbed endpoint that needs to be queried to retrieve the HTML embed code, since there is a secret token in addition to the URL

    if(preg_match_all('/https?:\/\/soundcloud\.com\/([^\/]+)\/([^\/ ]+)/', $this->body, $matches)) {
      foreach($matches[0] as $m) {
        // Fetch the embed code via the Soundcloud oEmbed endpoint
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'http://soundcloud.com/oembed?format=json&url=' . urlencode($m));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $response = curl_exec($ch);
        $data = json_decode($response);
        $embedded[] = $data->html;
      }
    }
    

    SlideShare

    SlideShare

    Code

    if(preg_match_all('/slideshare\.net\/[^\/]+\/[^ ]+-([0-9]+)/', $this->body, $matches)) {
      foreach($matches[1] as $m)
        $embedded[] = '<iframe src="http://www.slideshare.net/slideshow/embed_code/' . $m . '" width="600" height="440" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe>';
    }
    

    Spincam

    Spincam

    Code

    if(preg_match_all('/spincam\.net\/s\/([a-z0-9]+)/i', $this->body, $matches)) {
      foreach($matches[1] as $m)
        $embedded[] = '<div style="width: 360px; margin: 0 auto;"><iframe src="http://spincam.net/embed/' . $m . '" style="width:360px; height:480px; background:none; border:none; text-align:center;" scrolling="no"></iframe></div>';
    }
    

    Google Maps

    Google Maps

    Code

    if(preg_match_all('/http:\/\/goo\.gl\/maps\/[a-z0-9]+/i', $this->body, $matches)) {
      foreach($matches[0] as $m) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $m);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_exec($ch);
        $mapURL = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
    
        $embedded[] = '<iframe width="600" height="420" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="' . $mapURL . '&amp;source=embed&amp;output=svembed"></iframe>';
      }
    }
    

    Images

    Images

    Code

    if(preg_match_all('/https?:\/\/([^\s]+\.[^\s\.]+\.(png|jpg|jpeg|gif))/i', $this->body, $matches)) {
      foreach($matches[0] as $m)
        $embedded[] = '<img src="' . $m . '" />';
    }
    

    Video

    Video

    Code

    if(preg_match_all('/(https?:\/\/)([^\s]+\.[^\s\.]+\.(mp4))/i', $this->body, $matches)) {
      foreach($matches[0] as $i=>$m)
        $embedded[] = '<div style="width: 480px; margin: 0 auto;"><video autoplay controls width="480"><source src="' . $m . '" type="video/mp4" /><a href="' . $m . '"><span class="protocol">' . $matches[1][$i] . '</span>' . $matches[2][$i] . '</a></video></div>';
    }
    

    YouTube

    YouTube

    Code

    if(preg_match_all('/(youtube\.com|youtu\.be)\/watch\?v=([a-z0-9]+)/i', $this->body, $matches)) {
      foreach($matches[2] as $m)
        $embedded[] = '<div style="width: 600px; margin: 0 auto;"><iframe class="youtube-player auto-link figure" width="600" height="420" style="border:0"  src="http://www.youtube.com/embed/' . $m . '"></iframe></div>';
    }
    

    Vimeo

    Vimeo

    Code

    if(preg_match_all('/vimeo\.com\/([0-9]+)/', $this->body, $matches)) {
      foreach($matches[1] as $m)
        $embedded[] = '<div style="width: 600px; margin: 0 auto;"><iframe src="http://player.vimeo.com/video/' . $m . '" width="600" height="400" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></div>';
    }
    

    Vine

    Vine

    Code

    if(preg_match_all('/vine\.co\/v\/([a-z0-9]+)/i', $this->body, $matches)) {
      foreach($matches[1] as $m) 
        $embedded[] = '<div style="width: 480px; margin: 0 auto;"><iframe class="vine-embed" src="https://vine.co/v/' . $m . '/embed/simple" width="480" height="480" frameborder="0"></iframe></div>';
      // Add the necessary footer scripts to activate the embedded content
      $footerScripts[] = '<script async src="//platform.vine.co/static/scripts/embed.js" charset="utf-8"></script>';
    }
    
    Thu, May 9, 2013 12:47am -07:00 #p3k #indieweb #microformats
    3 replies 2 mentions
    • Absolon Kent twitter.com/absolonkent
      Thanks. I'll take a look at it. I also want to embed public Google calendars so the pdf.js option may be more fruitful.
      Fri, Mar 29, 2019 12:57pm +00:00 (via brid-gy.appspot.com)
    • Marcus Povey twitter.com/mapkyca
      Possible - override embed.tpl in a plugin with some regex-fu to extract urls with a pdf and/or look at mime types of any attachments. Then generate an embed - some browsers can do this natively I think, or you use something like pdf.js
      Fri, Mar 29, 2019 9:18am +00:00 (via brid-gy.appspot.com)
    • https://jgregorymcverry.com twitter.com/jgmac1106
      Would be cool. My current workflow is to upload pdf to my server and link on @withknown. (quickthoughts.jgregorymcverry.com/s/1h9BUN)
      Thu, Mar 28, 2019 12:50pm +00:00 (via brid-gy.appspot.com)

    Other Mentions

    • Absolon Kent twitter.com/absolonkent
      @mapkyca — I'm wondering if a pdf embed can be added to the .@withknown embed.tpl.php as you outlined in your "Experimenting with auto-embedding content" article? I'm stuck.
      aaronparecki.com/2013/05/09/1/e…
      Thu, Mar 28, 2019 12:09pm +00:00 (via brid-gy.appspot.com)
    • Ben Werdmuller werd.io/profile/benwerd
      Experimenting with auto-embedding content - Aaron Parecki
      Sun, Jun 23, 2013 11:18pm +00:00
Posted in /articles

Hi, I'm Aaron Parecki, Director of Identity Standards at Okta, and co-founder of IndieWebCamp. I maintain oauth.net, write and consult about OAuth, and participate in the OAuth Working Group at the IETF. I also help people learn about video production and livestreaming. (detailed bio)

I've been tracking my location since 2008 and I wrote 100 songs in 100 days. I've spoken at conferences around the world about owning your data, OAuth, quantified self, and explained why R is a vowel. Read more.

  • Director of Identity Standards at Okta
  • IndieWebCamp Founder
  • OAuth WG Editor
  • OpenID Board Member

  • šŸŽ„ YouTube Tutorials and Reviews
  • šŸ  We're building a triplex!
  • ā­ļø Life Stack
  • āš™ļø Home Automation
  • All
  • Articles
  • Bookmarks
  • Notes
  • Photos
  • Replies
  • Reviews
  • Trips
  • Videos
  • Contact
© 1999-2025 by Aaron Parecki. Powered by p3k. This site supports Webmention.
Except where otherwise noted, text content on this site is licensed under a Creative Commons Attribution 3.0 License.
IndieWebCamp Microformats Webmention W3C HTML5 Creative Commons
WeChat ID
aaronpk_tv