Friday, January 05, 2007

用 JSON 实现侧边栏的最新评论列表

上个月 21 号 Google 发出消息,声称 GData API 开始支持以 JSON (JavaScript Object Notation,中文介绍) 的形式提供数据,并且给出了对应的 API 文档,同时 Blogger Buzz 网站也告知广大用户,JSON 支持的 GData API 中同样也包括 Blogger。

在这之前,由于 JavaScript 先天的限制,我们不能通过 JavaScript 代码打开当前域以外的远程文件,这也就限制了我们通过传统的 AJAX 技术利用 GData API 的 Atom Feed 来实现 Blogger 页面上最新帖子、评论列表的即使更新,因为我们无法在某个 *.blogspot.com 域名下打开 www.blogger.com 下的 XML 文档。当然,新的 Blogger 支持在自己的域名下,也就是以 yourname.blogspot.com/feeds/ 的形式访问 Atom Feed 解决了这个问题,但是对于通过 FTP/sFTP 发布的非 blogspot 用户,还是无法绕过这个问题。

现在,Google GData API 除了可以在原来的地址后面加 alt=json 参数来以 JSON 的格式组织数据以外,还可以用 alt=json-in-script&callback=myFunction (其中 myFunction 是自己用来处理 JSON 数据的函数) 的方式使得 Feed 返回的 JS 代码内容直接是对 myFunction 函数的调用,这样就绕过了以上 JavaScript 不能远程调用本域以外资源的限制。

通过这个办法,我修改了自己 Blogger 侧边栏的最新评论列表。虽然原来有一个,不过只是根据 Blogger Help 上的这篇介绍开启的,原理还是利用 <Blogger> 标签的循环,只输出评论的部分,也就是说,原来的方法输出的只是当前页面最新评论列表,没有在首页列出的文章,其评论是不会出现的。而且,在默认情况下,评论的排序方式是先按帖子先后顺序,再按时间顺序。我自己另外写了一个 JavaScript 函数来对它们重新排序,并只保留最新的 10 条。

现在,通过 GData API 的 JSON 回调支持,我写了一个真正意义上的最新评论列表。看到这位网友提供了一个 blogspot 用户适用的办法,对于非 blogspot 发布,特别是 FTP/sFTP 发布的用户,可以用我的办法:

<div id="sidebar-recent-comments">
<p id="comment-loading">Loading Data...</p>
<dl id="comments-block">
<dt class="comment-data" name="comment-data">
<a href=""></a><span>, </span>
<span class="comment-poster">
<a href="" rel="nofollow"></a></span>
<span> said...</span></dt>
<dd class="comment-body" name="comment-body"><p></p></dd>
</dl></div>

<script type="text/javascript">

// Fetch the recent comments from Blogger Feed with JSON code and
// the callback func is "dispComments".
function getComments(blogId, counts) {

// Temporarily hide it
var dl = document.getElementById("comments-block");
dl.style.display = "none";

// Retrieve the JSON feed.
var script = document.createElement('script');
script.setAttribute('src', 'http://www2.blogger.com/feeds/' + blogId +
'/comments/default?alt=json-in-script&callback=' +
'dispComments&start-index=1&max-results=' + counts);
script.setAttribute('id', 'jsonScript-recent-comments');
script.setAttribute('type', 'text/javascript');
document.documentElement.firstChild.appendChild(script);
}

// Translate the date
function transDate(dateStr) {
dateStr = dateStr.substring(0, dateStr.indexOf("."));
dateStr = dateStr.replace("T", " ");
dateStr = dateStr.replace(/\-/g, "/");
return dateStr;
}

// Display the comment entries onto the web page.
function dispComments(json) {
var dl = document.getElementById("comments-block");

// get entry template
var dt = dl.getElementsByTagName("dt")[0];
var dd = dl.getElementsByTagName("dd")[0];

dl.removeChild(dt);
dl.removeChild(dd);

for (var i = 0; i < json.feed.entry.length; i++) {
var entry = json.feed.entry[i];
var curDt = dt.cloneNode(true);
var curDd = dd.cloneNode(true);

// Time
curDt.childNodes[0].href = entry.link[0].href;
curDt.childNodes[0].appendChild(
document.createTextNode(transDate(entry.published.$t)));

// Author
curDt.childNodes[2].childNodes[0].appendChild(
document.createTextNode(entry.author[0].name.$t));
if (entry.author[0].uri) {
curDt.childNodes[2].childNodes[0].href = entry.author[0].uri.$t;
}
else {
curDt.childNodes[2].childNodes[0].removeAttribute("href");
}
dl.appendChild(curDt);
dl.appendChild(curDd);

//Content
curDd.childNodes[0].appendChild(
document.createTextNode(entry.title.$t));
}

dl.style.display = "block";
var commentLoading = document.getElementById("comment-loading");
commentLoading.style.display = "none";
}

