Friday, March 31, 2006

How to create "Recent Comments"?

本站右邊Side Bar有一段列出本站訪客最近的留言,對追看本站的友好非常有用,有友好見過都詢問怎樣可將之放入自己的blog,以下是一個簡單的介紹。

Blogger.com本身並無提供Recent Comment的選項,幸好Blogger.com的Template可供用戶隨意改動,比其他blog網頁的彈性大得多,坊間也有人提供了在Blogger.com加Recent Comment的Hack程式,本站的Recent Comment即根據其中一個Hack程式改動而成。

先此聲明,以下的程序只適用於Blogger.com的blog,因為它用到Blogger.com伺服器的程式,所以其他的Blog Provider,例如網上行Hompy,Sina,便無能為力啦。

程序非常簡單,首先登入Blogger.com,選擇自己的blog,再選Template然後選擇裡面的Edit current,在這裡你會見到你所用template的程式碼。你只要將下面介紹的兩段程式碼插進原有的template程式碼,再Save,便完成了。要留意的是,以後如果再選用Blogger.com提供的其他template,今次插入的東西便會消失。

以下的程式碼取自這個網址再改動而成:

http://noisetheatre.blogspot.com/2005/11/javascript-implementation-of-recent.html


以上網址有簡單解釋不同段落的程式碼的作用,可供參考。

我的改動主要是改良顯示的模式,變為每個日子的下面顯示所有該日的留言。原本的模式如果要顯示留言日子,便需要每個留言都跟著一個日子,不好看之餘非常浪費網頁寶貴的空間。

第一段程式碼要放入<head>...</head>部份,你可以放在<title>...</title>之後:


<script type="text/javascript" language="JavaScript1.2">
/*
Blogger Recent Comments

Based on the Farrago Recent Comments Hack v1.03
boggerhacks.blogspot.com
(c) 2004 Ebenezer Orthodoxy

Statement: I would GPL the code if the original author would.
Mods by: Robin Parmar
Visit: noisetheatre.blogspot.com

Further modified from noisetheatre.blogspot.com by Ka Lok
*/

// our class
function RecentComments() {
// options to change
this.displayAmount = 10;
this.displayTemplate = '<li>[name]:<br/>[title]</li>';
this.displayPre = '<ul>';
this.displayPost = '</ul>';
this.displayLink = true;

// properties
this.comments = new Array();
this.title = '';
this.itemurl = '';

// methods
this.SetTemplate= rcSetTemplate;
this.SetAmount = rcSetAmount;
this.SetLink = rcSetLink;
this.SetPrePost = rcSetPrePost;

this.SetTitle = rcSetTitle;
this.SetUrl = rcSetUrl;

this.SortDate = rcSortDate;
this.AddComment= rcAddComment;
this.Display = rcDisplay;

// this line uses my date converter method
// this.DateConvert = rcDateConvert;
this.DateConvert = rcDateConvertWithDay;

// comment out the previous line and uncomment the
// next line to use original date format
// this.DateConvert = rcDateConvertDefault;

// or write your own and insert it

this.DateConvertForCommentListDisplay = rcDateConvertWithDayForCommentListDisplay;

}

// simple property setters: these are used by process
function rcSetTitle(x) {
this.title = document.getElementById(x).innerHTML;
}
function rcSetUrl(x) {
this.itemurl = x;
}

// these are used by user to customise
function rcSetTemplate(x) {
this.displayTemplate = x;
}
function rcSetAmount(x) {
this.displayAmount = x;
}
function rcSetLink(x) {
if (x==0) {
this.displayLink = false;
} else {
this.displayLink = true;
}
}
function rcSetPrePost(x, y) {
this.displayPre = x;
this.displayPost = y;
}

// date format converter
// insert your own here depending on the format you use for comment dates
// this one converts from:
// 01 November, 2005 16:35
// to:
// 11/01/2005 16:35:00
function rcDateConvert(dt) {
var s = dt.split(' ');
var d = s[0];
var m = s[1];
var y = s[2];
var t = s[3];

var MonthHash = new Array();
MonthHash['January'] = '01';
MonthHash['February'] = '02';
MonthHash['March'] = '03';
MonthHash['April'] = '04';
MonthHash['May'] = '05';
MonthHash['June'] = '06';
MonthHash['July'] = '07';
MonthHash['August'] = '08';
MonthHash['September']= '09';
MonthHash['October'] = '10';
MonthHash['November'] = '11';
MonthHash['December'] = '12';

// trim off comma
m = m.substring(0, m.length-1);

return MonthHash[m] + '/' + d + '/' + y + ' ' + t + ':00';
}

