Improving on Blogger’s Commenting System I

BcS is the target of numerous demands and criticism. As no major overhaul is in the books, numerous hacks have mushroomed to respond to its users’ desires. We’ll be looking at:
A. Embedding the comment form,
B. Numbering comments,
C. Show Author Photo in Comments,
D. Highlight owner’s comments,
E. Recent comments,
F. Top commentators,
G. Add Reactions

Calling what Blogger has a “commenting system” is an optimistic misnomer. While other blogging platforms (most notably, Wordpress), have impressing systems that invite comments and debate, Blogger has become a laggard. Very little in terms of comments has changed since Google has taken over. We will take a detailed look at how this antiquated system can be improved and hacked to provide a reasonable amount of modern functionality.

For those unhappy with Blogger commenting System (BcS), but who like it enough to still want to use it, there are 3 major alternatives: IntenseDebate, Disqus and Haloscan. We will be looking at all of them in detail in future episodes. In this article we will only consider a few hacks and improvements meant to make BcS more bearable.

 

A. Embedding the comment form

One of the biggest complaints about BcS is that the commenting form is not shown on the article page; because it is not easily visible, many readers forgo leaving a comment altogether. While in the past it has been possible to embed the form with iframes, this hack was crude and unworkable. Luckily, not long ago Blogger started to offer a hack to allow embedding of the commenting form, yet this is not as simple as one would expect. There are many guides on how to add the hack to your page, but most have mixed results (1). Here is a guide that has never failed me. If you have a default template, you might want to jump straight to step 3. If you have a customized template, follow the guide in its entirety. Note that starting with step 3 will temporary render your comment form unusable, until you complete the other steps, if your template is customized, which is why they are presented in this order.

  1. In your Dashboard, go to Layout –> Edit HTML (save your template first, if you don’t have a backup) and search (Ctrl+F) for the first block of code and replace it with the second:
    1. <p class='comment-footer'>
           <b:if cond='data:post.allowComments'>
                <a expr:href='data:post.addCommentUrl' expr:onclick='data:post.addCommentOnclick'> <data:postCommentMsg/></a>
           </b:if>
      </p>
    2. <p class='comment-footer'>
      <b:if cond='data:post.embedCommentForm'>
      <b:include data='post' name='comment-form'/>
      <b:else/>
      <b:if cond='data:post.allowComments'>
      <a expr:href='data:post.addCommentUrl' expr:onclick='data:post.addCommentOnclick'>
      <data:postCommentMsg/>
      </a>
      </b:if>
      </b:if>
      </p>
  2. Save your Template.
  3. Login to Blogger in Draft –> Settings –> Comments, choose “Embedded below posts”, and that’s it!

Note that there have been numerous reports of this not working as it should (2).

 

B. Numbering comments

As in step 1 above, go into your Template, search for the code in green and add the code in red:

<dl id='comments-block'>
<script type='text/javascript'>var CommentsCounter=0;</script>
<b:loop values='data:post.comments' var='comment'>
<div class='' expr:id='data:comment.id'>
<dt expr:class='"comment-author " + data:comment.authorClass' expr:id='data:comment.anchorName'>
<a expr:name='data:comment.anchorName'/>
<b:if cond='data:comment.authorUrl'>
<a expr:href='data:comment.authorUrl'><data:comment.author/></a>
<b:else/>
<data:comment.author/>
</b:if>
<data:commentPostedByMsg/>
<span class='comment-number'>
<a expr:href='"#comment-" + data:comment.id' title='Comment Link'>
<script type='text/javascript'>
CommentsCounter=CommentsCounter+1;
document.write(CommentsCounter)
</script>
</a>
</span>

</dt>
<dd class='comment-body'>
<b:if cond='data:comment.isDeleted'>
<span class='deleted-comment'><data:comment.body/></span>
<b:else/>
<p><data:comment.body/></p>
</b:if>
</dd>
<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>
</div>
</b:loop>
</dl>

Add the following before ]]></b:skin>:

