Automatic publication page

Jun 01, 2020

I have a pub­li­ca­tion page where my pub­li­ca­tions are dis­played. Since I don’t have many pub­li­ca­tions cur­rently, it is pretty easy to just man­u­ally list each pub­li­ca­tion in a mark­down or di­rectly in HTML. However, it can be­come te­dious and er­ror-prone once there is a large num­ber of pub­li­ca­tions. And what if I want to ma­nip­u­late how to dis­play them? The process can be­come la­bor in­tense. So I do it au­to­mat­i­cally. Here is how I do it.

The ex­am­ple shown here is writ­ten in JavaScript, but the codes should be eas­ily rewrit­ten in Python as well.

Get bib­li­o­graphic meta­data from DOI #

To make the process as au­to­matic as pos­si­ble, I use DOI as a sin­gle en­try point. Each pub­li­ca­tion has a unique DOI as­so­ci­ated with it and it can be used to get the in­for­ma­tion of the pub­li­ca­tion. For in­stance, https://​www.doi2bib.org/ can give you a BibTeX en­try from a DOI (I use this site a lot). The BibTeX en­try con­tains in­for­ma­tion like ti­tle, au­thors, jour­nal, year, etc which I would like to pop­u­late into the HTML.

Suppose I store an ar­ray of DOI in a file called DOI.json. What I would like to have is to loop through the list, find the bib­li­o­graphic meta­data of each DOI, and re­turn the re­sults in a read­able for­mat (preferably JSON). To do this, first I need to have a method to gen­er­ate bib­li­o­graphic meta­data pro­gram­mat­i­cally.

DOI Content Negotiation #

Fortunately, doi.org pro­vides a nice con­tent ne­go­ti­a­tion API to query meta­data as­so­ci­ated with a DOI. Following the doc­u­men­ta­tion, it is pretty straight­for­ward to write the core logic to do it,

// function to query the bibliographic metadata
async function getBib(doi) {
  const respose = await axios({
    url: "https://doi.org/" + doi,
    headers: {
      Accept: "application/vnd.citationstyles.csl+json",
    },
  });
  return response.data;
}

I use vnd.citationstyles.csl+json so that the re­sult is in CSL JSON for­mat be­cause it is sim­ple to work with. There are many other types sup­ported as well. For in­stance, you can get a BibTeX en­try us­ing application/x-bibtex in­stead of application/vnd.citationstyles.csl+json.

Incorporate into the site #

Now, I can get the data I want us­ing the method de­scribed above. How to use it to gen­er­ate the HTML page? This would vary de­pend­ing on what tools one uses to gen­er­ate the site.

I am us­ing 11ty to build my site. One of the many good things I like about it is that it al­lows me to use the data pretty straight­for­ward. The sup­ported JavaScript Data Files al­low me to sim­ply write the query logic and 11ty will au­to­mat­i­cally pick up the data, and make it avail­able in the tem­plate.

const doiList = require("./DOI.json");

module.exports = function () {
  return Promise.all(doiList.map(getBib));
};

The code lives in­side getBib.js file in­side the _data di­rec­tory. During the build, the bib­li­o­graphic meta­data re­trieved through the con­tent ne­go­ti­a­tion API will be avail­able in the tem­plate un­der the getBib key. The value is an ar­ray whose el­e­ments are the bib­li­o­graphic data for each DOI stored in DOI.json. For in­stance, if I want to dis­play the ti­tle of the first pub­li­ca­tion, I can sim­ply ac­cess it un­der getBib[0].title


It is fun to do this small cod­ing ex­er­cise. I learned a lit­tle bit about DOI along the way. For ex­am­ple, I have al­ways won­dered why click­ing a link like https://​doi.org/​10.1103/​Phys­Rev.108.171 will take me to the pub­lish­er’s site. I now know it is achieved by the so-called DOI re­solver.

Many other things can be done here. For in­stance, it would be nice to re­trieve all pub­li­ca­tions from a sin­gle ORCID iden­ti­fier. This way, I don’t even have to have a file stor­ing the DOIs. My guess is it can be done through their API.

I also found sev­eral pack­ages/​mod­ules re­lated to what I am do­ing here. I end up not us­ing these tools be­cause my goal is pretty sim­ple to achieve. But check them out be­low if you are in­ter­ested.


Other Resources #