// date format converter for new date format
//
// this one converts from:
// Monday, November 01, 2005 16:35:00pm
// to:
// 11/01/2005 16:35:00
function rcDateConvertWithDay(dt) {
var s = dt.split(' ');
var d = s[2];
var m = s[1];
var y = s[3];
var t = s[4]+' '+s[5];

var MonthHash = new Array();
MonthHash['January'] = '01';
MonthHash['February'] = '02';
MonthHash['March'] = '03';
MonthHash['April'] = '04';
MonthHash['May'] = '05';
MonthHash['June'] = '06';
MonthHash['July'] = '07';
MonthHash['August'] = '08';
MonthHash['September']= '09';
MonthHash['October'] = '10';
MonthHash['November'] = '11';
MonthHash['December'] = '12';

// trim off comma
d = d.substring(0, d.length-1);

// return MonthHash[m] + '/' + d + '/' + y + ' ' + t + ':00';
return MonthHash[m] + '/' + d + '/' + y + ' ' + t;
}

// date format converter for new date format for display in recent comment list
//
// this one converts from:
// Monday, November 01, 2005 16:35:00pm
// to:
// 01 Nov 2005
function rcDateConvertWithDayForCommentListDisplay(dt) {
var s = dt.split(' ');
var d = s[2];
var m = s[1];
var y = s[3];
var t = s[4];

var MonthHash = new Array();
MonthHash['January'] = 'Jan';
MonthHash['February'] = 'Feb';
MonthHash['March'] = 'Mar';
MonthHash['April'] = 'Apr';
MonthHash['May'] = 'May';
MonthHash['June'] = 'Jun';
MonthHash['July'] = 'Jul';
MonthHash['August'] = 'Aug';
MonthHash['September']= 'Sep';
MonthHash['October'] = 'Oct';
MonthHash['November'] = 'Nov';
MonthHash['December'] = 'Dec';

// trim off comma
d = d.substring(0, d.length-1);

// return MonthHash[m] + '/' + d + '/' + y + ' ' + t + ':00';
return d + ' ' + MonthHash[m] + ' ' + y;
}


// default converter: does nothing
// use if your comment date format is:
// mm/dd/yyyy hh:mm:ss
function rcDateConvertDefault(dt) {
return dt;
}

// given a date string this returns a sorted representation
function rcSortDate(strDate) {
strDate = this.DateConvert(strDate)

var d = new Date(strDate);

var day = '' + d.getDate();
if (day.length==1) {
day = '0' + day;
}
var month = '' + (d.getMonth()+1);
if (month.length==1) {
month = '0' + month;
}
var hour = '' + d.getHours();
if (hour.length==1) {
hour = '0' + hour;
}
var min = '' + d.getMinutes();
if (min.length==1) {
min = '0' + min;
}
var sec = '' + d.getSeconds();
if (sec.length==1) {
sec = '0' + sec;
}
var sortDate = '' + d.getFullYear() + month + day + hour + min + sec;
return sortDate;
}

// adds to global comments array
function rcAddComment(title, url, id, a, datestamp) {
var author = a;
var expt = '';
var st = '';

// grab content of our hidden layer containing all items
var html = document.getElementById('comm' + id).innerHTML;

// strip out whitespace
while (html.indexOf("\n") > -1) {
html = html.replace("\n", "");
}
while (html.indexOf(" />") > -1) {
html = html.replace(" />", "/>");
}
while (html.indexOf(" <a/>") > -1) {
html = html.replace(" <a/>", "<a/>");
}

var htmll = html.toLowerCase();
var pos1 = htmll.lastIndexOf('<br><a></a>posted by');
var pos2 = htmll.lastIndexOf('<br><a></a><a></a>');
var pos3 = htmll.lastIndexOf('<br/><a/><a/>');
var pos4 = htmll.lastIndexOf('<br/><a></a><a></a>');
var aoffset = pos1 + 6;

if (pos3 > -1) {
pos2 = pos3;
}
if (pos4 > -1) {
pos2 = pos4;
}
if (pos2 > -1) {
pos1 = pos2;
aoffset = htmll.lastIndexOf('<a><b> </b></a>');
if (aoffset == -1) {
aoffset = htmll.lastIndexOf('<a><b></b></a>') - 1;
}
}

if (pos1 > -1) {
author = html.substr(aoffset+15, html.length-1);
expt = html.substr(0, pos1-4);
} else {
expt = html;
}
expt = expt.replace(/(<([^>]+)>)/ig, "");

if (expt.length > 50) {
expt = expt.substr(0, 50);
if (expt.lastIndexOf(' ') > -1) {
expt = expt.substr(0, expt.lastIndexOf(' '));
}
expt += '...';
}
expt = expt.replace('"', "\"");
expt = expt.replace("'", "\'");

author = author.replace("<A ", "<a ");
if (!this.displayLink) {
author = author.replace(/(<([^>]+)>)/ig, "");
}

// build a template string of HTML
st = this.displayTemplate.replace('[name]', author);
st = st.replace('[title]', '<a title="' + expt + '" href="'
+ url + '#c' + id + '">' + title + '</a>');

// prefix with date for sorting purposes
st = this.SortDate(datestamp) + st;

// append date for display
// newly added
// st = st + '<br/>(' + this.DateConvertForCommentListDisplay(datestamp) + ')';

// accumulate on our array
this.comments.push(st);
}

