Skip to content

Instantly share code, notes, and snippets.

@razor-x
Last active February 19, 2020 10:26
Show Gist options
  • Save razor-x/8288761 to your computer and use it in GitHub Desktop.
Save razor-x/8288761 to your computer and use it in GitHub Desktop.
Load GitHub Gists asynchronously and optionally specify which file to show.

Load GitHub Gists asynchronously

This is now a Bower package: [gist-async]. [gist-async]: https://github.com/razor-x/gist-async

Requires jQuery.

Jekyll plugin included that modifies the gist markup added by its gist Liquid tag.

Load GitHub Gists asynchronously and optionally specify which file to show. This allows you to keep related files in a single gist, but show them individually on your pages. The async loading prevents your page rendering from stalling.

Example markup:

<div class="gist" data-gist="8288761" data-gist-file="gist-async.coffee">
  <a href="https://gist.github.com/8288761">Loading file gist-async.coffee from 8288761</a>
</div>

The minimal required markup is

<div data-gist="8288761"></div>

Demo on CodePen: http://codepen.io/razorx/pen/mGKih

Based on Mark Selby's async-gists.js: https://gist.github.com/markselby/7209751

This version by Evan Sosenko: https://gist.github.com/razor-x/8288761

# Load GitHub Gists asynchronously
# and optionally specify which file to show.
#
# This is now a Bower package: gist-async.
# https://github.com/razor-x/gist-async
#
# Requires jQuery.
#
# Based on Mark Selby's async-gists.js:
# https://gist.github.com/markselby/7209751
#
# This version by Evan Sosenko.
#
# Source and usage instructions:
# https://gist.github.com/razor-x/8288761
#
'use strict'
$ ->
GIST_HOST = 'https://gist.github.com'
elements = $('div[data-gist]')
gists = {}
code = []
stylesheets = []
# The asynchronous asset loader function.
loader = (url) ->
link = document.createElement 'link'
link.type = 'text/css'
link.rel = 'stylesheet'
link.href = url
document.getElementsByTagName('head')[0].appendChild link
return
elements.addClass('loading')
# Get elements referencing a gist
# and build a gists hash referencing
# the elements that use it.
elements.each (index, element) ->
element = $(element)
gist = element.data 'gist'
gists[gist] ?= targets: []
gists[gist].targets.push element
# Load the gists.
$.each gists, (id, data) ->
$.getJSON "#{GIST_HOST}/#{id}.json?callback=?", (data) ->
gist = gists[id]
gist.data = data
# Only insert the stylesheets once.
stylesheet = gist.data.stylesheet
if stylesheets.indexOf(stylesheet) < 0
stylesheets.push stylesheet
loader(stylesheet)
div = gist.data.div
gist.files = $(div).find('.gist-file')
gist.outer = $(div).first().html('')
# Iterate elements refering to this gist.
$(gist.targets).each (index, target) ->
file = target.data 'gist-file'
if file
outer = gist.outer.clone()
inner = "<div class=\"gist-file\">" \
+ $(gist.files.get(gist.data.files.indexOf(file))).html() \
+ "</div>"
outer.html inner
else
outer = $(div)
outer.hide()
target.fadeOut 'fast', ->
$(this).replaceWith(outer)
outer.fadeIn()
# Overrides the gist markup added by Jekyll's gist Liquid tag
# to support loading GitHub Gists asynchronously using gist-async.coffee from
# https://gist.github.com/razor-x/8288761
module Jekyll
class GistTag
def gist_script_tag(gist_id, filename = nil)
file_data_attr = filename.empty? ? '' : %Q{ data-gist-file="#{filename}"}
# Append additional markup to this string that will be replaced on gist load
inner = ''
%Q{<div class="gist" data-gist="#{gist_id}"#{file_data_attr}>#{inner}</div>}
end
end
end
@timrourke
Copy link

Found this immensely useful. I forked your gist to add a silly little WordPress shortcode for easy gist embedding. Thanks for your excellent work on this, seems way more predictable/maintainable than the crazy PHP string manipulation I was doing to produce the same result. And it's async.

@timrourke
Copy link

@razor-x
Copy link
Author

razor-x commented May 16, 2015

@timrourke I'm glad you found this useful. I just noticed your comment now as am converting this to a full-fledged Bower package. I will make a new gist with the WordPress and Jekyll plugins. Then I will create a demo page that loads them using the plugin!

https://github.com/razor-x/gist-async

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment