Skip to content

Commit 437294d

Browse files
committed
add comments via mastodon toots
1 parent 8677da3 commit 437294d

File tree

7 files changed

+112
-1
lines changed

7 files changed

+112
-1
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
title: "Add Comments to Hugo Blog"
3+
date: 2021-03-23T22:19:10+01:00
4+
draft: false
5+
tags: ["note", "comment", "mastodon", "javascript"]
6+
description: "Use JavaScript to load comments from Mastodon"
7+
8+
comments:
9+
host: fosstodon.org
10+
username: ghost_letters
11+
id:
12+
---
13+
14+
After reading this [Toot from Surendrajat](https://fosstodon.org/web/statuses/105935391504191020) I wanted to add Mastodon Toots as comments. Thanks [@carl](https://linuxrocks.online/@carl) for inventing the smart comment solution and sharing the required JavaScript / Hugo integration.
15+
16+
Original source: [Adding comments to your static blog with Mastodon](https://carlschwan.eu/2020/12/29/adding-comments-to-your-static-blog-with-mastodon/)
17+
18+
If you want to see how it all comes together, check out this [git commit]().
19+

themes/ghostletters/layouts/_default/single.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ <h1>{{ .Title }}</h1>
66
<hr>
77
{{ partial "metadata.html" . }}
88
</footer>
9+
{{ partial "comments.html" . }}
910
</article>
1011
{{ end }}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{{ with .Params.comments }}
2+
<div class="article-content">
3+
<h2>Comments</h2>
4+
<p>You can use your Mastodon account to reply to this <a class="link" href="https://{{ .host }}/@{{ .username }}/{{ .id }}">post</a>.</p>
5+
<p><a class="button" href="https://{{ .host }}/interact/{{ .id }}?type=reply">Reply</a></p>
6+
<p id="mastodon-comments-list"><button id="load-comment">Load comments</button></p>
7+
<noscript><p>You need JavaScript to view the comments.</p></noscript>
8+
<script type="text/javascript">
9+
function escapeHtml(unsafe) {
10+
return unsafe
11+
.replace(/&/g, "&amp;")
12+
.replace(/</g, "&lt;")
13+
.replace(/>/g, "&gt;")
14+
.replace(/"/g, "&quot;")
15+
.replace(/'/g, "&#039;");
16+
}
17+
18+
document.getElementById("load-comment").addEventListener("click", function() {
19+
document.getElementById("load-comment").innerHTML = "Loading";
20+
fetch('https://{{ .host }}/api/v1/statuses/{{ .id }}/context')
21+
.then(function(response) {
22+
return response.json();
23+
})
24+
.then(function(data) {
25+
if(data['descendants'] &&
26+
Array.isArray(data['descendants']) &&
27+
data['descendants'].length > 0) {
28+
document.getElementById('mastodon-comments-list').innerHTML = "";
29+
data['descendants'].forEach(function(reply) {
30+
reply.account.display_name = escapeHtml(reply.account.display_name);
31+
reply.account.emojis.forEach(emoji => {
32+
reply.account.display_name = reply.account.display_name.replace(`:${emoji.shortcode}:`,
33+
`<img src="${escapeHtml(emoji.static_url)}" alt="Emoji ${emoji.shortcode}" height="20" width="20" />`);
34+
});
35+
mastodonComment =
36+
`<div class="mastodon-comment">
37+
<div class="comment_author">
38+
<img class="comment_avatar" src="${escapeHtml(reply.account.avatar_static)}" height=40 width=40 alt="">
39+
<a class="comment_display_name" href="${reply.account.url}" rel="nofollow">
40+
${reply.account.display_name}
41+
</a>
42+
${reply.created_at.substr(0, 10)}
43+
<a class="comment_reply" href="${reply.uri}" rel="nofollow">
44+
Reply
45+
</a>
46+
</div>
47+
<div class="content">
48+
<div class="mastodon-comment-content">${reply.content}</div>
49+
</div>
50+
</div>`;
51+
document.getElementById('mastodon-comments-list').appendChild(DOMPurify.sanitize(mastodonComment, {'RETURN_DOM_FRAGMENT': true}));
52+
});
53+
} else {
54+
document.getElementById('mastodon-comments-list').innerHTML = "<p>Not comments found</p>";
55+
}
56+
});
57+
});
58+
</script>
59+
<script src="/js/purify.min.js"></script>
60+
</div>
61+
{{ end }}

themes/ghostletters/layouts/partials/head.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
<meta name="viewport" content="width=device-width, initial-scale=1">
33
<link rel="stylesheet" type="text/css" href="/css/style.css">
44

5+
{{ if isset .Page.Params "comments" }}
6+
<link rel="stylesheet" type="text/css" href="/css/style_comments.css">
7+
{{ end }}
8+
59
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
610
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
711

themes/ghostletters/layouts/partials/metadata.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<div class="grid-left-right">
22
<div class="left">
33
{{ $dateTime := .PublishDate.Format "2006-01-02" }}
4-
{{ $dateFormat := .Site.Params.dateFormat | default "Jan 2, 2006" }}
4+
{{ $dateFormat := .Site.Params.dateFormat | default "2006-01-02" }}
55
Published
66
<time datetime="{{ $dateTime }}">{{ .PublishDate.Format $dateFormat }}</time>
77
</div>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
.mastodon-comment {
2+
background-color: mistyrose;
3+
padding: 8px;
4+
margin-bottom: 8px;
5+
border-radius: 8px;
6+
}
7+
8+
.comment_author {
9+
display: flex;
10+
}
11+
12+
.comment_display_name {
13+
margin-right: 8px;
14+
}
15+
16+
.comment_reply {
17+
flex-grow: 1;
18+
text-align: right;
19+
}
20+
21+
.comment_avatar {
22+
margin-right: 8px;
23+
}

themes/ghostletters/static/js/purify.min.js

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)