Pages

Wednesday, May 2, 2012

36

Top Commentators Gadget with avatars

I had a request of this gadget in one blog comment. There are some top commentators gadgets around, most relying on a Yahoo pipe. I knew it can be done with just javascript, with no pipes. Demo: it is installed on this blog, look at the right sidebar. Hope you like it. :)

Features

You can configure the maximum number of top commentators, and minimum number of comments one must have to get on the list (to weed out the 1 comment commentators, if wanted, for example). Own nick and a list of other nicks (for example "Anonymous") can be excluded from the list. Output strings can be translated.

The Script, installing

Add a HTML/Javascript gadget to your blog, and paste the following code into it.

Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. <style type="text/css">
  2. .top-commenter-line {margin: 3px 0;}
  3. .top-commenter-line .profile-name-link {padding-left:0;}
  4. .top-commenter-avatar {vertical-align:middle;}
  5. </style>
  6. <script type="text/javascript">
  7. //
  8. // Top Commentators gadget with avatars, by MS-potilas 2012.
  9. // Gets a list of top commentators from all comments, or specified number of days in the past.
  10. // See http://yabtb.blogspot.com/2012/05/top-commenters-gadget-with-avatars.html
  11. //
  12. // CONFIG:
  13. var maxTopCommenters = 5;   // how big a list of top commentators
  14. var minComments = 1;        // how many comments must top commentator have at least
  15. var numDays = 0;            // from how many days (ex. 30), or 0 from "all the time"
  16. var excludeMe = true;       // true: exclude my own comments
  17. var excludeUsers = ["Anonymous", "someotherusertoexclude"];     // exclude these usernames
  18. var maxUserNameLength = 42; // 0: don't cut, >4: cut usernames
  19. //
  20. var txtTopLine = '<b>[#].</b> [image] [user] ([count])';
  21. var txtNoTopCommenters = 'No top commentators at this time.';
  22. var txtAnonymous = '';      // empty, or Anonymous user name localized if you want to localize
  23. //
  24. var sizeAvatar = 16;
  25. var cropAvatar = true;
  26. //
  27. var urlNoAvatar = "http://lh4.googleusercontent.com/-069mnq7DV_g/TvgRrBI_JaI/AAAAAAAAAic/Iot55vywnYw/s"+sizeAvatar+"/avatar_blue_m_96.png"; // http://www.blogger.com/img/avatar_blue_m_96.png resizeable
  28. var urlAnoAvatar = 'http://www.gravatar.com/avatar/00000000000000000000000000000000?d=mm&s=' + sizeAvatar;
  29. var urlMyProfile = ''; // set if you have no profile gadget on page
  30. var urlMyAvatar = '';  // can be empty (then it is fetched) or url to image
  31. // config end
  32. // for old IEs & IE modes:
  33. if(!Array.indexOf) {
  34.  Array.prototype.indexOf=function(obj) {
  35.   for(var i=0;i<this.length;i++) if(this[i]==obj) return i;
  36.   return -1;
  37. }}
  38. function replaceTopCmtVars(text, item, position)
  39. {
  40.   if(!item || !item.author) return text;
  41.   var author = item.author;
  42.  
  43.   var authorUri = "";
  44.   if(author.uri && author.uri.$t != "")
  45.     authorUri = author.uri.$t;
  46.  
  47.   var avaimg = urlAnoAvatar;
  48.   var bloggerprofile = "//www.blogger.com/profile/";
  49.   if(author.gd$image && author.gd$image.src && authorUri.indexOf(bloggerprofile) >= 0)
  50.     avaimg = author.gd$image.src;
  51.   else {
  52.     var parseurl = document.createElement('a');
  53.     if(authorUri != "") {
  54.       parseurl.href = authorUri;
  55.       avaimg = 'http://www.google.com/s2/favicons?domain=' + parseurl.hostname;
  56.     }
  57.   }
  58.   if(urlMyProfile != "" && authorUri == urlMyProfile && urlMyAvatar != "")
  59.     avaimg = urlMyAvatar;
  60.   if(avaimg == "http://img2.blogblog.com/img/b16-rounded.gif" && urlNoAvatar != "")
  61.     avaimg = urlNoAvatar;
  62.   var newsize="s"+sizeAvatar;
  63.   avaimg = avaimg.replace(/\/s\d\d+-c\//, "/"+newsize+"-c/");
  64.   if(cropAvatar) newsize+="-c";
  65.   avaimg = avaimg.replace(/\/s\d\d+(-c){0,1}\//, "/"+newsize+"/");
  66.  
  67.   var authorName = author.name.$t;
  68.   if(authorName == 'Anonymous' && txtAnonymous != '' && avaimg == urlAnoAvatar)
  69.     authorName = txtAnonymous;
  70.   var imgcode = '<img class="top-commenter-avatar" height="'+sizeAvatar+'" width="'+sizeAvatar+'" title="'+authorName+'" src="'+avaimg+'" />';
  71.   if(authorUri!="") imgcode = '<a href="'+authorUri+'">'+imgcode+'</a>';
  72.  
  73.   if(maxUserNameLength > 3 && authorName.length > maxUserNameLength)
  74.     authorName = authorName.substr(0, maxUserNameLength-3) + "...";
  75.   var authorcode = authorName;
  76.   if(authorUri!="") authorcode = '<a class="profile-name-link" href="'+authorUri+'">'+authorcode+'</a>';
  77.  
  78.   text = text.replace('[user]', authorcode);
  79.   text = text.replace('[image]', imgcode);
  80.   text = text.replace('[#]', position);
  81.   text = text.replace('[count]', item.count);
  82.   return text;
  83. }
  84.  
  85. var topcommenters = {};
  86. var ndxbase = 1;
  87. function showTopCommenters(json) {
  88.   var one_day=1000*60*60*24;
  89.   var today = new Date();
  90.  
  91.   if(urlMyProfile == "") {
  92.     var elements = document.getElementsByTagName("*");
  93.     var expr = /(^| )profile-link( |$)/;
  94.     for(var i=0 ; i<elements.length ; i++)
  95.       if(expr.test(elements[i].className)) {
  96.         urlMyProfile = elements[i].href;
  97.         break;
  98.       }
  99.   }
  100.  
  101.   if(json && json.feed && json.feed.entry && json.feed.entry.length) for(var i = 0 ; i < json.feed.entry.length ; i++ ) {
  102.     var entry = json.feed.entry[i];
  103.     if(numDays > 0) {
  104.       var datePart = entry.published.$t.match(/\d+/g); // assume ISO 8601
  105.       var cmtDate = new Date(datePart[0],datePart[1]-1,datePart[2],datePart[3],datePart[4],datePart[5]);
  106.  
  107.       //Calculate difference btw the two dates, and convert to days
  108.       var days = Math.ceil((today.getTime()-cmtDate.getTime())/(one_day));
  109.       if(days > numDays) break;
  110.     }
  111.     var authorUri = "";
  112.     if(entry.author[0].uri && entry.author[0].uri.$t != "")
  113.       authorUri = entry.author[0].uri.$t;
  114.  
  115.     if(excludeMe && authorUri != "" && authorUri == urlMyProfile)
  116.       continue;
  117.     var authorName = entry.author[0].name.$t;
  118.     if(excludeUsers.indexOf(authorName) != -1)
  119.       continue;
  120.  
  121.     var hash=entry.author[0].name.$t + "-" + authorUri;
  122.     if(topcommenters[hash])
  123.       topcommenters[hash].count++;
  124.     else {
  125.       var commenter = new Object();
  126.       commenter.author = entry.author[0];
  127.       commenter.count = 1;
  128.       topcommenters[hash] = commenter;
  129.     }
  130.   }
  131.   if(json && json.feed && json.feed.entry && json.feed.entry.length && json.feed.entry.length == 200) {
  132.     ndxbase += 200;
  133.     document.write('<script type="text/javascript" src="http://'+window.location.hostname+'/feeds/comments/default?redirect=false&max-results=200&start-index='+ndxbase+'&alt=json-in-script&callback=showTopCommenters"></'+'script>');
  134.     return;
  135.   }
  136.  
  137.   // convert object to array of tuples
  138.   var tuplear = [];
  139.   for(var key in topcommenters) tuplear.push([key, topcommenters[key]]);
  140.  
  141.   tuplear.sort(function(a, b) {
  142.     if(b[1].count-a[1].count)
  143.         return b[1].count-a[1].count;
  144.     return (a[1].author.name.$t.toLowerCase() < b[1].author.name.$t.toLowerCase()) ? -1 : 1;
  145.   });
  146.  
  147.   // list top topcommenters:
  148.   var realcount = 0;
  149.   for(var i = 0; i < maxTopCommenters && i < tuplear.length ; i++) {
  150.     var item = tuplear[i][1];
  151.     if(item.count < minComments)
  152.         break;
  153.     document.write('<di'+'v class="top-commenter-line">');
  154.     document.write(replaceTopCmtVars(txtTopLine, item, realcount+1));
  155.     document.write('</d'+'iv>');
  156.     realcount++;
  157.   }
  158.   if(!realcount)
  159.     document.write(txtNoTopCommenters);
  160. }  
  161. document.write('<script type="text/javascript" src="http://'+window.location.hostname+'/feeds/comments/default?redirect=false&max-results=200&alt=json-in-script&callback=showTopCommenters"></'+'script>');
  162. </script>


Script configuration

There are two CSS definitions at first, which can be changed to your liking. After that there comes javascript code and configurable variables. Here is a list of the variables and a short explanation.

maxTopCommenters: how big the list is at maximum
minComments: how many comments must top commentator have at least
numDays: from how many days (ex. 30), or 0 from "all the time" (max 500 comments)
excludeMe: true, if own comments excluded
excludeUsers: array of usernames to exclude
maxUserNameLength: if 0, don't cut; if > 4, cut lenghty usernames

txtTopLine: specifies, what is output on each line. This text can have simple variables, which are: [#], [image], [user], and [count]. [#] is substituted by position on the list, [image] by commentator's avatar image, [user] by commentator name and [count] by number of comments. Text can also contain html.
txtNoTopCommenters: what to display, if list is empty
txtAnonymous: "Anonymous" username localized, or empty if English text "Anonymous" is to be used
getTitles: if true, fetch titles from post feed; if false, titles are generated from url
blogger favico [B]
urlMyAvatar: especially if trueAvatars = false, set here the url to your avatar image
urlMyProfile: if you don't have a profile gadget on page, put your profile url here!
urlAnoAvatar: anonymous avatar, you can change from mystery man to a custom one, if you want, possibly this
urlNoAvatar: comment feed offers the icon (Blogger logo) for those Bloggers who have not set their profile image. You can override the icon with this setting (default: ).

cropAvatar: crop avatar to square (true) or stretch (false) to square
sizeAvatar: size of avatar in x and y direction, pixels

If you have very much comments (thousands and thousands of them), I suggest you to use this as "top commentators of 30 days" gadget or something like that (set numDays variable to 30), so that it won't take too long to load and calculate all the comments.

June 5th 2012: Small CSS update: Blogger changed the paddings of .profile-name-link, that's why I added this line (line 3.):
.top-commenter-line .profile-name-link {padding-left:0;}

August 1st 2017: To fix avatars, please change lines 48 and 49 (article code is updated).
[Hide comments] - [Show comments]
Click on a single comment to hide/show its text

36 comments:

Anonymous said May 2, 2012 at 11:33 PM

WOW! That's what I was talking about. :D
Thank you very much. :)

Ismail Sosse Alaoui said May 3, 2012 at 2:11 PM

Hi admin thanks a lot for this great work.
i want to say that the gadget doesn't on my internet explorer
thanks to answer

MS-potilas said May 3, 2012 at 3:36 PM

@Mr Admin Hi, thanks for the report on IE, reminds me that I always should test on Internet Explorer, too... Sorry about the incompatibility.

I've updated the code in this article to work also with Internet Explorer, lines 31-36 are new (implements indexOf if it does not exist).

Ismail Sosse Alaoui said May 3, 2012 at 11:26 PM

@MS-potilas
thanks MS-potilas for this, and i want to make you knowing that i have the same problem with recent comment...
thanks to answer

MS-potilas said May 4, 2012 at 8:19 AM

@Mr Admin Hi, there's some bug in IE7 emulate mode with feeds with "foreign characters". It can be fixed by editing the template and changing this:

<meta content='IE=EmulateIE7' http-equiv='X-UA-Compatible'/>

to this:

<meta content='IE=EmulateIE8' http-equiv='X-UA-Compatible'/>

Hope it helps. :)

Beben Koben said May 3, 2012 at 7:26 PM

hehehe...it's me, top commentator :D

Taufik Nurrohman said May 20, 2012 at 7:51 PM

Very nice. This is really use the original Blogger feed URL!

Unknown said May 29, 2012 at 11:29 AM

Good sir...you are a genius...:)

