
So, in my last article regarding building the website at my final paragraph I state that I won’t add a comments section due to possible spam.
However, over the months since that article I started to notice something… people were commenting?! How?! On my wordpress dashboard I got a notification to approve these comments. So clearly my fear of spammers was not correct as wordpress allows me to approve posts before they go out. Sure enough, I had two spammers as well.
But then I had two nice comments:

I later learned that in order for these people to do this, they must have found the wordpress backend and then made a profile and then commented. All this effort to show their gratitude? Well, much appreciated folks!
I thought recently, I shouldn’t make it so difficult for people to show their appreciation, heck, maybe people could use comments to allow them to point out mistakes, maybe give feedback on how they’ve done it differently or… well, the general nice compliment wouldn’t go amiss either :).
So this afternoon I set out to add this capability back. I started my writing a simple html to test the following functional needs:
- Can I grab comment based on article post associated with.
- Can I post a comment for an article.
For the grabbing, there was already plenty out there to help me find this, the REST API provides this ability through:
So the syntax was simple, I needed to just put in my domain, my blog area, then wp-json/wp/v2/comments?post=’ . $_GET[‘id’]
So I grab this using:
$json = file_get_contents('http://www.edward-jones.co.uk/blog/wp-json/wp/v2/comments?post=' . $_GET['id']);
$comments = json_decode($json);
You may notice this is similar to the coding style of other parts of my website, this is not by mistake, I reuse alot of my own code like examples.
I can then iterate through this returned array of data with a foreach function. I mainly used postman at this stage however to verify the functionality before much coding. I also found I can comment based on this article:
https://www.contradodigital.com/2016/04/06/post-comments-wordpress-rest-api-version-2/
Okay so that’s the two functional parts, now I needed to start creating the code. I started by just going and finding the html and css to create the form and came up with this as my form:
<div id="breaker" class='striped-border'></div>
<div id="newcomment">
<label for="fname">Your name:</label>
<input type="text" id="aname" name="aname" size="30">
<p><label for="email">Email Address:</label>
<input type="text" id="email" name="email" size="30">
<p><label for="w3review">Leave a comment:</label>
<p><textarea id="comment" name="comment" rows="7" cols="50"></textarea>
<p><div id="commentbutton"><button type="button" id="submitbutton" style="float:right;">Comment</button></div>
</div>
For my CSS for this section I used:
.striped-border { border: 1px dashed #000; width: 100%;}
#commentbutton {
}
#newcomment {
margin-top: 20px;
width:80%;
margin-left: 10%;
margin-right: 10%;
}
#comment {
display:block;
width:100%;
//height:100px;
}
button {
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
font-size: 14px;
padding: 4px 8px;
color: rgba(0, 0, 0, 0.85);
background-color: #fff;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 4px;
}
button:hover,
button:focus,
button:active {
cursor: pointer;
background-color: #ecf0f1;
}
Now for the actual comments and the actual css for that I used this article as a great example on how to setup a lovely comment section:
So, this gave me a finished up css of:
#commentsection {
width:100%;
margin-top:20px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
line-height: 1.4;
box-sizing: border-box;
}
.comment-thread {
width: 700px;
max-width: 100%;
margin: auto;
padding: 0 30px;
background-color: #fff;
border: 1px solid transparent; /* Removes margin collapse */
}
.m-0 {
margin: 0;
}
.sr-only {
position: absolute;
left: -10000px;
top: auto;
width: 1px;
height: 1px;
overflow: hidden;
}
/* Comment */
.comment {
position: relative;
margin: 20px auto;
}
.comment-heading {
display: flex;
align-items: center;
height: 50px;
font-size: 14px;
}
.comment-voting {
width: 20px;
height: 32px;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 4px;
}
.comment-voting button {
display: block;
width: 100%;
height: 50%;
padding: 0;
border: 0;
font-size: 10px;
}
.comment-info {
color: rgba(0, 0, 0, 0.5);
margin-left: 10px;
}
.comment-author {
color: rgba(0, 0, 0, 0.85);
font-weight: bold;
text-decoration: none;
}
.comment-body {
padding: 0 20px;
padding-left: 28px;
}
.comment-author:hover {
text-decoration: underline;
}
.replies {
margin-left: 20px;
}
So now the php to load the comments, I basically bundled it together to load the data into the div’s as with the article like so:
foreach ($comments as $c) {
// For each comment, print it
echo '<div id="breaker" class="striped-border"></div>';
echo '<div class="comment">';
echo ' <div class="comment-heading">';
echo '<div class="comment-info">';
echo ' <a href="#" class="comment-author">' . $c->author_name . '</a>';
echo '<p>';
echo ' • ' . $c->formatted_date;
echo ' </p>';
echo ' </div>';
echo '</div>';
echo '<div class="comment-body">';
echo ' <p>';
echo str_replace("<br />\n", " ", $c->content->rendered );
echo ' </p>';
echo ' </div>';
echo '</div>';
// echo '<div class="comment" id=' . $c->id . '>';
// echo '<div id="breaker" class="striped-border"></div>';
// echo 'Commenter: ' . $c->author_name . '<p>';
// echo 'Comment:' . $c->content->rendered . '<p>';
//echo '</div>';
}
Apologies for the lack of indenting here, using SSH to write up web code makes it a bit tricky as my server exists in the cloud on a virtual server.
Now, the final part is getting the button to post:
<script>
$(document).ready(function(){
$.urlParam = function(name){
var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href);
if (results == null){
return null;
}
else {
return decodeURI(results[1]) || 0;
}
}
$('#submitbutton').click(function() {
var author = $('#aname').val();
var comment = $('#comment').val();
var email = $('#email').val();
$.post('http://www.edward-jones.co.uk/blog/wp-json/wp/v2/comments',
{
author_name: author,
author_email: email,
content: comment,
post: $.urlParam('id')
}, function(data, status){
if(status){
alert("Thank you for your comment! Unfortunately due to spammers I have limited comments to require approval, your comment will be viewable once approved, have a n$
}else{
alert("Oops, something went wrong!");
}
});
});
});
</script>
Here I need javascript/jQuery to know what my article pages ID is and then grab the information for the inputs. In order to post a comment wordpress requires minimally these 4 data items:
- Author name
- Author email
- Content
- Post associated to the comment
So you’re probably thinking, Ed, you rushed all that a bit, whats the hurry? Well, this isn’t the interesting parts. The interesting bit is the changes needed to wordpress. So we have to make two main changes to wordpress’ functions.php to allow this to work. The first is:
- Getting a good date format for comments – note, $comment->formatted_date doesn’t actually exist by default in your wordpress’ REST API!
- WordPress doesn’t allow anonymous posting by default.
Let’s tackle the second one first weirdly. This one was pretty easy with some googling, you simply add anywhere into your functions.php page the following:
function filter_rest_allow_anonymous_comments() {
return true;
}
add_filter('rest_allow_anonymous_comments','filter_rest_allow_anonymous_comments');
Thanks to:
https://wordpress.stackexchange.com/questions/214480/post-comments-using-wp-rest-api-v2-in-wordpress
The next bit is the formatted date, now you may recall that I’ve done this before for posts. So I refound the article:
Now I then thought, okay, just change post for date. However when I used this in postman to get a comment again, I got the formatted date field but it’s value was true, not a date. So I finally found this where someone had a similar track of thought:
Thanks to the second comment I then added into my functions.php the following:
add_action('rest_api_init', function() {
register_rest_field(
array('comment'),
'formatted_date',
array(
'get_callback' => function( $object ) {
return date_i18n( __( 'j F Y, H:i', 'wpse' ), strtotime( $object['date'] ) );
},
'update_callback' => null,
'schema' => null,
)
);
});
And hey presto, I can get comments, populate them into my article.php and also allow users to post! Now as is my style, I modularised some of this to alternate files that I used the article.php php’s functionality to then add in, but that’s not necessary if you want to replicate this.
As encouraged, any questions, comments, feedback on this article, let me know!
My next mission is to fix the email system, it can’t currently send emails to gmail it seems – too many restrictions even though I’ve set my server DNS up correctly, apparently there’s a wordpress plugin I can use that should help and found while trying to investigate the REST API for this project.