Comments
You can use your Mastodon account to reply to this post.
If you aren’t aware, this blog is created using Hugo. This means this blog is essentially just static files being served by a static web engine. It makes it light, and simply to host/deploy. One thing it makes it hard to do, is host comments, because comments are by nature dynamic (not static).
I came across the idea of using Mastodon a platform that is community-owned and ad-free. This allows “dynamic” comments, without me having to add a comment engine to my blog. Yay! Let’s do it!
Using the code from Carl Schwan I hacked together the following code:
{{ with .Params.comments }}
<div class="article-content">
<h2>Comments</h2>
<p>You can use your Mastodon account to reply to this <a class="link" href="https://{{ .host }}/@{{ .username }}/{{ .id }}">post</a>.</p>
<p><a class="button" href="https://{{ .host }}/interact/{{ .id }}?type=reply">Reply</a></p>
<p id="mastodon-comments-list"><button id="load-comment">Load comments</button></p>
<noscript><p>You need JavaScript to view the comments.</p></noscript>
<script src="/assets/js/purify.min.js"></script>
<script type="text/javascript">
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
document.getElementById("mastodon-comments-list").innerHTML = "Loading comments";
fetch("https://{{ .host }}/api/v1/statuses/{{ .id }}/context")
.then(function (response) {
return response.json();
})
.then(function (data) {
if (data["descendants"] && Array.isArray(data["descendants"]) && data["descendants"].length > 0) {
document.getElementById("mastodon-comments-list").innerHTML = "";
data["descendants"].forEach(function (reply) {
reply.account.display_name = escapeHtml(reply.account.display_name);
reply.account.emojis.forEach((emoji) => {
reply.account.display_name = reply.account.display_name.replace(
`:${emoji.shortcode}:`,
`<img src="${escapeHtml(emoji.static_url)}" alt="Emoji ${emoji.shortcode}" height="20" width="20" />`
);
});
let mastodonComment = document.createElement("div")
mastodonComment.classList.add("mastodon-comment")
let mastodonAvatar = document.createElement("div")
mastodonAvatar.classList.add("avatar")
let mastodonAvatarImage = document.createElement("img")
mastodonAvatarImage.src = escapeHtml(reply.account.avatar_static)
mastodonAvatarImage.height = 60
mastodonAvatarImage.width = 60
let mastodonContent = document.createElement("div")
mastodonContent.classList.add("content")
let mastodonAuthor = document.createElement("div")
mastodonAuthor.classList.add("author")
let mastodonAuthorLink = document.createElement("a")
mastodonAuthorLink.href = reply.account.url
mastodonAuthorLink.rel = "nofollow"
let mastodonAuthorName = document.createElement("span")
mastodonAuthorName.innerText = reply.account.display_name + " "
let mastodonAuthorAccount = document.createElement("span")
mastodonAuthorAccount.classList.add("disabled")
mastodonAuthorAccount.innerHTML = escapeHtml(reply.account.acct)
let mastodonCommentDate = document.createElement("a")
mastodonCommentDate.classList.add("date")
mastodonCommentDate.href = reply.uri
mastodonCommentDate.rel = "nofollow"
mastodonCommentDate.innerText = reply.created_at.substr(0, 10)
let mastodonContentComment = document.createElement("div")
mastodonContentComment.classList.add("mastodon-comment-content")
mastodonContentComment.innerHTML = reply.content
mastodonAvatar.appendChild(mastodonAvatarImage)
mastodonAuthorLink.appendChild(mastodonAuthorName)
mastodonAuthorLink.appendChild(mastodonAuthorAccount)
mastodonAuthor.appendChild(mastodonAuthorLink)
mastodonAuthor.appendChild(mastodonCommentDate)
mastodonContent.appendChild(mastodonAuthor)
mastodonContent.appendChild(mastodonContentComment)
mastodonComment.appendChild(mastodonAvatar)
mastodonComment.appendChild(mastodonContent)
document.getElementById("mastodon-comments-list").appendChild(mastodonComment);
});
} else {
document.getElementById("mastodon-comments-list").innerHTML = "<p>Not comments found</p>";
}
});
</script>
</div>
{{ end }}
By adding the following to my front matter
of each post:
comments:
host: fosstodon.org
user: utahcon
id: {{POSTID}}
I get a nice little comments section at the bottom of each of my posts, additionally I can enable and disable the
comments PER POST! That means if I don’t want to see what every Tom, Dick, and Harry has to say about a post, I simply
don’t include the above snippet in the front matter
, and boom, no comments.
The only downside, as of right now, is that I have to manually create the Mastodon post and bring the ID back here to
add into the front matter
. Ideally I would like my build agent to recognize new posts, create Mastodon posts
automatically, and then inject them into the front matter
. This might be a stretch today, but it is something to
noodle on.
With that said, if you have a solution for the build agent issue, leave a comment!