.comment-number { float: right; display: block; width: 50px; margin-right: 5px; margin-top: -35px; /*comments-counter position*/ text-align: right; font-family: 'Century Gothic','Lucida Grande',Arial,Helvetica,Sans-Serif; font-size: 30px; font-weight: normal; } /*since the numbers are actually links, we need to force the color properties*/ .comment-number a:link, .comment-number a:visited { color: #445566 !important; text-decoration: none !important; } .comment-number a:hover, .comment-number a:active { color: #FF9933 !important; text-decoration: none !important; }

Save your Template and enjoy! I haven’t found much use for this hack, but you just might!

 

C. Show Author Photo in Comments

This is a feature that has captured Bloggers’ imagination since immemorial times.

1. PurpleMoggy’s Hack (3)

Edit your Template as in Step 1 above and add the following code just above </head>:

<script src='http://yggomelprup.googlepages.com/blogger_comment_photos.js' type='text/javascript'/> 
<script type='text/javascript'> 
//<![CDATA[ 
addLoadEvent(function(){showCommentPhotos('commentphoto','comment-author', 1);}); 
//]]> 
</script>

Alternatively, you might consider downloading and hosting that blogger_comment_photos.js file on your own hosting service:

/* Script by Stephen Paul Weber a.k.a. Singpolyma (http://singpolyma-tech.blogspot.com/)
   Based on work by Johan Sundstrom (http://ecmanaut.blogspot.com/2005/10/blogger-hack-inline-comment-faces.html)
   Updated by PurpleMoggy (http://purplemoggy.blogspot.com/)
*/

if( document.all && !document.getElementsByTagName )
  document.getElementsByTagName = function( nodeName )
  {
    if( nodeName == '*' ) return document.all;
    var result = [], rightName = new RegExp( nodeName, 'i' ), i;
    for( i=0; i<document.all.length; i++ )
      if( rightName.test( document.all[i].nodeName ) )
result.push( document.all[i] );
    return result;
  };
document.getElementsByClassName = function( className, nodeName )
{
  var result = [], tag = nodeName||'*', node, seek, i;
  var rightClass = new RegExp( '(^| )'+ className +'( |$)' );
  seek = document.getElementsByTagName( tag );
  for( i=0; i<seek.length; i++ )
    if( rightClass.test( (node = seek[i]).className ) )
      result.push( seek[i] );
  return result;
};
function writeScript(src) {
  var thescript = document.createElement("script");
  thescript.type = "text/javascript";
  thescript.src = src;
  document.body.appendChild(thescript);
}//end function writeScript
function addLoadEvent(func) {
         var oldonload = window.onload;
         if (typeof window.onload != 'function') {
            window.onload = func;
         } else {
            window.onload = function() {
               oldonload();
               func();
            }
         }//end if
}//end function addLoadEvent
BloggerProfiles = {};
BloggerProfiles.callbacks = {};
//BloggerProfiles.noimage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkBAMAAACCzIhnAAAAMFBMVEUAAAD%2FAIT%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FV4HBuAAAAAnRSTlP%2FAOW3MEoAAAFZSURBVHja7ZhZDsQgCIYJNygnUO5%2FyAFcutkqfWhmMpIuyQxf9EdAU2D2GrgJQcBpD5HFZROZyER%2BAqEoD%2BboQALqAxwIgXp7EXwFEXdDiHkYQUMoSG8cQzAjAWzAIUT85ZLhOKiuMSRRmCM%2BgNSBGpG7QMTxAQJehPyIDuOTnxBXkHM6e5ZyWZwJY7lI7EjLjk3k25HWQveQU8r%2BNiIJLztRSf5SA6RvrtE5INJatYOB%2BFmP0SJDK7a1PI9IsWg1nJpTKWm8QLQ%2FsCG8ecmfXLrTaWK540fZL2VS4m6NI%2F2I94ioV015P9PBuIvks3pBoIq5npiFbo%2FcaxFfjmE%2FsbwyN0iSj1U%2BBewgGu5DkPtaVDBtlrK3LnpeYIjbhOHT6os6vfWEVO8lMKedqZWWTaPG0aTXLkz%2BvpD6yJrCg4iWDUYXohEZ2F47NpGJTOSPkVe%2BXL3xFe4D3BFIBtihCWMAAAAASUVORK5CYII%3D';
BloggerProfiles.noimage = 'http://img139.imageshack.us/img139/1011/defaultavatarad7.png';
BloggerProfiles.imageWidth = 60;
BloggerProfiles.imageHeight = 75;
BloggerProfiles.callbacks.profile = function(data) {
          if(data.photo) {
             node = document.createElement('img');
             node.alt = 'Photo';
             if(!data.photo.url)
                data.photo.url = BloggerProfiles.noimage;
             node.src = data.photo.url;
             if(data.photo.width)
                node.width = data.photo.width;
             if(data.photo.height)
                node.height = data.photo.height;
             if (node.width > BloggerProfiles.imageWidth) {
                node.height = (BloggerProfiles.imageWidth * node.height) / node.width;
                node.width = BloggerProfiles.imageWidth;
             }
             if (node.height > BloggerProfiles.imageHeight) {
                node.width = (BloggerProfiles.imageHeight * node.width) / node.height;
                node.height = BloggerProfiles.imageHeight;
             }
             thecomments = document.getElementsByClassName('commentphoto-'+escape(data.url));
             for(var i=0; i<thecomments.length; i++)
                thecomments[i].appendChild(node.cloneNode(false));
             if(data.blogs) {
                for(var i=0; i<data.blogs.length; i++) {
                   if(data.blogs[i].url == BloggerProfiles.blogurl) {
                      thecomments = document.getElementsByClassName('commentblock-'+escape(data.url));
                      for(var i2=0; i2<thecomments.length; i2++) {
                         thecomments[i2].style.color = BloggerProfiles.color;
                         thecomments[i2].style.backgroundColor = BloggerProfiles.bgcolor;
                      }//end for thecomments
                   }//end if blogs.url == blogurl
                }//end for blogs
             }//end if data.blogs
          }//end if data.photo
          else {
             node = document.createElement('img');
             node.alt = 'Photo';
             node.src = BloggerProfiles.noimage;
             if (node.width > BloggerProfiles.imageWidth) {
                node.height = (BloggerProfiles.imageWidth * node.height) / node.width;
                node.width = BloggerProfiles.imageWidth;
             }
             if (node.height > BloggerProfiles.imageHeight) {
                node.width = (BloggerProfiles.imageHeight * node.width) / node.height;
                node.height = BloggerProfiles.imageHeight;
             }
             thecomments = document.getElementsByClassName('commentphoto-'+escape(data.url));
             for(var i=0; i<thecomments.length; i++)
                thecomments[i].appendChild(node.cloneNode(false));
             if(data.blogs) {
                for(var i=0; i<data.blogs.length; i++) {
                   if(data.blogs[i].url == BloggerProfiles.blogurl) {
                      thecomments = document.getElementsByClassName('commentblock-'+escape(data.url));
                      for(var i2=0; i2<thecomments.length; i2++) {
                         thecomments[i2].style.color = BloggerProfiles.color;
                         thecomments[i2].style.backgroundColor = BloggerProfiles.bgcolor;
                      }//end for thecomments
                   }//end if blogs.url == blogurl
                }//end for blogs
             }//end if data.blogs
          }//end else
}//end callback
function showCommentPhotos(photoclass,linkclass,linknum,fullclass,blogurl,color,bgcolor) {
  var comments, comlinks, i, node, re, by, blocks;
  BloggerProfiles.blogurl = blogurl;
  BloggerProfiles.color = color;
  BloggerProfiles.bgcolor = bgcolor;
  re = new RegExp( '^http://www.blogger.com/profile/\\d+', 'i' );
  comments = document.getElementsByClassName(photoclass);
  comlinks = document.getElementsByClassName(linkclass);
  if(fullclass)
     blocks = document.getElementsByClassName(fullclass);
  else
     blocks = [];
  var profilesobj = {};
  var profileurls = [];
  for(i=0; i<comments.length; i++) {
    by = comlinks[i].getElementsByTagName('a').item(linknum);
    if(by && re.test(by.href)) {
       comments[i].className += ' commentphoto-'+escape(by.href);
       if(blocks && blocks[i])
          blocks[i].className += ' commentblock-'+escape(by.href);
    } else {
       comments[i].className += ' commentphoto-nophoto'+i;
    }//end if-else
    if( !by || !re.test( by.href ) ) {BloggerProfiles.callbacks.profile({'url':'nophoto'+i,'photo':{'url':BloggerProfiles.noimage}});continue;}
    if(!profilesobj[by.href])
       profileurls.push(by.href);
    profilesobj[by.href] = true;
  }//end for
  for(i=0; i<profileurls.length; i++)
     writeScript('http://singpolymaplay.ning.com/bloggerProfile.php?xn_auth=no&url='+encodeURIComponent(profileurls[i]));
}//end function showCommentPhotos

Find the code in green and add the one in red:

<dl id='comments-block'> 
        <b:loop values='data:post.comments' var='comment'> 
          <dt class='comment-author' expr:id='"comment-" + data:comment.id'> 

<div class='commentphoto' style='float:right;'/>
    <a expr:name='"comment-" + data:comment.id'/> 
            <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-body'> 
            <b:if cond='data:comment.isDeleted'> 
              <span class='deleted-comment'><data:comment.body/></span> 
            <b:else/> 
              <p><data:comment.body/></p> 
            </b:if> 
          </dd> 
          <dd class='comment-footer'> 
            <span class='comment-timestamp'> 
              <a expr:href='"#comment-" + data:comment.id' title='comment permalink'> 
                <data:comment.timestamp/> 
              </a> 
              <b:include data='comment' name='commentDeleteIcon'/> 
            </span> 
          </dd> 

<div style='clear:both;'/>
    </b:loop> 
      </dl>
 

The bloggerProfile.php file seems to contain only this (assuming no server-side scripting):

if(typeof(BloggerProfiles) == "undefined") var BloggerProfiles = {};
BloggerProfiles.profile = {"url":""};
if(BloggerProfiles.callbacks && BloggerProfiles.callbacks.profile) BloggerProfiles.callbacks.profile(BloggerProfiles.profile)

Change float:right to float:left if you want to change on what side the photo shows. The size of photo is given by these two variables in the external .js file:

BloggerProfiles.imageWidth = 10;
BloggerProfiles.imageHeight = 20;

2. Tsung Kai-Chen’s more concise version

Posted in a comment to PurpleMoggy’s hack (4):

BloggerProfiles.callbacks.profile = function(data) {
         node = document.createElement('img');
         node.alt = 'Photo';

         if(data.photo) {
             if(!data.photo.url)
                data.photo.url = BloggerProfiles.noimage;
             node.src = data.photo.url;
          }else node.src = node.src = BloggerProfiles.noimage;         
             thecomments = document.getElementsByClassName('commentphoto-'+escape(data.url));
             for(var i=0; i<thecomments.length; i++)
                thecomments[i].appendChild(node.cloneNode(false));
             if(data.blogs) {
                for(var i=0; i<data.blogs.length; i++) {
                   if(data.blogs[i].url == BloggerProfiles.blogurl) {
                      thecomments = document.getElementsByClassName('commentblock-'+escape(data.url));
                      for(var i2=0; i2<thecomments.length; i2++) {
                         thecomments[i2].style.color = BloggerProfiles.color;
                         thecomments[i2].style.backgroundColor = BloggerProfiles.bgcolor;
                      }//end for thecomments
                   }//end if blogs.url == blogurl
                }//end for blogs
             }//end if data.blogs
}//end callback

3. Singpolyma’s second try

Before finally joining Wordpress, sp improved (5) his original method:

Go to 'Edit HTML' under Template and check the 'Expand Widget Templates' box.
Find the green code and enter the red one below it:

<dl id='comments-block'>
<b:loop values='data:post.comments' var='comment'>

<div style="clear:both">
<dt style="float:left;margin-right:5px;clear:both;" expr:id='"commentphoto" + data:comment.id'></dt>
<script type="text/javascript">if(typeof(commentPhotoIds) == 'undefined') var commentPhotoIds = []; commentPhotoIds.push({'id':'commentphoto<data:comment.id/>', 'url':'<data:comment.authorUrl/>'});</script>

A bit further down you will see a </dl>. Immediately before it insert the code: </div>
Directly before the </body> code in your template add this code:

<script type='text/javascript'>
//<![CDATA[
function commentPhotoDo() {
var tag;
for(var i in commentPhotoIds) {
tag = document.createElement('script');
tag.type = 'text/javascript';
tag.src = 'http://scrape.singpolyma.net/avatar.php?maxwidth=70&url='+encodeURIComponent(commentPhotoIds[i].url)+'&id='+encodeURIComponent(commentPhotoIds[i].id)+'&defaultimage='+encodeURIComponent('http://img139.imageshack.us/img139/1011/defaultavatarad7.png');
document.body.appendChild(tag);
}//end for var i in commentPhotoIds
}//end function commentPhotoDo
commentPhotoDo();

The avatar.php file seems to contain the following:

<?php

function getTidy($url) {
//   $curl = curl_init('http://cgi.w3.org/cgi-bin/tidy?docAddr='.urlencode($url).'&forceXML=on');
   $curl = curl_init($url);
   curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
   curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
   curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.4) Gecko/20060508 Firefox/2.0');
   $rtrn = curl_exec($curl);
   curl_close($curl);
//   $tidy = new tidy;
//   $tidy->parseString($rtrn, array('output-xml' => true, 'doctype' => 'loose', 'add-xml-decl' => true),'utf8');
//   $tidy->cleanRepair();
//   return str_replace('&nbsp;','&#160;',$tidy);
   return str_replace('&nbsp;','&#160;',$rtrn);
}//end function getTidy