Blackswan said June 2, 2012 at 7:53 AM

This is great! Tried installing but my comments are also showing. How can I exclude them? Thks!

MS-potilas said June 2, 2012 at 9:48 AM

@Shirley Tay
Hi, you probably don't have Profile gadget on your blog, so you must set variable urlMyProfile to point to your profile page, like this:

var urlMyProfile = 'http://www.blogger.com/profile/04765892937555860461';

Blackswan said June 2, 2012 at 10:02 AM

Thks for your prompt response! I should've included my link for your reference earlier! I'm not sure what's Profile Gadget but I think I've got one. I'm not tech savvy. Could u kindly take a look at my blog? If I don't have one, do I just copy & paste this "http://www.blogger.com/profile/04765892937555860461" inside the code? Thks so much!

MS-potilas said June 2, 2012 at 11:29 AM

@Shirley Tay
Hi, it seems that with Google plus the profile link leads directly there, so yes, the profile link must be set. Now line 28. reads:


var urlMyProfile = ''; // set if you have no profile gadget on page


Change it to:

var urlMyProfile = 'http://www.blogger.com/profile/04765892937555860461';

That should do it.

Another way to make it block your own comments is to change "someotherusertoexclude" to "Shirley Tay" in line 16, if the profile link thing won't work.

Blackswan said June 2, 2012 at 12:08 PM

