Dynamically Rendering GitHub Files in Web Pages

You know how you can easily embed GitHub Gists into a webpage? I’ve always wanted that for any file on GitHub. I post a lot of code on my blog and it’s always tedious and error-prone having to copy and paste the code. I’d rather be able to dynamically render a specific version of a file hosted on GitHub. So I created a little JavaScript jQuery plugin called github-files that pulls blobs from GitHub. Those blobs can then be rendered client-side and optionally syntax highlighted. To use github-files, get the git sha for a file:

git rev-parse HEAD:src/main/javascript/github-files.js

Then you can grab the file from GitHub in JavaScript:

$.getGithubFile("user", "repo", "sha",
    function(contents) {

Here’s the source for github-files.js, fetched dynamically using github-files.js and rendered with highlight.js:

This uses GitHub’s JSONP API to pull the file in. It’s pretty simple and could use a few more features but it’s a start! Matt Raible and I are using this for our upcoming ÜberConf presentation to render code in our reveal.js preso. Hopefully this is useful for others. Let me know what you think.

  • This is so cool!! You could build a CMS and manage the content from Github!

  • Marcello Barnaba

    Why extending jQuery on .ready()?

    • Before I did it that way I was getting an error that $ was not defined.  Maybe this isn’t the right way to do it.  This is my first jQuery plugin.  Suggestions?

      • Wes

        jQuery.getGithubFile = function(…){

        That should do the trick for you.  Or, if you wanted to load the content straight into a container div you could do:

        jQuery.fn.getGithubFile = function(){}

        Then you can say:

        $(‘#mydiv’).getGithubFile(“user”, “repo”, “sha”);

        and you will have ‘this’ referencing that jQuery object and just append the new content inside your plugin.

        If you are interested in a nice plugin template look here: http://css-tricks.com/snippets/jquery/jquery-plugin-template/

        • I agree. I also think that there are a few other performance improvements lurking in there. I forked the repo and will submit some suggestions. This looked like a project that I could contribute a little to so I am diving in.

          • Awesome!  Thanks guys!  Send me a pull request.

            A few other things I’d like to do:
             – Put the js (and maybe min.js) on a CDN
             – Have a function that allows you to get a blob’s hash just by specifying a branch and a file name (for when you always want the most recent instead of a specific version of a blob)

          • You can use GitHub’s pages as a CDN – 

          • I don’t think GitHub pages is actually a CDN (edge cached assets).  It’s just a static hosting service.

  • @jlward4th:disqus you should include your testing environment in the repo so that if someone wants to help out they can do so efficiently. I haven’t used Jasmine before so I don’t know how to use the XML file to run the tests. Any help would be appreciated.

    • I’m using Maven to run the tests and do the build.  All you need to do is run:

      mvn test

      Does that help?

    • You can also run:

      mvn jasmine:bdd

      And then navigate to: http://localhost:8234

      • Yes thanks. Glad I’m on a Mac and don’t have to install/configure anything. Not a big fan of some of the processes involved with Apache projects; mostly surrounding Java. But the tests are running fine now with 

        mvn jasmin:bdd

  • Just sent a pull request. 

  • This is awesome man.  I am working on a jQuery plugin right now that is going to be heavily influenced by this blog post.  I will post the link when it is finished and give credit where credit is due!

  • D Chiesa

    I see nothing after the “Here’s the source…:” line??? Did it work?

    • Thanks for reporting the problem! I’ve fixed this. Turns out I accidentally removed github-files.js from my server.

  • This is really great, thanks!

  • Hey James: cool code, thanks! Just one question (and I am being lazy, I could look at the GitHub API etc, but I figured you might already know the answer)…

    git rev-parse HEAD:src/main/javascript/github-files.js

    That gets the sha for the HEAD revision of the given file at that moment in time, but that reference will be out of date as soon as more commits are made to the file. Is there any way for it to fetch the current HEAD (whatever that revision happens to be), rather than being based on the revision that was at the HEAD when the rev-parse was called?

    Does that make sense?

    Cheers mate.

    • Instead of supplying a sha I think you can just say “master”. Let me know if that works.

      • Sorry, I should have come back to this sooner James. I tried that and it didn’t. For my situation the file I’m linking to changes very infrequently, and as it’s my own repo, I know when it happens so can just redo the SHA as needs must.

        Cheers again for a really helpful article mate.