$bloggerdata = getTidy($_REQUEST['url']);
@$doc = new DOMDocument();
@$doc->preserveWhiteSpace = false;
@$doc->loadHTML($bloggerdata);
@$bloggerdata = $doc->saveXML();
$theParser = xml_parser_create();
xml_parse_into_struct($theParser,$bloggerdata,$vals);
xml_parser_free($theParser);

$img = array();
foreach($vals as $el) {
   if($el['tag'] == 'IMG' && ($el['attributes']['ALT'] == 'My Photo' || in_array('photo',explode(' ',$el['attributes']['CLASS'])))) {$img['photo'] = array();$img['photo']['url'] = $el['attributes']['SRC'];$img['photo']['width'] = $el['attributes']['WIDTH'];$img['photo']['height'] = $el['attributes']['HEIGHT'];}
}//end foreach
$img = $img['photo'];

header('Content-type: text/javascript;');
if($_REQUEST['maxwidth']) {
   $img['height'] = '';//size proportionately
   if(!$img['width'] || $img['width'] > $_REQUEST['maxwidth']) $img['width'] = $_REQUEST['maxwidth'];
}//end if maxwidth
if($_REQUEST['maxheight']) {
   $img['width'] = '';//size proportionately
   if(!$img['height'] || $img['height'] > $_REQUEST['maxheight']) $img['height'] = $_REQUEST['maxheight'];
}//end if maxheight
if($img['url'])
   echo 'document.getElementById("'.$_REQUEST['id'].'").innerHTML = "<img src=\"'.htmlentities($img['url']).'\"'.($img['width'] ? ' width=\"'.$img['width'].'\"' : '').($img['height'] ? ' height=\"'.$img['height'].'\"' : '').' alt=\"\" />";';
