How to Display W3C Specification data using its Web API

The Emmy® award winning W3C is an international standards organization for the World Wide Web. It creates new web standards and revises them constantly to keep them consistent and relevant across the globe.

Browsers and websites have become standard compliant to a greater extent with time, this allows websites to render and work uniformly across all the various browsers. One of the most useful resources publicly available is the W3C Specification documentations in w3c.org.

Recently W3C made its data available through a Web API, the project page of which is in Github. The intro of this API from its project page is as follows:

“In response to demand from developers in our community wanting to interact with W3C’s data, the W3C Systems Team has developed a Web API. Through it we are making available data on Specifications, Groups, Organizations and Users.”

In today’s post we’ll see how to fetch the Specification data through the W3C API. You’ll find the various requests you can post to fetch the Specification data and others in https://api.w3.org/doc, it also comes with a sandbox for each request to test the API, but you’ll need an API key.

Let’s first see how to get the API key.

  1. Login to your W3C account or create one.
  2. Then go to Manage API Keys in your profile page.
  3. Click New API Key and give it a name to generate your key.
  4. Then if you wish, you can copy-paste it into the api key textbox at the beginning of the webpage https://api.w3.org/doc to test the API in the sandbox.

For this post, we’ll look into the request that uses shortnames to display the Specification URL, description and document status. The request looks like this:

https://api.w3.org/Specifications/{shortname}?apikey={apikey}&_format=json

For example, an HTML5 spec request will be like this;

https://api.w3.org/Specifications/html5?apikey={apikey}&_format=json

Now, let’s focus on the HTML we’ll use to display the data fetched through the API. For this I’ve decided to use HTML Template. HTML templates are used to hold HTML code that are parsed but not rendered until they’re added to the page using JavaScript.

<div id="w3cSpecs">
    <h1>W3C SPECS</h1>
</div>

<Template>
    <div class="w3cSpec">
        <h2 class="w3cSpecHeader"></h2>     
        <h3>URL</h3>
        <a class="w3cSpecLink"></a>
        <h3>Description</h3>
        <div class="w3cDescription"></div>
        <h3 >Latest Version Status</h3>
        <mark class="status"></mark>
    </div>
</Template>

The template is ready. Now, onto the JavaScript that’ll be making the HTTP request and displaying the response JSON data in HTML. Here’s the set of global variables we’ll start with:

var shortnames = ['html5','selectors4','battery-status','fullscreen'],
    xmlhttp = new XMLHttpRequest(),
    w3cSpecsEle = document.querySelector('#w3cSpecs'),
    templateEle = document.querySelector('Template');

shortnames is an array of shortnames of the Specifications we want to display in our webpage; if you want to find the shortname of a Specification look at its W3C URL and you’ll be able to see it at the end.

However, it isn’t guaranteed that you’ll be able to get all Specifications like this; there isn’t a definitive list of shortnames and Specifications that are available through the API yet.

Loop through the shortnames array and post a HTTP request for each, and fetch the response.

for (var i=0;i<shortnames.length;i++){
    xmlhttp.open('GET', 'https://api.w3.org/Specifications/'+shortnames[i]+'?apikey={your-api-key}&_format=json', false);
    xmlhttp.send();
    xmlhttp.onreadystatechange = checkRequestState();
}

function checkRequestState(){
    if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
        var jsonResponse = JSON.parse(xmlhttp.responseText);
        displaySpec(jsonResponse)
    }
}

The responseText is a JSON string and has to be parsed to get the JSON object. displaySpec is the function that’ll use the JSON data and display it in HTML.

Below is the sample JSON response text for HTML5 Specification and after the code for displaySpec.

W3C API JSON
function displaySpec(json){
    if ('content' in templateEle) {
        /* get Template's content */
        templateEleContent = templateEle.content;
        /* add spec title to h2 header */
        w3cSpecHeader = templateEleContent.querySelector('.w3cSpecHeader');
        w3cSpecHeader.textContent = json.title;
        /* add spec URL to the link  */
        w3cSpecLink = templateEleContent.querySelector('.w3cSpecLink');
        w3cSpecLink.textContent = json.shortlink;   
        w3cSpecLink.href = json.shortlink;      
        /* add spec description */
        w3cSpecDetail = templateEleContent.querySelector('.w3cDescription'); 
        w3cSpecDetail.innerHTML = json.description;
        /* add spec status and color it based on its value */
        W3cSpecLatestVerStatus = templateEleContent.querySelector('mark');
        var status = json._links["latest-version"].title;
        W3cSpecLatestVerStatus.textContent = status;
        switch(status){
            case 'Recommendation':
                W3cSpecLatestVerStatus.className = "recommendation";
                break;
            case 'Working Draft':
                W3cSpecLatestVerStatus.className = 'draft';
                break;
            case 'Retired':
                W3cSpecLatestVerStatus.className = 'retired';
                break;
            case 'Candidate Recommendation':
                W3cSpecLatestVerStatus.className = 'candidateRecommendation';
                break;
        }
        /* add copy of the Template's content to the main div */
        w3cSpecsEle.appendChild(document.importNode(templateEleContent, true));
    }
    else {/* add JS code to create the elements individually */ }
}

if ('content' in templateEle) is to check if HTML Template is supported by the browser, if it isn’t, create all the HTML elements in the JS itself. And when there’s support, fill the HTML elements that are inside the Template’s content with the respective data from JSON and finally, append a copy of Template’s content to the main #w3cSpecs div.

That’s it. With a bit of CSS stylings, the output looks like this:

W3C API Output