function rcDisplay() {
// most recent comments first
this.comments.sort();
this.comments.reverse();

if (this.displayPre.length >0) {
document.write(this.displayPre);
}

// start of new declaration for date header
var latestDate = '';
var revMonthHash = new Array();
revMonthHash['01'] = 'Jan';
revMonthHash['02'] = 'Feb';
revMonthHash['03'] = 'Mar';
revMonthHash['04'] = 'Apr';
revMonthHash['05'] = 'May';
revMonthHash['06'] = 'Jun';
revMonthHash['07'] = 'Jul';
revMonthHash['08'] = 'Aug';
revMonthHash['09'] = 'Sep';
revMonthHash['10'] = 'Oct';
revMonthHash['11'] = 'Nov';
revMonthHash['12'] = 'Dec';
// end of new declaration for date header

for (i=0; i<10 && i < this.comments.length && i < this.displayAmount; i++) {
var s = this.comments[i];

// start of showing date header

if (s.substr(0, 8) != latestDate) {
// if (latestDate != '') {
// document.write('</ul>');
// }
latestDate = s.substr(0, 8);
document.write('<li><i><u>' + s.substr(6, 2) + ' '
+ revMonthHash[s.substr(4, 2)] + ' ' + s.substr(0, 4) + '</u></i></li>');
// document.write('<li><ul>');
}

// end of showing date header

// strips off date prefix
s = s.substr(14, s.length-1);
document.write(s);
}

if (this.displayPost.length >0) {
document.write(this.displayPost);
}
}
</script>



以上的程式碼還有一個地方要注意,它假設blog的Comments的Comments Timestamp Format設定為「Monday, November 01, 2005 16:35:00 PM」的式樣,如果你要用別的設定,便需要修改上面的Javascript程式。

第二段程式碼要插進真正顯示Recent Comment的Side Bar的html碼之中:


<!-- START RecentComments 1.05 -->
<MainPage>
<h2>recent comments</h2>
<script type="text/javascript" language="JavaScript1.2">
var rc = new RecentComments();
rc.SetTemplate('<li>[name]: [title]</li>');
rc.SetPrePost('<ul>', '</ul>');
rc.SetLink(0);
rc.SetAmount(10);
</script>
<Blogger>
<span id="comm<$BlogItemNumber$>" style="visibility:hidden; position:absolute;">
<BlogItemTitle><$BlogItemTitle$></BlogItemTitle>
</span>
<script type="text/javascript" language="JavaScript1.2">
rc.SetTitle('comm<$BlogItemNumber$>');
rc.SetUrl('<$BlogItemPermalinkURL$>');
</script>
<BlogItemCommentsEnabled><BlogItemComments>
<span id="comm<$BlogCommentNumber$>" style="visibility:hidden; position:absolute;">
<$BlogCommentBody$>
</span>
<script type="text/javascript" language="JavaScript1.2">
rc.AddComment(rc.title, rc.itemurl, '<$BlogCommentNumber$>',
'<$BlogCommentAuthor$>', '<$BlogCommentDateTime$>');
</script>
</BlogItemComments></BlogItemCommentsEnabled>
</Blogger>
<script type="text/javascript" language="JavaScript1.2">
rc.Display();
</script>
</MainPage>
<!-- END RecentComments 1.05 -->

1 Comments:

At Sunday, April 02, 2006 12:20:00 am, Blogger Ka Lok said...

你需要檢查你的blog的Comments的Comments Timestamp Format是否設定為「Monday, November 01, 2005 16:35:00 PM」的式樣。別的設定會導致Sort錯Comment。

 

Post a Comment

<< Home