else if($_REQUEST['defaultimage'])
   echo 'document.getElementById("'.$_REQUEST['id'].'").innerHTML = "<img src=\"'.htmlentities($_REQUEST['defaultimage']).'\"'.($img['width'] ? ' width=\"'.$img['width'].'\"' : '').($img['height'] ? ' height=\"'.$img['height'].'\"' : '').' alt=\"\" />";';

?>

 

D. Highlight Your Own Comments

The mother of “highlight your own comments” post is Hackosphere’s (6):

First find this class called comment-body, copy it to define another class comment-body-author and modify it for the way your comments should look like. For example, here I have set the color to what I want and made it bold.

.comment-body {
margin:0;
padding:0 0 0 20px;
}
.comment-body p {
font-size:100%;
margin:0 0 .2em 0;
}

.comment-body-author {
margin:0;
padding:0 0 0 20px;
}
.comment-body-author p {
font-size:100%;
margin:0 0 .2em 0;
color:#CC3300;
text-decoration:bold;
}

Then, search for "id ='comments-block'" in your template to identify the portion of code in this page and add the new code shown in red and blue. The red one is for author comment highlighting and the blue one is for comment notification.

That hack was made long time ago, when Blogger’s commenting system was even less evolved. The hack is not useful in its entirety, but it will help you in having your own comments highlighted. Singpolyma also mentions another hack (7), this time to show an author's photo in the footer of a post:

