Skip to content

Instantly share code, notes, and snippets.

@timrourke
Forked from razor-x/README.md
Last active August 29, 2015 14:19
Show Gist options
  • Save timrourke/4e10a1149a151e340896 to your computer and use it in GitHub Desktop.
Save timrourke/4e10a1149a151e340896 to your computer and use it in GitHub Desktop.

Load GitHub Gists asynchronously

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.
#
# 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()
//This silly little shortcode simplifies using Evan Sosenko's excellent script for async loading of github gists.
//Plop this in your functions file or functionality plugin.
//Usage: [gist id="12345567" file="example.js"]
//
function async_gist_func( $atts ) {
$gist = shortcode_atts( array(
'id' => '',
'file' => ''
), $atts );
if ( $gist['id'] && $gist['file'] ) {
$gist['jQuery'] = '<script>!function($){(function(){"use strict";$(function(){var GIST_HOST,code,elements,gists,loader,stylesheets;return GIST_HOST="https://gist.github.com",elements=$("div[data-gist]"),gists={},code=[],stylesheets=[],loader=function(url){var link;link=document.createElement("link"),link.type="text/css",link.rel="stylesheet",link.href=url,document.getElementsByTagName("head")[0].appendChild(link)},elements.addClass("loading"),elements.each(function(index,element){var gist;return element=$(element),gist=element.data("gist"),null==gists[gist]&&(gists[gist]={targets:[]}),gists[gist].targets.push(element)}),$.each(gists,function(id){return $.getJSON(GIST_HOST+"/"+id+".json?callback=?",function(data){var div,gist,stylesheet;return gist=gists[id],gist.data=data,stylesheet=gist.data.stylesheet,stylesheets.indexOf(stylesheet)<0&&(stylesheets.push(stylesheet),loader(stylesheet)),div=gist.data.div,gist.files=$(div).find(".gist-file"),gist.outer=$(div).first().html(""),$(gist.targets).each(function(index,target){var file,inner,outer;return file=target.data("gist-file"),file?(outer=gist.outer.clone(),inner=\'<div class="gist-file">\'+$(gist.files.get(gist.data.files.indexOf(file))).html()+"</div>",outer.html(inner)):outer=$(div),outer.hide(),target.fadeOut("fast",function(){return $(this).replaceWith(outer),outer.fadeIn()})})})})})}).call(this)}(jQuery);</script>';
$gist['css'] = '<style>.gist.loading::after{content: "(loading)";color: #99cc00;}.gist.loading-failed::after{content: "(loading failed)";color: #cc0000;}</style>';
$gist['HTML'] = '<div class="gist" data-gist="' . $gist['id'] . '" data-gist-file="' . $gist['file'] . '"><a href="https://gist.github.com/' . $gist['id'] . '">Loading file ' . $gist['file'] . ' from ' . $gist['id'] . '</a></div>';
return $gist['jQuery'] . $gist['css'] . $gist['HTML'];
}
}
add_shortcode( 'gist', 'async_gist_func' );
# 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment