Dynamically replacing Gists with raw content for jQuery Mobile

This post is more than 2 years old.

I've recently begun making uses of Gists to host my code blocks. I like the formatting - I like that folks can take the code and fork it - I just like it in general. Plus, all the cool kids are using it so why shouldn't I? However, I realized yesterday that the Gist embeds were not working on my mobile site. Why? Let's look at a simple example and it will soon make sense.

Consider the following simple jQuery Mobile page:

It's a one page template with an embedded Gist as well. Notice the two links at the bottom. If we open this up it will work just fine. Your browser sees the script tag and executes it. You can test this yourself here (but don't try the buttons just yet):


Now - let's look at the first page, the one I called testa.cfm. This page is "faking" dynamic content with some static text on top that is then output within our page. While I'm using ColdFusion to demonstrate that, please note this is not a ColdFusion issue.

If you were to click the first button, you will see the page load, but no gist will show up:

What happened? jQuery Mobile uses Ajax to load in your additional pages. When Ajax is used to load content and it includes a script block like that, it is not executed. This isn't jQuery Mobile issue - it's just how Ajax calls like are going to work. We could get around this by telling jQuery Mobile to not use Ajax for its link - that's super simple too: <a href="something.html" data-ajax="false">. But that felt wrong to me.

So I began thinking of a solution. First - I discovered that the Gist service has an API: Gists API. This API allows you to fetch the raw content of a Gist along with other metadata. I now had a conundrum. Do something client-side or server-side? While I figured I could do it client-side, something told me it made sense to handle this on the server instead. It would let me have a server-wide cache and possibly do other manipulations to make the content more appropriate for a mobile platform. I'm not sold on this needing to be server-side.

My solution then was rather simple. Given an input, we could use a regular expression to look for Gist embeds. For each we find, perform a HTTP call to the API to fetch the raw content and embed that into the document instead.

Obviously the additional HTTP call will be expensive. With that in mind I decided to employ caching. This is another good solution for the server as anyone who hits the page after the first user will also get the benefit of the cached version. This does - of course - mean that if the Gist is updated the cache will be stale. For simplicity's sake I'm just going to not worry about that now.

Here is my solution. It's ColdFusion-based, but simple enough that anyone could rewrite this in PHP, Ruby, etc.

If we take it step by step, you can see the regex used to find gists. I then loop over them (backwards because it is possible a gist may include an example of a gist, this blog post does!) and do some simple replacements. If the raw data isn't cached, we perform a HTTP request and cache the result after processing the JSON. This really needs some try/catches though. Finally - we wrap the result in some pre tags (which you customize) and insert it into the original string. Here's an example of a jQuery Mobile page making use of this API.

You can test this by going back to my demo and trying the "Good" demo.

Thoughts? As just an FYI, this is not being used on my mobile site yet. I'm hoping my readers provide some feedback to let me know how well this works (or doesn't).

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Chris Blackwell posted on 4/15/2012 at 10:53 AM

I'be had this issue too, bit rather than parse the gist, which might break if github change the format, I decided to render it using a js engine on the server.

The source is on github naturally - https://github.com/d1rtym0n...

Comment 2 by Raymond Camden posted on 4/16/2012 at 12:25 AM

Interesting - I have to ask though why you use Rhino? Since all Gist is doing is nicely dropping in text, isn't that overkill to replicate?

Comment 3 by ChrisBlackwell posted on 4/16/2012 at 5:32 PM

Yeah i guess it might be slightly overkill, but when i was thinking about how to aproach the problem i had one of those "hey, you know whada be cool" moments and just ran with it.

I've just updated the project so that it caches the final html, rather than js, that removes the need to use rhino at all apart form the first request, although in my unscientific F5 testing the rhino portion of the code executes in ~5ms, so it really isn't that big an overhead.

Comment 4 by Raymond Camden posted on 4/16/2012 at 6:00 PM

Some of my best code experiences have come from "know what would be cool?" - hope I didn't sound too negative. ;)