Awhile ago I received this message from an unidentified user:

Title: photo for authors
Can you use javascript to show an author's photo in the footer of a post? I've looked everywhere and only find it in the old blogger Any help would be awesome!

While a script based on my new comment author photos could be built to inject the image for the post author (multi-author blogs), I thought it might first be useful to provide basic information about hard-coding this.

  1. Go to the Template tab on your blog's dashboard
  2. Select Edit HTML
  3. Check the Expand Widget Templates box
  4. Find the code block starting with <div class='post-footer'> or after <data:post.body/>
  5. Insert the content you want there
  6. Save!

 

E. Recent Comments

1. The easiest method to display Recent Comment is to use the Comment feed and display it as a built-in Feed widget, using Add Gadget. The Comment Feed is http://YOURBLOG NAME.blogspot.com/feeds/comments/default. You can specify whether to show comment authors or even the date of the comment.

2. The second method allows more customization:

Copy and paste the following code into Notepad, then save the file with a .js extension:

function showrecentcomments(json) { 
for (var i = 0; i < numcomments; i++) { 
var entry = json.feed.entry[i]; 
var alturl; 
if (i == json.feed.entry.length) break; 
for (var k = 0; k < entry.link.length; k++) { 
if (entry.link[k].rel == 'alternate') { 
alturl = entry.link[k].href; 
break; 


alturl = alturl.replace("#", "#comment-"); 
var postlink = alturl.split("#"); 
postlink = postlink[0]; 
var linktext = postlink.split("/"); 
linktext = linktext[5]; 
linktext = linktext.split(".html"); 
linktext = linktext[0]; 
var posttitle = linktext.replace(/-/g," "); 
posttitle = posttitle.link(postlink); 
var commentdate = entry.published.$t; 
var cdyear = commentdate.substring(0,4); 
var cdmonth = commentdate.substring(5,7); 
var cdday = commentdate.substring(8,10); 
var monthnames = new Array(); 
monthnames[1] = "Jan"; 
monthnames[2] = "Feb"; 
monthnames[3] = "Mar"; 
monthnames[4] = "Apr"; 
monthnames[5] = "May"; 
monthnames[6] = "Jun"; 
monthnames[7] = "Jul"; 
monthnames[8] = "Aug"; 
monthnames[9] = "Sep"; 
monthnames[10] = "Oct"; 
monthnames[11] = "Nov"; 
monthnames[12] = "Dec"; 
if ("content" in entry) { 
var comment = entry.content.$t;} 
else 
if ("summary" in entry) { 
var comment = entry.summary.$t;} 
else var comment = ""; 
var re = /<\S[^>]*>/g;  
comment = comment.replace(re, ""); 
if (!standardstyling) document.write('<div class="bbrecpost">'); 
if (standardstyling) document.write(' 
'); 
if (showcommentdate == true) document.write('On ' + monthnames[parseInt(cdmonth,10)] + ' ' + cdday + ' '); 
document.write('<a href="' + alturl + '">' + entry.author[0].name.$t + '</a> commented'); 
if (showposttitle == true) document.write(' on ' + posttitle); 
if (!standardstyling) document.write('</div><div class="bbrecpostsum">'); 
if (standardstyling) document.write(' 
'); 
if (comment.length < numchars) { 
if (standardstyling) document.write('<i>'); 
document.write(comment); 
if (standardstyling) document.write('</i>');} 
else 
{  
if (standardstyling) document.write('<i>'); 
comment = comment.substring(0, numchars); 
var quoteEnd = comment.lastIndexOf(" "); 
comment = comment.substring(0, quoteEnd); 
document.write(comment + '...<a href="' + alturl + '">(more)</a>'); 
if (standardstyling) document.write('</i>');} 
if (!standardstyling) document.write('</div>'); 
if (standardstyling) document.write(' 
'); 

if (!standardstyling) document.write('</div>');}

Upload the file to googlepages, or somewhere where you can upload *.js files.

From your Dashboard, go to Layout –> Page Elements and Add Gadget as HTML / JavaScript. Call it Recent Comments or whatever strikes your fancy.

Add the code below, after replacing BLOG URL and UPLOADED JAVASCRIPT FILE URL with your own stuff.

<script style="text/javascript" src="UPLOADED JAVASCRIPT URL"></script> 
<script style="text/javascript">var numcomments = 5;var showcommentdate = true;var showposttitle = true;var numchars = 100;var standardstyling = true;</script> 
<script src="http://YOURBLOG NAME.blogspot.com/feeds/comments/default?alt=json-in-script&callback=showrecentcomments"></script>

You can customize the above code as follows:

  • var numcomments = 5 "This means that 5 latest comments will be displayed in the sidebar. If you want more than 5 just change the number"
  • var showcommentdate = true "true for displaying the comment date and false for not displaying"
  • var showposttitle = true "true for displaying post title and false for not displaying"
  • var numchars = 100 "Only 100 characters in the comment will be displayed"

3. The 3rd method is not much different from above, but is presented differently by Amanda (9)

You can paste the following code directly into an HTML / JavaScript widget on the sidebar, after replacing yourblog.blogspot.com with your own URL.

<script style="text/javascript" src="http://kunoichi.info/blogger_buster/comments.js"></script><script style="text/javascript">var a_rc=3;var m_rc=true;var n_rc=true;var o_rc=100;</script><script src="http://yourblog.blogspot.com/feeds/comments/default?alt=json-in-script&callback=showrecentcomments"></script>

You can customize variables as shown above. Unlike the previous version, this one will also display a link to Amanda. Here is the comments.js file in case you would like to host it yourself (you may also right click and save as.. locally in the box immediately above; I left it as a live link for this very purpose):

//Recent Comments Widget originally by Blogger Templates and updated by Blogger Buster function showrecentcomments(json){for(var i=0;i<a_rc;i++){var b_rc=json.feed.entry[i];var c_rc;if(i==json.feed.entry.length)break;for(var k=0;k<b_rc.link.length;k++){if(b_rc.link[k].rel=='alternate'){c_rc=b_rc.link[k].href;break;}}c_rc=c_rc.replace("#","#comment-");var d_rc=c_rc.split("#");d_rc=d_rc[0];var e_rc=d_rc.split("/");e_rc=e_rc[5];e_rc=e_rc.split(".html");e_rc=e_rc[0];var f_rc=e_rc.replace(/-/g," ");f_rc=f_rc.link(d_rc);var g_rc=b_rc.published.$t;var h_rc=g_rc.substring(0,4);var i_rc=g_rc.substring(5,7);var j_rc=g_rc.substring(8,10);var k_rc=new Array();k_rc[1]="Jan";k_rc[2]="Feb";k_rc[3]="Mar";k_rc[4]="Apr";k_rc[5]="May";k_rc[6]="Jun";k_rc[7]="Jul";k_rc[8]="Aug";k_rc[9]="Sep";k_rc[10]="Oct";k_rc[11]="Nov";k_rc[12]="Dec";if("content" in b_rc){var l_rc=b_rc.content.$t;}else if("summary" in b_rc){var l_rc=b_rc.summary.$t;}else var l_rc="";var re=/<\S[^>]*>/g;l_rc=l_rc.replace(re,"");if(m_rc==true)document.write('On '+k_rc[parseInt(i_rc,10)]+' '+j_rc+' ');document.write('<a href="'+c_rc+'">'+b_rc.author[0].name.$t+'</a> commented');if(n_rc==true)document.write(' on '+f_rc);document.write(': ');if(l_rc.length<o_rc){document.write('<i>&#8220;');document.write(l_rc);document.write('&#8221;</i><br/><br/>');}else{document.write('<i>&#8220;');l_rc=l_rc.substring(0,o_rc);var p_rc=l_rc.lastIndexOf(" ");l_rc=l_rc.substring(0,p_rc);document.write(l_rc+'&hellip;&#8221;</i>');document.write('<br/><br/>');}}document.write('<div style="font-size:70%;text-align:center"><a href="http://www.bloggerbuster.com/2007/08/recent-comments-widget-update-this.html">Add this widget to your blog</a></div>');}

Enjoy!

 

F. Top Commentators

One way to reward and encourage comments is to display a list of the top commentators. The first to design such a widget, based on Yahoo Pipes, was AssessMyBlog (8). BloggerBuster (9) and GoogleSystem (10) soon followed with bug fixes and improvements.

To display your Top Commentators, please add the following code as a HTML / Javascript sidebar widget:

<script type="text/javascript">
function pipeCallback(obj) {
document.write('<ol>');
var i;
for (i = 0; i < obj.count ; i++)
{
var href = "'" + obj.value.items[i].link + "'";
var item = "<li>" + "<a href=" + href + ">" + obj.value.items[i].title + "</a> </li>";
document.write(item);
}
document.write('</ol>');
}
</script>
<script src=http://pipes.yahoo.com/pipes/pipe.run?_render=json&_callback=pipeCallback&_id=992f0d75e437d1cb64c1507605cefe09&url=http%3A%2F%2FYOURblog.blogspot.com&num=10&filter=YOURNAME type="text/javascript"></script>

To make it work for your blog, replace YOURblog.blogspot.com with your own and YOURNAME with the name you use to sign your comments. This way, you will not take someone else’s space and your name will be filtered out from the list. You can add more names using a comma and make sure there are no spaces in between. The filter takes any regular expression (11).

  • To filter alias1, alias2, alias3 use filter=alias1,alias2,alias3
  • To filter names starting with Johnny, such as Johnny Baloney, Johnny B and Johnny Banknote use filter=Johnny.+
  • To filter names including special characters ? . + escape them with a backslash; Wheretoday? becomes Wheretoday\?

Let me know if you have any problem!

 

G. Add Reactions

Reactions are not really comments, but they are, just like comments, feedback. It’s currently a feature that can be added only from Blogger in Draft (12, 13).

In the unusual scenario that you are using a virgin, default template, go to Layout –> Edit HTML and click on "Revert Widget Templates to Default" to replace all the widget templates with the updated code. (This will preserve your existing widgets.) Most people however have updated or modified their template, so updating will not yield the desired results.

To update your code manually, go to Layout -> Edit HTML in your Dashboard and check the "Expand widget templates" box. Next, search for the following line of code (or similar):
<p class='post-footer-line post-footer-line-1'> If you cannot find it, search for <p><data:post.body/></p> Immediately after, add the following:

<span class='reaction-buttons'> <b:if cond='data:top.showReactions'> <table border='0' cellpadding='0' width='100%'><tr> <td valign='center'><span class='reactions-label'> <data:top.reactionsLabel/></span> </td> <td><iframe allowtransparency='true' class='reactions-iframe' expr:src='data:post.reactionsUrl' frameborder='0' name='reactions' scrolling='no'/></td> </tr></table> </b:if> </span>

As usual, preview and, if everything’s alright, save.

 

Bonus: Gravatars

I noticed that one of my templates is displaying gravatars. I’m not sure how exactly that’s done, I need to look at it in greater detail; until then, here are a few snipets of code that are most likely relevant:

/*++++++++++++++++++++++++++++++ Comments +++++++++++++++++++++++++++++++++*/
.author_info {
        float:left;
        width:320px;
        font-family:"New times roman",Arial;
        padding-bottom:2px;
}

.comment_count {
        color:#acc4d0;
        float:right;
        width:40px;
        font-weight:700;
        font-size:24px;
}

.gravatar {
        float:left;
        height:32px;width:32px;
        margin-right:7px;
        margin-bottom:2px;
}
/*++++++++++++++++++++++++++++++ Calendar +++++++++++++++++++++++++++++++++*/
table#wp-calendar{
    width: 100%;
}

/*+++++++++++++++++++++++++++++ Comment +++++++++++++++++++++++++++++++++*/

#comments h4 {
    color:#003F80;
    font-size:14px;
    font-weight:bold;
    padding:10px 0px 20px;
}

#comments-head {
    background:#2370BF none repeat scroll 0%;
    border:2px solid #C1DBE8;
    color:#FFFFFF;
    font-size:14px;
    font-weight:700;
    height:18px;
    margin:0px;
    padding:2px 4px;
}

#comments-block {
margin:0 0 1px;
padding:0;
font-size:11px;
}

#comment-entry {
    background:#C1DBE8 none repeat scroll 0%;
    display:block;
    list-style-image:none;
    list-style-position:outside;
    list-style-type:none;
    margin:7px 0pt;
    padding:6px 15px 12px;
}

.comment-author {
    float:left;
    font-family:"New times roman",Arial;
    padding-bottom:2px;
    width:320px;
}

.gravatar {
    border:1px dashed #000000;
    float:left;
    height:32px;
    margin-bottom:2px;
    margin-right:7px;
    padding:1px;
    width:32px;
}

.comment-body {
    border-top: 1px dashed rgb(147, 160, 173);
    clear: both;
    margin:0px;
}

p.comment-footer {
    color:#003F80;
    font-size:14px;
    font-weight:bold;
    padding:10px 0px 20px;
}
.comment-footer2 {
    color:#003F80;
    font-size:14px;
    font-weight:bold;
    padding:10px 0px 20px;
}

                <b:if cond='data:post.allowComments'>
                    <a expr:href='data:post.addCommentUrl' expr:onclick='data:post.addCommentOnclick'><data:post.numComments/> Comments</a>
                </b:if>

              </span></small> </p>
        </b:if>

            <p class='post-footer-line post-footer-line-2'/>
            <p class='post-footer-line post-footer-line-3'/>

    </div>

  </div>
</b:includable>
<b:includable id='commentDeleteIcon' var='comment'>
  <span expr:class='&quot;item-control &quot; + data:comment.adminClass'>
    <a expr:href='data:comment.deleteUrl' expr:title='data:top.deleteCommentMsg'>
      <span class='delete-comment-icon'>&#160;</span>
    </a>
  </span>

<b:includable id='comments' var='post'>
  <div class='comments' id='comments'>
    <a name='comments'/>
    <b:if cond='data:post.allowComments'>
      <div id='comments-head'>
        <b:if cond='data:post.numComments == 1'>
          1 <data:commentLabel/>:
        <b:else/>
          <data:post.numComments/> <data:commentLabelPlural/>:
        </b:if>
      </div>

      <dl id='comments-block'>
        <b:loop values='data:post.comments' var='comment'>
        <div id='comment-entry'>
        <div class='gravatar'>
            <img width='32' height='32' class='avatar' src='http://i254.photobucket.com/albums/hh92/eblogtemplates/langit/gravatar.jpg' alt='gravatar'/>               
        </div>
          <dt class='comment-author' expr:id='&quot;comment-&quot; + data:comment.id'>
          <strong style="color: rgb(0, 63, 128); font-size: 16px;">
            <a expr:name='&quot;comment-&quot; + data:comment.id'/>
            <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/>
        </strong>
        <br/>
        <span class='comment-timestamp'>
            <data:comment.timestamp/> <b:include data='comment' name='commentDeleteIcon'/>
        </span>
        </dt>
          <dd class='comment-body'>
            <b:if cond='data:comment.isDeleted'>
              <span class='deleted-comment'><data:comment.body/></span>
            <b:else/>
              <p><data:comment.body/></p>
            </b:if>
          </dd>
          <dd class='comment-footer'>
            <span class='comment-timestamp'>
            </span>
          </dd>
        </div> 
        </b:loop>
      </dl>

      <p class='comment-footer2'>
        <a expr:href='data:post.addCommentUrl' expr:onclick='data:post.addCommentOnclick'><data:postCommentMsg/></a>
      </p>
    </b:if>

    <div id='backlinks-container'>
    <div expr:id='data:widget.instanceId + &quot;_backlinks-container&quot;'>
       <b:if cond='data:post.showBacklinks'>
         <b:include data='post' name='backlinks'/>
       </b:if>
    </div>
    </div>
  </div>
</b:includable>

Hope you enjoyed our special presentation! Let us know how much, we love feedback! :)

Sources

  1. BloggerBuster: Comment Form
  2. software-testing-zone: A Regression Bug?
  3. PurpleMoggy's Comment Photos
  4. Tsung Kai-Chen's code
  5. SingPolyma's 2nd try
  6. Author Comment Highlighting
  7. Content in Footer
  8. AssessMyBlog: Top Commentators Update
  9. Amanda's Recent Comments (cache, s)
  10. GoogleSystem: top-commentators-for-blogger-blog
  11. http://en.wikipedia.org/wiki/Regular_expression_examples
  12. BloggerBuster guide to adding Reactions
  13. BloggerInDraft - Reactions announcement

blog comments powered by Disqus
Your gift enables us to continue to provide high quality reporting with little or no advertising.