StackUnderflow.js: A JavaScript Library and Mashup Tool for StackExchange

StackUnderflow.js is a JavaScript library that lets you retrieve – and render – questions from the StackExchange API directly on your website just by including a simple, lightweight .js script.

The library is fully documented, so for technical details please check out the StackApps entry for it, and follow the links to the GitHub repository. The rest of this post is about my motivation for the library, how I am using it on the blog, and some other thoughts about the API.

StackExchange (e.g. StackOverflow) has recently published an API (still in beta). It’s not very often that such a rich source of data suddenly becomes accessible. So it got me a little excited about all the possibilities. I think the full set of possibilities has yet to be realized, even by the rapidly growing set of entries in the StackExchange API Contest. Like most new things, it takes time. Plus, the API is currently read-only, but it seems they have plans to add write support in the future. Now that will be interesting. An idea for utilizing that in a novel way just popped into my head, just now.

Anyway – one thing I have noticed over the last few years is just how much StackOverflow.com has grown as a referrer to this blog. There’s an untold number of SO questions thank here as a reference. StackOverflow is consistently one of my top referrers. I joked once that my SO rep is grossly understated, for credit for all those answers, I get not.

Searching for “InfinitiesLoop” on StackOverflow returns over 100 results:

http://stackoverflow.com/search?q=infinitiesloop

So the first thought I had for utilizing the API is to bring those questions directly to this blog. I want readers to be able to see the SO questions that link to my blog in general, or to each individual blog entry. The nature of my blog entries are such that most of my referrers are from Google searches, people looking for answers to problems they have. It’s only natural to try and bring two sources that are very likely to help together, is it not? It’s a perfect marriage if you ask me!

Searching with the StackExchange API

As always seems to be the case, as soon as I start dipping my feet into some new technology, I immediately discover that what I want to accomplish is beyond its limitations. Fooey.

The StackExchange API does not support searching the body or answers of a question, only the tags and the title.

The reason stated is for performance – they suggest you use a proper search engine to look for questions by their content instead. That makes sense, I guess. Why reinvent the wheel, Google and the like are more than capable. The way you do it is pretty simple. All StackExchange questions are found under the “/questions” url, and you can restrict matches to that url. Here’s a Google search that finds all questions linking here:

http://www.google.com/search?hl=en&q=site:stackoverflow.com/questions+weblogs.asp.net/infinitiesloop

You’ll see in the results that all the urls look like this:

http://stackoverflow.com/questions/questionid/title

Ah ha – so doing this I can get the question IDs!

Abstracting it Away

So, the first thing I did was work around this limitation by utilizing an AJAX Google search to find the questions, then the StackExchange API to retrieve the questions. There’s two disadvantages to that: (1) The Google API I’m using is one that limits results to 8 per request, and (2) We must now perform at least two requests to get the data. But I think these disadvantages are no biggie – it wouldn’t be common to find more than 8 questions for one article, and even if there were, the top 8 results should be very relevant, and I don’t necessarily want to bombard you with every result anyway. And the added delay is no biggie – it’s still very fast, and this content is intended to be shown as a sort of ‘extra’ part of the site, which will silently load while the user is focusing on the main content.

Rendering the Questions/Data

Of course I fully anticipate there to be a very rich JavaScript API wrapper for StackExchange. I would love if StackUnderflow.js turned into one (hey, it’s open source). But there’s too many people out there that are smarter and have more time than me, so I doubt it. There’s already one posted that is automatically generated from the robust StackExchange API help.

Cool, but I hope these libraries realize that almost as important as getting the raw data is getting it onto the page. So StackUnderflow.js not only lets you get raw data, but has a built-in ability for rendering it, too. Rendering it in the familiar StackExchange way. Currently, it only supports rendering questions, but I intend on adding answers, comments, badges, etc, as well.

It also lets you customize the rendering via a very simple templating engine (by no means meant to be a generic templating engine, but more than adequate for what is needed here), and you can of course customize the CSS, or do both.

How I am Using It

This blog is hosted on Community Server from who-knows-who. I was fortunate to get this blog as a virtue of being a Microsoft employee (although I think its more open now). It sure has done wonders for my readership compared to when I had it on blogger. But this means I only have a little bit of control over it. One day I dream I’ll host it myself and thus have complete control over it, but for now, I’m stuck here.

The dashboard for this blog lets me enter any HTML, even script, into the ‘news’ section, which appears on the left navbar. The blog entries themselves all live under a <div> with id “content2”. I want whatever page the user is on to show StackOverflow pages linking to it. If they are on the main page, that will mean any and all links. If they are looking at the specific page for a blog article, it will mean links to that article only.

Some of the lines may wrap horribly – expand your browser if you can (ahemipadahem).

<link type="text/css" rel="Stylesheet" href="http://infinity88.com/stackunderflow/stackoverflow.css" />

<script type="text/javascript" src="http://infinity88.com/stackunderflow/stackunderflow-1.0.0.min.js"></script>

<script type="text/javascript">

stackunderflow.googleQuestions(null, function(questions) {

    if (questions.questions.length) {

        var content = document.getElementById("content2");

        var header = document.createElement("h3");

        var msg = (document.location.toString().toLowerCase() === "http://weblogs.asp.net/infinitiesloop/")

            ? 'Some <a href="http://stackOverflow.com">StackOverflow</a> questions that link to this BLOG...'

            : 'Some <a href="http://stackOverflow.com">StackOverflow</a> questions that link to this ARTICLE...';

        header.innerHTML = msg + " <br/><span style='font-size:8px'>(powered by <a href='http://github.com/infinitiesloop/stackunderflow.js'>StackUnderflow.js<a/>)</span>";

        content.appendChild(header);

        stackunderflow.render.questions(questions, "#content2");

    }

});

</script>

This code isn’t the prettiest – this is by no means meant to be something you copy and paste into your blogs. First of all, my blog being out of my control already does horrible things on the client side that I hate. Don’t treat your blog that way :)

The code to focus on is the included script, stylesheet, the ‘googleQuestions’ API, and the ‘render.questions’ call. Actually, it supports a shorter chaining syntax, which you’ll see in the readme on github. Note that in the call to ‘googleQuestions’ I pass null as the search term. The library uses the current page URL by default if you don’t provide one. Being in the side bar, this code appears on every page. So it will always show links to the page you are on. You could if you wanted make it more specific than that or include keyword, etc.. basically, anything you might Google for.

The ‘content2’ div is appended to (the library takes care of waiting for DOMContentLoaded, etc, for you). And since I haven’t specified a template to use, the default one is used, which uses a similar HTML structure that StackOverflow.com itself uses to show question summaries. It also uses a certain set of CSS classes, hence the link to the stylesheet. The classes aren’t the same as StackOverflow.com though – they’ve been modified to (1) be more uniquely named by having a ‘se-‘ prefix, and (2) only apply to content within the dynamically rendered content so it can’t possibly mess with the rest of your page.

Just look at the bottom of my main page to see it in action, and then try some of my popular articles like Truly Understanding ViewState.

I have lots of ideas for improving it, not the least of which is the ability to show all questions from a certain user, so you could show a list of your own questions, and filtering of those questions (e.g. only unanswered ones). But mostly I hope people pick up an interested in the project and contribute to it via GitHub!

Enjoy!

No Comments