getComments('yourBlogId', entryCount);
</script>

注意最后一行调用的 getComments 函数的两个参数,yourBlogId 是你当前这个 Blog 的 blogId,每个 Blog 都是不同的。打开自己帖子的评论页面,从 URL 上就可以找到自己的 blogId。第二个参数 entryCount 是要显示的评论条数,例如 10。

另外,为了保持页面整洁,我只使用了评论的第一行,也就是 title 部分的内容。如果需要显示完整,将以上代码中蓝色的 title 改成 content 即可。

为了简洁起见,也可以把 getComments 和 dispComments 两个函数放到外部的 .js 文件中去定义,页面只用引入这个 .js 文件,然后调用 getComments 即可。

14 comments:

Anonymous said...

Hi, i come from Hong Kong. I enjoy visit your blog, it very beautiful.

I would like to ask you something as below:
1). 用 JSON 实现侧边栏的最新评论列表
I copy it to my google blog, (same with you, the domain name is my own domain, but host on blogger.)
But i cannot get the Recent comments result on my blog main page.
* I have already change the 'BlogId', entryCount.

2). I like your comment form, how to do it?
Would you teach me?

Anyways, thank you.

YeeHK

Anonymous said...

Hi!

I would like to do the Comment Form on my blogger.
Would you teach me?

Thanks!

Anonymous said...

Sorry for the late reply.

The JSON side comment bar should work. I've no idea why it doesn't fit your blog. Can you leave an adress of your blog or something so that I can have a look of your code and see what's happening.

Regarding the comment form, actually I've written a servlet and deployed it on my own server, so it may be not so easy so be implemented with bloggger hosting blogs. If you're interested, you can add me on MSN (the address is in my profile) so that we can have further discussion.

Anonymous said...

Gregory, first of all, thank you for your reply.

Thank you for teaching me through MSN. =)

mmjiaxin said...

herve leger dresses
louis vuitton handbags outlet
coach outlet store
ralph lauren outlet
ray-ban sunglasses
kobe bryants shoes
tiffany and co
karen millen uk
coach outlet online
phone cases
rolex uk
nike free 5
swarovski crystal
louis vuitton handbags outlet
ray ban sunglasses
cheap oakley sunglasses
michael kors canada
nba jerseys
mlb jerseys
michael kors handbags
mm1205

xumeiqing said...

20161117meiqing
toms outlet
coach outlet store
polo ralph lauren outlet online
canada goose outlet
michael kors canada
adidas stan smith
ugg australia
coach outlet
gucci handbags
nike cortez

chenmeinv0 said...

michael kors
cheap jordans
timberland outlet
cheap nhl jerseys
kate spade
hermes handbags
louis vuitton
hermes bags
canada goose
ugg official site
hzx20170206

Unknown said...

The NFL Flag for Tennessee Titans is viewable from both sides with the opposite side being a reverse image.Fly this flag with any of our tailgate poles or 6' aluminum flagpoles and adjustable flag brackets.cowboys stars and stripes flags
dallas cowboys house flagsNew York Yankees house divided flags
wholesale Oakland Athletics bannersHouse Divided Flags,
Sports Flags 3x5,
football team flags,
ncaa flags and banners,

Unknown said...

north face outlet
lebron shoes
parada bags
louboutin shoes
longchamp bag
michael kors outlet online
ike air force
michael kors
prada outlet online
air max outlet
20170308huazhen

xjd7410@gmail.com said...

20170513 junda
yeezy boost
burberry canada
cheap jordan shoes
rolex watches for sale
gucci outlet online
ralph lauren outlet
coach factory outlet
fitflops sale clearance
polo outlet
michael kors handbags outlet

Unknown said...

2018612 leilei3915
michael kors handbags
mbt shoes outlet
mulberry handbags
snapbacks wholesale
uggs outlet
christian louboutin outlet
ralph lauren uk
pandora jewelry
michael kors handbags
moncler jackets

jeje said...

jordan 8
fitflops clearance
canada goose jackets
moncler outlet
lacoste polo
kate spade outlet
tory burch outlet
true religion jeans outlet
canada goose outlet
clarks outlet

Unknown said...

www1107
jordans
issey miyake
ugg boots outlet
supreme clothing
asics shoes
pandora jewelry
christian louboutin shoes
canada goose outlet
ugg outlet
nike outlet











Anonymous said...

As for safety, the betting platform is SSL-secured, so gamers can relaxation assured they’re in secure hands here. Our top pick overall is Ignition Casino, featuring broad selection|a wide array|a massive selection} of video games from top providers, engaging bonuses, and the most well-liked cost strategies amongst gamers. While slightly little bit of game information 카지노사이트 and skill might help you win at blackjack, poker, or fantasy sports activities, the “coinflip” video games like roulette and slots are particularly unhealthy for gamblers. If you’re going to gamble and play a game of pure likelihood, anticipate to lose cash.