Thks again! Slow loading to your blog & the code doesn't load even when I clicked on Download Raw. Will come back later to get the code later & try installing :)

Blackswan said June 3, 2012 at 8:43 AM

Hey, the first method didn't work but the 2nd one works like magic. Chk it out! Thks so much! How can I exclude 2 names? Tried putting punctuation but didn't work. Lol! Pls advise! You've been a great help!

MS-potilas said June 3, 2012 at 12:19 PM

@Shirley Tay

Hi, good you got it working. For more exclusions, try changing the line to this:

var excludeUsers = ["Anonymous", "Shirley Tay", "OtherName"];

(change OtherName to the username you want). If you want still one more, then it looks like this:

var excludeUsers = ["Anonymous", "Shirley Tay", "OtherName", "StillOtherName"];

etc. :)

Blackswan said June 3, 2012 at 3:54 PM

Thks a million! It's working :) U're a genius! Actually, I've been directed by Aratina Cage's blog at Last Comments. I was searching for solution to the Recent Comments which I've installed previously. It worked fine until lately, my comments are showing. Wonder if you can help? I only want to show visitors comments but not mine. Thks again!

MS-potilas said June 6, 2012 at 11:15 AM

@Shirley Tay Hi, I did a hack for my recent comments hack, maybe this is what you're after: Hack for my recent comments hack: don't show own comments. :)

