Schildwächter – Ideas and Solutions by Carsten Thiel

to embed or not to embed

I am actually not a big fan of simpli inlining remote content calls into this blog via iframes for Twitter, Youtube etc. But when I first started getting it back up, I decided to take the easy way first. Thus tweets and youtube videos were directly embedded.

Now its time to start fixing that and reduce it to a minimum.

I began with the tweets.

I am using a modified version of the Jekyll Lazy Tweet Embedding Plugin to render tweets. Basically, the plugin fetches the HTML from Twitter’s oembed API and puts it directly into the static blog post page. All I did was extend the plugin with a small string replacement stripping the <script> tag and adding a simple <span> at the beginning of the blockquote for the twitter icon. Finally a bit of basic CSS markup is applied, to add Twitter’s border and the two icons.

Though this currently only show the plain message and not any images, its good enough for now.

Moving on to Youtube, I decided to implement a solution by Amit Agarwal on top of a simple youtube plugin by Joel Verhagen.

Adopting Amit’s approach, I output the image div directly into the HTML, so the post Mathenacht 2013 which contains the markup

{% youtube D-iI06hlDMIs %}

renders to

<div class="youtube-container">
  <div class="youtube-player" id="D-iI06hlDMI" data-id="D-iI06hlDMI">
    <img class="youtube-thumb" src="https://i.ytimg.com/vi/D-iI06hlDMI/hqdefault.jpg">
    <div class="play-button"></div>
    <div class="youtube-title">Youtube</div>
  </div>
</div>

Apply a bit of javascript and css to that, and you get the nice playback feature visible in the post.

Now, the title can be set as a second argument to the youtube tag, bit isn’t here. To see how this works, let’s look at the slightly extended variant for playlists:

class YouTubeList < Liquid::Tag
  # playlist id, preview id and optional caption
  Syntax = /^\s*([^\s]+)\s+([^\s]+)(?:\s+([^\s]+))?\s*/

  def initialize(tagName, markup, tokens)
    super

    if markup =~ Syntax then
      @list = $1
      @preview = $2

      # title has a default
      if $3.nil? then
        @title = "Youtube Playlist"
      else
        # to simplify RegEx, use _ for space in String
        @title = $3.gsub('_',' ')
      end

    else
      raise "Please provide YouTube ID of list and preview video in the \"youtubelist\" tag"
    end
  end

  # render the html to be processed by javascript later
  def render(context)
    "<div class=\"youtube-container\">
       <div class=\"youtube-list-player\" id=\"#{@list}\" data-id=\"#{@list}\">
         <img class=\"youtube-thumb\" src=\"https://i.ytimg.com/vi/#{@preview}/hqdefault.jpg\">
         <div class=\"play-button\"></div>
         <div class=\"youtube-title\">#{@title}</div>
       </div>
    </div>"
  end

  Liquid::Template.register_tag "youtubelist", self
end

This will again be replaced with the actual youtube content, once the user clicks on the image and thus explicitly chooses to load the remote content. The JS to do that is taken from Amit’s original post. I did think about loading the title and first video directly from youtube during compile time, but that requires authenticated API access, though maybe I’ll do it at a later point.

It is not perfect, in that the image is still loaded from youtube, but caching someone else’s preview images and effectively hosting them on my server might be legally tricky.

Also, the blog’s fonts are loaded directly from Google’s Fonts API as well.

Tags: code blog jekyll