When I set out to come up with a cool design for my site, I wasn’t really sure what I was shooting for. I just downloaded Twitter Bootstrap and went to work throwing DIVs around. I’m pretty happy with how it came out, but one part that I really like a lot is the GitHub feed you see in the right hand column. I haven’t ever seen a site with one and there weren’t any tutorials on how to make one, so I figured I’d jump right in.
From my GitHub profile, I could see that there was an easy way to pull an RSS feed of my Public Activity, so I figured I’d start there. Clicking the icon returns an Atom feed with a lot of (unnecessary, in my opinion) mark-up. The DOM for a single push looked like this:
1 2 3 4 5 6 7 8 9 10 11 12 13
That’s a lot of divs for a simple display that was going to be a pain in the ass to style. I was a little disappointed and the thought of trying to parse it with regex sounded miserable(on a related note, is there a decent DOM parser for CF?). I remembered that Twitter will give you your activity stream in different formats by specifying them in the URL, a la http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=theseanwalsh. I decided to give it a shot and change the URL I was pinging to https://www.github.com/s992.json instead of s992.atom. Lo and behold, it worked! I had something to start with…
Reading over the JSON that was returned, it quickly became apparent that I was not going to be able to just take what GitHub gave me and loop over it unless I wanted a lot of logic in my view. Each “event” – Push, Pull, Fork, Follow, Watch, etc. – had a slightly different JSON structure. Well, I love writing cfscript and I love writing components, so I figured I’d try my hand at writing a component to parse the JSON into a more usable format.
For each item that I wanted to display, I knew I wanted to follow the same general format: [actor] did [action] to [target]. The date, URL, and repository description or commit message wouldn’t hurt either. So, I got to work.
The first thing I needed to do was make the request to GitHub and turn that into some JSON:
1 2 3 4 5 6 7 8 9 10 11 12
This code is pretty self explanatory. Once I had the JSON, I needed to mold it into something that I was ready to use in my view, so I wrote a method to loop over it and call some other methods depending on the type of event that GitHub said it was.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
I played around with the idea of dynamically making the method calls(and getting rid of that ugly switch/case block) by using evaluate, but I don’t have a comprehensive list of the potential events – meaning that if GitHub tosses me an event that I haven’t written a method for, I’ll get a big ugly CF error due to a missing method. If anyone can suggest a better way to do this, I’m all ears! You’ll also see that I keep two counters – one for the loop through the JSON and another that counts how many items I’ve actually put into my returned array. The reason for this is that if I hit an event that I haven’t accounted for, I will end up with a struct that is missing some keys.
Each method called is pretty similar(and you can check out the full CFC by hitting the download link at the bottom of the post), so I’ll just give an example of one of them – handlePushEvent:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
If you’re still paying attention, you’ll notice that I make a call to buildArrayForMultipleCommits() in there. The reason for this is that GitHub passes all commits for a specific event in an array. There is a lot of stuff in there I don’t care about, like the SHA, the author e-mail, and the author name – all I care about is the commit message right now. So, I just loop over the array and return an array that only has the commit messages:
1 2 3 4 5 6 7 8 9 10
Alright, we’re ready to go! Now all I have to do in my view is grab the “clean” JSON and loop over it, formatting it how I want it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
I’ve uploaded the CFC as well as my Mura display object to GitHub, so please feel free to check it out and give me some feedback! You can find it at https://github.com/s992/github-feed-widget