Hiyacynthia said July 2, 2012 at 1:36 AM

I just installed this and I think mine needs some tweaking because I have no avatars or clickable links to my followers. Can you help?
http://www.everydayunderwear.com
I can be reached at hiyacynthia@hotmail.com for going back and forth.

MS-potilas said July 2, 2012 at 10:05 AM

@Cindy Brown
Hi, I think the problem is with Discus commenting system, that you have on your blog. If you look at the comments feed http://www.everydayunderwear.com/feeds/comments/default?max-results=200 the author uri's are missing. So the gadget sees them as non-registered, and have nowhere to link the name/avatar.

I think this could help you: Add Disqus Top Commentators Widget To Blogger Blog :)

Unknown said August 10, 2012 at 7:39 AM

The article is very useful,Thanks for sharing.

Velarah said December 16, 2012 at 8:38 PM

Hmm...seems not to work on my blog. http://www.phinphins.de

The Comments should be displayed in the "Test" gadget, which is an html/js gadget.

Even if I use your raw code, it wont show up, like the gadget isnt function correctly.

Any suggestions?
Thanks for your great work.

MS-potilas said December 16, 2012 at 10:05 PM

@Velarah
Hi, when I looked your blog's html source, it seems that you have only the first 135 lines of the gadget code there, and the rest is missing.

Unknown said December 16, 2012 at 11:39 PM

@MS-potilas

Nah, doesnt know, why copy & paste messed it up.

Thanks for your help

xxx
velarah

Streuterklamotte said April 11, 2013 at 7:20 PM

Thank you so much... I was looking for it since several weeks, because I really like it!
Viele liebe Grüße,
Sabine

Gaby Cortez said September 18, 2014 at 8:12 PM

Hello :)
Great tip, loved it! I'm using in my blog. *-*
http://my-stories-wonderful-books.blogspot.com.br/

Unknown said January 2, 2015 at 12:04 PM

Can anyone tell me how can i reset or update the Top commentators after month. I wan to reset Top Commentators in my Blog...
Blog URL is http://seoonpeak.blogspot.com

Plz Help me....

MS-potilas said January 6, 2015 at 9:15 PM

@Shiv Kumar Gupta
Hi,
You can set the numDays variable:

var numDays = 30;

This way the gadget calculates top commenters only from the last 30 days, older comments are ignored.

Nanda. said May 3, 2015 at 4:50 AM

Hey,
I'm a brazilian blogger and I just came to say Thank you for create this code, it has transformed the way we can interact with our followers. :)
So that's it. I'm really glad to know that r people like u in the world.
Sorry for my bad english and thank u, one more time.
xoxo,
Nanda.
If you feel like you want you, visit my blog:
Nandalandia :D

Beatriz Ramirez said July 20, 2015 at 1:52 AM

Hi!Brazilian here!I loved your gadget! Thank you.
♥ Blog da Mirez

Post a Comment

Related Posts Plugin for WordPress, Blogger...
See the hack
for this dynamic
views icon: