Follow this Blog!

Jul 23, 2011

f Comment

Reverse the Order Of Comments In Google Blogger

AmazonBy default Google Blogger orders the comments of each post in the ascending order of recentness, meaning that the most recent comment shows up last. How uncool! Did it ever occur to them that people would like to see the most recent comment first? How do I show the most recent comments first? How do I show the comments in the descending order of recentness? This post will first describe the issue and then recommend a fix that works!

The Problem
Let's see if there's a way to fix this issue natively in Blogger's widget tag language.

Log into your Blogger account and go to Design -> Edit HTML and check 'Expand Widget Templates' you'll see the following (I put the 'comment-footer' section above 'comment-body' to fit my blog's style):
...
<b:loop values='data:post.comments' var='comment'> 
  <dt expr:class='"comment-author " + data:comment.authorClass' expr:id='data:comment.anchorName'>
    <b:if cond='data:comment.favicon'>
      <img expr:src='data:comment.favicon' height='16px' style='margin-bottom:-2px;' width='16px'/>
    </b:if>
    <a expr:name='data:comment.anchorName'/>
    <b:if cond='data:blog.enabledCommentProfileImages'>
      <data:comment.authorAvatarImage/>
    </b:if>
    <b:if cond='data:comment.authorUrl'>
      <a expr:href='data:comment.authorUrl' rel='nofollow'><data:comment.author/></a>
    <b:else/>
      <data:comment.author/>
    </b:if>
    <data:commentPostedByMsg/>
  </dt>
  <dd class='comment-footer'>
    <span class='comment-timestamp'>
      <a expr:href='data:comment.url' title='comment permalink'>
        <data:comment.timestamp/>
      </a>
      <b:include data='comment' name='commentDeleteIcon'/>
    </span>
  </dd>
  <dd class='comment-body' expr:id='data:widget.instanceId + data:comment.cmtBodyIdPostfix'>
    <b:if cond='data:comment.isDeleted'>
      <span class='deleted-comment'><data:comment.body/></span>
    <b:else/>
      <p>
        <data:comment.body/>
      </p>
    </b:if>
  </dd>
</b:loop>
...
The key line is this:

<b:loop values='data:post.comments' var='comment'>
This line basically loops through each comment for this post. To reverse the order of these comments you'll need a way to indicate you want to loop starting at the most recent comment and work your way through the older comments. But HOW? Unfortunately there is NO WAY to do it natively in Blogger's widget tags for layout! How frustrating!

Luckily you can use the almighty Javascript to manipulate the DOM and reverse the order of the comments! Below we'll discuss this solution. Questions? Let me know!

Solution: Use Javascript
To use the Javascript solution here are the steps you need to do. I assume you've already created an external Javascript file (mine is called js.js) and referenced it within <head> section in your HTML template. Your Javascript file should contain the Javascript code I'll be discussing in this post.

In STEP 1 wrap all components of a comment in a DIV. Each comment has three components: author, body, footer. Once they are wrapped inside one DIV, you can manipulate the comments much more easily. This is not a necessary step but it helps organize comments.

In STEP 2 you write a Javascript function to collect all the comment nodes and insert them into the DOM in the reverse order.

Finally, in STEP 3, call the Javascript function and see that the comments are reversed! Obviously this solution only works if Javascript is enabled, but in today's world of browsers you can pretty much assume that this is the case.

Next let's look at each step in detail below!

STEP 1: Group each comment into one DIV block
Log into your Blogger account and go to Design -> Edit HTML and check 'Expand Widget Templates' and locate the following block of code:
<b:loop values='data:post.comments' var='comment'> 
    <dt expr:class='"comment-author " + data:comment.authorClass' expr:id='data:comment.anchorName'>
      ...
    </dt>
    <dd class='comment-footer'>
      ...
    </dd>
    <dd class='comment-body' expr:id='data:widget.instanceId + data:comment.cmtBodyIdPostfix'>
      ...
    </dd>
</b:loop>
As you can see each comment consists of the author, footer (date and time, etc.), and body. Again I've put the 'comment-footer' section above 'comment-body' to fit my blog's style. Change it to the following:
<b:loop values='data:post.comments' var='comment'> 
  <div class='comment-block'>
    <dt expr:class='"comment-author " + data:comment.authorClass' expr:id='data:comment.anchorName'>
      ...
    </dt>
    <dd class='comment-footer'>
      ...
    </dd>
    <dd class='comment-body' expr:id='data:widget.instanceId + data:comment.cmtBodyIdPostfix'>
      ...
    </dd>
  </div>
</b:loop>
Now you can see that we've grouped the 'comment-author' block, 'comment-footer' block, and 'comment-body' block inside one DIV block so that we can easily manipulate each comment!

STEP 2: Write a Javascript Function
Now let's open up the external Javascript file referenced by your blog's HTML template. In it we need to write a Javascript function to manipulate the order of comments. Here's the code:
function reverseComments() {
 var commentList = document.querySelectorAll("div.comment-block");

 for(var i=0;i< commentList.length;i++) {
  var node = commentList[i];
  node.parentNode.insertBefore(node, node.parentNode.firstChild);
 }
}
The way the function works is simple. It selects all the DIV blocks with class set to 'comment-block'; then it loops through each comment and insert it again in the reverse order. Once it's done you get the same comments in the reverse order!

In fact this is Javascript and as such you can manipulate the comments any way you want. You can do things like show only the first 3 comments and have the rest hidden which become visible upon clicking a button that says "See more comments". The sky is the limit!

STEP 3: Call the Javascript function
Now you simply call the function 'reverseComments()' where appropriate! You MUST call it when the DOM is ready! I use jQuery, so I call reverseComments() inside the block of $(document).ready(function() { ... }); in my external Javascript file. If you don't use jQuery simply call the function in the following manner:
window.onload=function(){
  reverseComments();
}

Questions? Let me know!
Please leave a comment here!
One Minute Information - by Michael Wen
Find Michael on Google or Facebook
ADVERTISING WITH US - Direct your advertising requests to Michael