Skip to content

Commit

Permalink
No Ticket : Add current version of comment-section.html
Browse files Browse the repository at this point in the history
  • Loading branch information
jdvp committed Sep 24, 2021
1 parent 9b752cc commit 82b36b2
Show file tree
Hide file tree
Showing 2 changed files with 276 additions and 1 deletion.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
# jekyll-comments-google-forms
Files necessary to add comments to Jekyll through use of Google Forms: https://jdvp.me/articles/Google-Forms-Jekyll-Comments

Files necessary to add comments to Jekyll through use of Google Forms.

To see how to use this file in your Jekyll project, take a look at this article I wrote: [Using Google Forms for Jekyll Comments]

[Using Google Forms for Jekyll Comments]: https://jdvp.me/articles/Google-Forms-Jekyll-Comments
270 changes: 270 additions & 0 deletions comment-section.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
{% if site.comment-read %}
<!-- Load Required 3rd-Party Scripts. We use the following:
* jquery for DOM manipulation
* jquery-csv for parsing Google Sheets CSV data to JSON
* validator for escaping user-entered comments to prevent malicious code input in comments
Make sure to update these to the latest versions every once in a while.
-->
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/jquery-csv/1.0.11/jquery.csv.min.js"
integrity="sha512-Y8iWYJDo6HiTo5xtml1g4QqHtl/PO1w+dmUpQfQSOTqKNsMhExfyPN2ncNAe9JuJUSKzwK/b6oaNPop4MXzkwg=="
crossorigin="anonymous"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/validator/13.5.2/validator.min.js"
integrity="sha512-vZEoK8xRncku4g5GANHh5zobUjeCMbZkSEahrADeAcRlk/1Ignf8sAKojkV4RZLkPw145+ILJFisI2pnjsPtGQ=="
crossorigin="anonymous"></script>

<!-- Our own JS starts here-->
<script>
var thisPageUrl = "{{ include.url }}";
var visibleComments = [];

/* Format the comment's date to our desired format */
function formatDate(stringDate) {
var date = new Date(stringDate);
var dateOptions = { year: 'numeric', month: 'long', day: 'numeric'};
var timeOptions = { hour: 'numeric', minute: 'numeric' };
return `${date.toLocaleDateString("en-us", dateOptions)} at ${date.toLocaleTimeString("en-us", timeOptions)}`;
};

/* Called when the comments have been loaded or relaoded.
Comments that we have already displayed on the page will be ignored */
function displayComments(comments) {
/* if we have no comments, show the 'no comments available' section */
if (comments == null || comments === "") {
if (visibleComments.length == 0) {
$("#no-comments").show();
}
return;
}

/* Add headers so json objects are named properly */
comments = `timestamp,name,comment,isAuthor\n${comments}`;
commentList = $.csv.toObjects(comments);

/* iterate over each comment that came from Google Sheets */
commentList.forEach(function(element) {
/* don't re-add existing comments */
if (visibleComments.includes(JSON.stringify(element))) {
return;
}

/* If the author was the one who commented back, add this 'verified' logic */
var verifiedAuthorTag = "";
if (element.isAuthor === "TRUE") {
verifiedAuthorTag = "&nbsp;<strong>(Author)</strong>";
}

/* Create the new item using HTML and append it to the user-visible comment section */
var newItem = $(`
<div class="comment-item">
<p class="commenter-name">${validator.escape(element.name)}${verifiedAuthorTag}<small>${formatDate(element.timestamp)}</small></p>
<div>
<p>${validator.escape(element.comment).replace(new RegExp('\r?\n','g'), '<br />')}</p>
</div>
</div>
`).hide();
$("#commentSection").append(newItem);
newItem.fadeIn();
visibleComments.push(JSON.stringify(element));

/* Hide the 'no comments available' section since we have added a comment */
$("#no-comments").hide();
});
};

/* Calls to the Google Sheets gviz API to load the comment data
Since we are storing comments for all of our blog articles in one sheet, we filter
by page URL. */
function reloadComments() {
/*
Use SQL in the gviz URL to load the correct csv.
In this implementation, columns are mapped to the following:
A - timestamp, the time the comment was left
B - page url, the page the comment was left on
C - name, the text left in the comment name field
D - comment, the text left in the comment field
E - isAuthor, boolean indicating if the comment was left by the actual author
*/
var sqlStatement = encodeURIComponent(`SELECT A, C, D, E WHERE B = '${thisPageUrl}'`);
fetch(`{{ site.comment-read }}/gviz/tq?tqx=out:csv&sheet=comments&tq=${sqlStatement}&headers=0`)
.then(response => response.text())
.then(response => displayComments(response));
};

/* Reload the comments when the page first loads */
reloadComments();

/* encodes the form data for http transport */
const encodeFormData = (data) => {
return Object.keys(data)
.map(key => encodeURIComponent(key) + '=' + encodeURIComponent(data[key]))
.join('&');
};

