/assets/img/2019-07-17_commento-count_1-640.png

Commento: Display number of comments

tl;dr: We can create a simple Javascript to get the number of comments for a post using Commento’s /api/comment/count API and then display the number inside a HTML element.

Contents

Now that we’ve installed Commento and integrated it into our blog, I’d like to give you a small example of how to use the API.

/api/comment/count API

Commento provides the /api/comment/count endpoint to show the number of comments made to a post.

To this endpoint you give the domain and an array of paths for which you want to receive the number of comments.

{
  "domain": "localhost:3000",
  "paths": ["/post-1/", "/post-2/"]
}

It then returns an object with all pages:

{
  "commentCounts": {
    "/post-1/": 0,
    "/post-2/": 1
  },
  "success": true
}

You can further explore this with Postman1 or curl:

curl -X POST \
  http://localhost:8080/api/comment/count \
  -H 'Content-Type: application/json' \
  -d '{
  "domain": "localhost:3000",
  "paths": [
    "/post-1/",
    "/post-2/"
  ]
}'
/assets/img/2019-07-17_commento-count_1-640.png

Commento.io: count.js

The Commento documentation also contains an example2 for the use of this API, namely the display of links including the number of comments submitted.

The script count.js3 is used and all links that correspond to a certain scheme are rewritten:

<a href="https://example.com/foo#commento"></a>

will be rewritten to

<a href="https://example.com/foo#commento">12 comments</a>

Custom count.js

For this use-case I want to replace the content of a span element in the post’s head with the number of comments.

The span is identified by the id post__comment-js and the content is only replaced, if Commento provided a valid response.

Since we were there anyway we can also workaround the Commento bug #173 (commentCount off-by-one)4.

First we need to add some information about the Commento instance into our HTML content, I suggest to add data-comments-url to your body. If you only want to display comments on specific pages (e.g. Posts), you can add an additional check here and don’t write out the url in this case.

{{ if and (eq .Type "posts") (isset $.Site.Params.comments.commento "host") }}
<body data-comments-url="{{ $.Site.Params.comments.commento.host }}">
  {{ else }}
  <body>
    {{ end }}
  </body>
</body>

We will then use this property inside the Javascript to reach the correct Commento instance:

/**
 * Call api and then display the result
 */
function initCount(countSpan) {
  const commentsUrl = document.body.dataset.commentsUrl;
  if (commentsUrl) {
    const data = getPostData();
    const request = new XMLHttpRequest();
    request.open("POST", `${commentsUrl}/api/comment/count`, true);
    request.send(JSON.stringify(data));

    request.onload = () => {
      if (request.status === 200) {
        displayCount(countSpan, request.response);
      }
    };
  }
}

/**
 * Display count from response
 */
function displayCount(countSpan, countResponse) {
  try {
    const responseJson = JSON.parse(countResponse);
    if (!responseJson.success) {
      return;
    }
    // fixes off-by-one https://gitlab.com/commento/commento/issues/173
    let count;
    if (typeof responseJson.commentCounts[location.pathname] === "number") {
      count = responseJson.commentCounts[location.pathname] + 1;
    } else {
      count = 0;
    }
    countSpan.textContent = `${count} ${count === 1 ? "comment" : "comments"}`;
  } catch (ex) {
    // do nothing
  }
}

/**
 * Build the POST data object for the API
 */
function getPostData() {
  return {
    domain: location.host,
    paths: [location.pathname]
  };
}

document.addEventListener("DOMContentLoaded", function() {
  const countSpan = document.getElementById("post__comment-js");
  if (countSpan) {
    initCount(countSpan);
  }
});

Footnotes

Tags

Comments

Related