Adding DISQUS to Hakyll posts

λ June 21, 2019
Tags: hakyll

I am sure there cooler ways of doing it in site.hs using metadata tags but alas, not being that familiar with Hakyll that much, after a few frustrating hours, I just wanted to get DISQUS integrated and get on with life.

The full instructions can be found on the Disqus site and they form the basis of my solution so maybe reading that page first might be useful.

After a little bit of exploratory hacking I arrived at a solution which uses a custom partial template and a little bit of JavaScript code in that template to make sure that the DISQUS engine gets the two bits of food it needs:

  • the page URL
  • a unique page identifier

Presumably these two bits of information are used so that the correct thread can be created / loaded on the page and keep it distinct from all other pages. That means that just using JS code I needed to get the live page URL and then I use that to create a unique identifier.

Step 1: The template.

There are a couple of parts, first I created a new template in the templates folder, I called it ./templates/disqus.html (seemed like a good choice) and it contains the stock manual installation code from the DISQUS site but slightly modified for my purposes:

<div id="disqus_thread"></div>
<script>
var disqus_config = function()
{
  var clean = window.location.pathname.replace(/-/g, '').replace(/\//g, '');
  var parts = clean.split('.');
  this.page.url = window.location.href;
  this.page.identifier = parts[0];
};
</script>

This was saved in ./templates/disqus.html as stated before. What it does is copy the current page URL into the this.page.url slot and then replaces all of the hyphens and forwards slashes from the path-name part of the URL into the this.page.identifier slot, forming a nice unique name for every post you write.

Step 2: Calling the partial

To make this part of every post I write, I then edited the templates/post.html file and added this at the bottom:

$partial("templates/disqus.html")$

Step 3: The finishing touch to make it all work

On my site I have a file called sitecode.js which contains all the little bits and pieces to make my site work the way I want it to. As part of the document loading I have the “other” part of the DISQUS code:

$(document).ready(function() {
  var disqus = document.getElementById("disqus_thread");
  if (null != disqus) {
    var script  = document.createElement('script');
    script.type ='text/javascript';
    script.src  = 'https://monadicwarrior.disqus.com/embed.js';
    script.setAttribute('data-timestamp', +new Date());
    document.body.appendChild(script);
  }
);

This is the magic sauce, applied when the document has loaded. It triggers the creation of a new script tag that pulls in the DISQUS code and then searches out for that DIV tag we placed into the template, disqus_thread.

As you can see below, we even have it on this page too, use the browser inspector if you like to see how it all worked out.

Comments