/* Posts a comment */
function postComment() {
var username = $("#comment-name").val();
var comment = $("#comment-comment").val();

fetch(`{{ site.comment-post }}/formResponse`, {
method: 'POST',
mode: 'no-cors',
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: encodeFormData({
"{{ site.comment-post-fields[0] }}" : thisPageUrl,
"{{ site.comment-post-fields[1] }}" : username,
"{{ site.comment-post-fields[2] }}" : comment
})
}).then(response => {
$("#comment-name").val('');
$("#comment-comment").val('');
reloadComments();
})
.catch(error => {console.log(error);});

return false;
};
</script>
<!--
HTML for displaying the actual comment section.
It has a state for oth when the article has comments and when it does not.
-->
<h4 class="post-subtitle">Comments</h4>
<div id="commentSection" class="comments">
<div id="no-comments" class="post-info">
<p>There are currently no comments on this article, be the first to add one below</p>
</div>
</div>
<h4 class="post-subtitle">Add a Comment</h4>
<div class="comments">
<div class="post-info">
<p>Note that I may remove comments for any reason, so try to be civil. If you are looking for a response to your comment, either leave your email address or check back on this page periodically.</p>
</div>
<div class="comments-form">
<form onsubmit="return postComment()" id="comment-form" autocomplete="off">
<ul>
<li><input id="comment-name" name="username" type="text" placeholder="Name" required="" value=""></li>
<li><textarea id="comment-comment" name="comment" placeholder="Comment" required=""></textarea></li>
<li><input id="comment-submit" type="submit" value="Post"></li>
</ul>
</form>
</div>
</div>
<!--
Styling information.
This might typically be in an scss file but is added here so only a single
file needs to be added to a project trying to implement this feature.
-->
<style>
@import url("https://fonts.googleapis.com/css?family=Source+Sans+Pro");
.comment-item {
position: relative;
padding: 0.5em 2.5em;
background: white;
font-family: "Source Sans Pro", sans-serif;
width: 95%;
margin: 1em auto;
box-shadow: 0px 0px 2px 2px rgba(0, 0, 0, 0.1);
border-radius: 8px;
}
.comment-item:after {
content: "";
position: relative;
display: block;
clear: both;
}
.comment-item p {
line-height: 1.6;
}
.comment-item small {
padding-left: 0.7em;
color: #999;
font-size: 0.8em;
}
.commenter-name {
color: #367588;
text-decoration: none;
font-size: 1em;
font-weight: 700;
}
.commenter-name strong {
color: #e91e63;
text-decoration: none;
font-size: 1em;
font-weight: 700;
}
.comments {
border-top: 0.5px solid #e5e5e5;
padding-top: 1rem;
position: relative;
}
.comments-form {
margin-left: 1em;
margin-right: 1em;
width: 95%;
font-family: "Source Sans Pro", sans-serif;
}
.comments-form ul {
list-style: none;
margin-left: -40px;
}
.comments-form ul li {
margin-bottom: 15px;
}
.comments-form ul li input[type='submit'] {
border: 0;
border-radius: 8px;
padding: 10px 10px;
background: #9ccc65;
color: #fff;
font-family: "Source Sans Pro", sans-serif;
font-weight: bold;
font-size: 0.9em;
text-transform: uppercase;
margin-bottom: 20px;
width: 25%;
outline-style: none;
}
.comments-form ul li input[type='text'], .comments-form ul li textarea {
width: 50%;
padding: 10px;
border: 0;
border-radius: 8px;
background: #f7f7f7;
font-family: "Source Sans Pro", sans-serif;
}
.comments-form ul li input[type='text']::-webkit-input-placeholder, .comments-form ul li textarea::-webkit-input-placeholder {
font-family: "Source Sans Pro", sans-serif;
}
.comments-form ul li input[type='text']::-moz-placeholder, .comments-form ul li textarea::-moz-placeholder {
font-family: "Source Sans Pro", sans-serif;
}
.comments-form ul li input[type='text']:-ms-input-placeholder, .comments-form ul li textarea:-ms-input-placeholder {
font-family: "Source Sans Pro", sans-serif;
}
.comments-form ul li input[type='text']::-ms-input-placeholder, .comments-form ul li textarea::-ms-input-placeholder {
font-family: "Source Sans Pro", sans-serif;
}
.comments-form ul li input[type='text']::placeholder, .comments-form ul li textarea::placeholder {
font-family: "Source Sans Pro", sans-serif;
}
.comments-form ul li input[type='text']:focus, .comments-form ul li textarea:focus {
background: #fff;
font-family: "Source Sans Pro", sans-serif;
}
.comments-form ul li textarea {
width: 100%;
height: 80px;
resize: vertical;
min-height: 80px;
}
</style>
{% endif %}

0 comments on commit 82b36b2

Please sign in to comment.