##JavaSript / Soapi.JS (V2) --- using Soapi.JS (V2) <sub>yes, this is a teaser - v2 will be released before the weekend.</sub> --- var apiKey = "my-foo-bar-fu-is-strong"; var ctx = new Soapi.ApiContext(apiKey); ctx.initialize(function() { // all available sites have been loaded from stackauth // to track loading of stats var counter = 0; // now we load the .stats property of the Site object for (var i = 0; i < ctx.sites.length; i++) { var site = ctx.sites[i]; if (!site.stats) { counter++; site.get_stats(function(data, site_as_context) { // keep the user informed document.getElementById("output") .innerHTML = "loaded stats for " + site_as_context.name; /* is it */soupYet()/*?*/; }, function(error, site_as_context) { // site sent as userContext // keep the user informed document.getElementById("output") .innerHTML = "failed to loaded stats for " + site_as_context.name; // the request failed but we must decrement the counter /* is it */soupYet()/*?*/; }, site /* as context */); }; }; // that's all the code it takes to get all sites from stackauth and // the statistics for each. More then half of it is exception handling // and progress updates. // the rest is the code to render the /sites and /stats data to HTML function soupYet(/*?*/) { // check to see if all sites have been loaded if (--counter == 0) { // dump all to table var output = "<table cellpadding='0' cellspacing='0' style='border:solid 1px silver;'> \ <tr class='header'><td>Site</td><td>State</td><td>Tags</td><td>Logo</td><td>API</td> \ <td>v.p.d</td><td>users</td><td>questions</td><td>q.p.m.</td><td>accepted</td> \ <td>unanswered</td><td>answers</td><td>a.p.m</td><td>comments</td><td>votes</td> \ <td>badges</td><td>b.p.m.</td></tr>"; for (var i = 0; i < ctx.sites.length; i++) { var site = Soapi.Domain.Site(ctx.sites[i]); output += "<tr>" + "<td><img src='" + site.icon_url + "' style='width:32px;height:32px;'/>" + "<a href='" + site.site_url + "' style='color:" + site.styling.link_color + ";' target='_blank' title='" + site.description.replace("'", "`") + "'>" + site.name + "</a></td>" + "<td class='stats'>" + site.state + "</td>" + "<td class='stats'><span style='color:" + site.styling.tag_foreground_color + ";background-color:" + site.styling.tag_background_color + ";'>[tags]</span></td>" + "<td class='stats'> <a href='" + site.logo_url + "' target='_blank'>logo</a></td>" + "<td class='stats'> <a href='" + site.api_endpoint + "/" + site.stats.api_version.version + "/help' target='_blank'>" + site.stats.api_version.version + " " + site.stats.api_version.revision + "</a></td>" + "<td class='stats'>" + Math.ceil(site.stats.views_per_day) + "</td>" + "<td class='stats'>" + site.stats.total_users + "</td>" + "<td class='stats'>" + site.stats.total_questions + "</td>" + "<td class='stats'>" + Math.ceil(site.stats.questions_per_minute) + "</td>" + "<td class='stats'>" + site.stats.total_accepted + "</td>" + "<td class='stats'>" + site.stats.total_unanswered + "</td>" + "<td class='stats'>" + site.stats.total_answers + "</td>" + "<td class='stats'>" + Math.ceil(site.stats.answers_per_minute) + "</td>" + "<td class='stats'>" + site.stats.total_comments + "</td>" + "<td class='stats'>" + site.stats.total_votes + "</td>" + "<td class='stats'>" + site.stats.total_badges + "</td>" + "<td class='stats'>" + Math.ceil(site.stats.badges_per_minute) + "</td>" + "</tr>"; }; output += "</table>"; document.getElementById("output").innerHTML = output; } }; }, function(error) { alert(error.message); }); **Output:** ![alt text][1] [1]: https://i.sstatic.net/TYfN1.png