2009年2月5日星期四

为 Blogger 增加翻页功能

翻页功能,或者叫页码导航(Page Navigation),在 WordPress 中是一个最基本的功能,见于几乎任何一个 WordPress 博客中,而这个基本的功能在 Blogger 平台博客中还不能使用官方的布局功能小工具(Widget)实现。
来自译言的翻页示例

这篇文章摘自 Blogger Accessories。在 Blogger Accessories,博主提供了两种实现方法,分别是修改 HTML 方式Widget 方式。下面将对通过 Widget 为 Blogger 平台的布局模式博客添加翻页功能做下叙述,这种方式相对简便易懂。

首先需要确认,你的 Blogger 博客只有使用“布局(Layout)”才可以外使用这个功能。
打开 Blogger 控制台,进入“布局”标签后,添加一个小工具“HTML/JavaScript”,输入如下的代码:

<style>
.showpageArea {padding: 0 2px;margin-top:10px;margin-bottom:10px;
}
.showpageArea a {border: 1px solid #505050;
color: #000000;font-weight:normal;
padding: 3px 6px !important;
padding: 1px 4px ;margin:0px 4px;
text-decoration: none;
}
.showpageArea a:hover {
font-size:11px;
border: 1px solid #333;
color: #000000;
background-color: #FFFFFF;
}
.showpageNum a {border: 1px solid #505050;
color: #000000;font-weight:normal;
padding: 3px 6px !important;
padding: 1px 4px ;margin:0px 4px;
text-decoration: none;
}
.showpageNum a:hover {
font-size:11px;
border: 1px solid #333;
color: #000000;
background-color: #FFFFFF;
}
.showpagePoint {font-size:11px;
padding: 2px 4px 2px 4px;
margin: 2px;
font-weight: bold;
border: 1px solid #333;
color: #fff;
background-color: #000000;
}
.showpage a:hover {font-size:11px;
border: 1px solid #333;
color: #000000;
background-color: #FFFFFF;
}
.showpageNum a:link,.showpage a:link {
font-size:11px;
padding: 2px 4px 2px 4px;
margin: 2px;
text-decoration: none;
border: 1px solid #0066cc;
color: #0066cc;
background-color: #FFFFFF;
}
.showpageNum a:hover {font-size:11px;
border: 1px solid #333;
color: #000000;
background-color: #FFFFFF;
}
</style>

<script type="text/javascript">

function showpageCount(json) {
var thisUrl = location.href;
var htmlMap = new Array();
var isFirstPage = thisUrl.substring(thisUrl.length-14,thisUrl.length)==".blogspot.com/";
var isLablePage = thisUrl.indexOf("/search/label/")!=-1;
var isPage = thisUrl.indexOf("/search?updated")!=-1;
var thisLable = isLablePage ? thisUrl.substr(thisUrl.indexOf("/search/label/")+14,thisUrl.length) : "";
thisLable = thisLable.indexOf("?")!=-1 ? thisLable.substr(0,thisLable.indexOf("?")) : thisLable;
var thisNum = 1;
var postNum=1;
var itemCount = 0;
var fFlag = 0;
var eFlag = 0;
var html= '';
var upPageHtml ='';
var downPageHtml ='';

var pageCount=5;
var displayPageNum=3;
var firstPageWord = '首页';
var endPageWord = '末页';
var upPageWord ='上一页';
var downPageWord ='下一页';

var labelHtml = '<span class="showpageNum"><a href="/search/label/'+thisLable+'?&max-results='+pageCount+'">';

for(var i=0, post; post = json.feed.entry[i]; i++) {
var timestamp = post.published.$t.substr(0,10);
var title = post.title.$t;
if(isLablePage){
if(title!=''){
if(post.category){
for(var c=0, post_category; post_category = post.category[c]; c++) {
if(encodeURIComponent(post_category.term)==thisLable){
if(itemCount==0 || (itemCount % pageCount ==(pageCount-1))){
if(thisUrl.indexOf(timestamp)!=-1 ){
thisNum = postNum;
}

postNum++;
htmlMap[htmlMap.length] = '/search/label/'+thisLable+'?updated-max='+timestamp+'T00%3A00%3A00%2B08%3A00&max-results='+pageCount;
}
}
}
}//end if(post.category){

itemCount++;
}

}else{
if(title!=''){
if(itemCount==0 || (itemCount % pageCount ==(pageCount-1))){
if(thisUrl.indexOf(timestamp)!=-1 ){
thisNum = postNum;
}

if(title!='') postNum++;
htmlMap[htmlMap.length] = '/search?updated-max='+timestamp+'T00%3A00%3A00%2B08%3A00&max-results='+pageCount;
}
}
itemCount++;
}
}

for(var p =0;p< htmlMap.length;p++){
if(p>=(thisNum-displayPageNum-1) && p<(thisNum+displayPageNum)){
if(fFlag ==0 && p == thisNum-2){
if(thisNum==2){
if(isLablePage){
upPageHtml = labelHtml + upPageWord +'</a></span>';
}else{
upPageHtml = '<span class="showpage"><a href="/">'+ upPageWord +'</a></span>';
}
}else{
upPageHtml = '<span class="showpage"><a href="'+htmlMap[p]+'">'+ upPageWord +'</a></span>';
}

fFlag++;
}

if(p==(thisNum-1)){
html += '&nbsp;<span class="showpagePoint"><u>'+thisNum+'</u></span>';
}else{
if(p==0){
if(isLablePage){
html = labelHtml+'1</a></span>';
}else{
html += '<span class="showpageNum"><a href="/">1</a></span>';
}
}else{
html += '<span class="showpageNum"><a href="'+htmlMap[p]+'">'+ (p+1) +'</a></span>';
}
}

if(eFlag ==0 && p == thisNum){
downPageHtml = '<span class="showpage"> <a href="'+htmlMap[p]+'">'+ downPageWord +'</a></span>';
eFlag++;
}
}//end if(p>=(thisNum-displayPageNum-1) && p<(thisNum+displayPageNum)){
}//end for(var p =0;p< htmlMap.length;p++){

if(thisNum>1){
if(!isLablePage){
html = '<span class="showpage"><a href="/">'+ firstPageWord +' </a></span>'+upPageHtml+' '+html +' ';
}else{
html = ''+labelHtml + firstPageWord +' </a></span>'+upPageHtml+' '+html +' ';
}
}

html = '<div class="showpageArea"><span style="font-size:11px;padding: 2px 4px 2px 4px;margin: 2px 2px 2px 2px;color: #000000;border: 1px solid #333; background-color: #FFFFFF;" class="showpage">第'+thisNum+'页,共'+(postNum-1)+'页: </span>'+html;

if(thisNum<(postNum-1)){
html += downPageHtml;
html += '<span class="showpage"><a href="'+htmlMap[htmlMap.length-1]+'">'+endPageWord+'</a></span>';
}

if(postNum==1) postNum++;
html += '</div>';

if(isPage || isFirstPage || isLablePage){
var pageArea = document.getElementsByName("pageArea");
var blogPager = document.getElementById("blog-pager");

if(postNum <= 2){
html ='';
}

for(var p =0;p< pageArea.length;p++){
pageArea[p].innerHTML = html;
}

if(pageArea&&pageArea.length>0){
html ='';
}

if(blogPager){
blogPager.innerHTML = html;
}
}

}
</script>

<script src="/feeds/posts/summary?alt=json-in-script&callback=showpageCount&max-results=99999" type="text/javascript"></script>
<div style="text-align:right;font-size:10px;color:000000;margin-top:15px;display:none;"> <a href="http://rias-techno-wizard.blogspot.com/2008/07/page-navigation-hack-for-blogger.html">Grab this Widget ~ Blogger Accessories</a></div>

把这些代码粘贴进这个 Widget 之中后,可能并没有完成。

1. 如果你没有使用默认分配的 yourname.blogspot.com 而是自定义域,那么你需要修改一下这个段落:

var isFirstPage = thisUrl.substring(thisUrl.length-14,thisUrl.length)==".blogspot.com/";
代码用来判断当前页面是否为首页,你可以直接改为:

var isFirstPage = "http://www.yourname.com/";

2. 代码中的这些段落可以自行修改:

var pageCount = 5;
这代表了每个页面中文章的数量;这并不一定要与控制台“格式设置”中的“x个帖子在主页上”一致。

var displayPageNum = 3;
代表每次列出的页面数量,默认是 3 个。

3. 如果你的博客并非由 Blogger 托管,那么你可以把上述红色的“<script>”一段改为:

<script src="http://www.blogger.com/feeds/BLOG-ID/posts/summary?alt=json-in-script&callback=showpageCount&max-results=99999" type="text/javascript"></script>
BLOG-ID 可以在控制台的地址中看到。不过,这个地址大概是被伟大的 wall 屏蔽的,如果你在国外,或者不在乎“连接被重置”,则可以一试。
上述第3点有问题,因为不由 Blogger 托管的 FTP 发布的 Blog 根本不能使用 /search?updated-max= 链接。此段内容请略过,抱歉。

完成,你可以按下图中的方法把这个 Widget 挪到文章下方。



大功告成。

最后还要说明这个方式的缺点。
依然是 wall 的问题,它可能会对 blogger.com/feeds/xxx 这个地址较为敏感,有遭遇“连接被重置”的危险。
此外,这个对 json-in-script 的调用明显比没有这个应用时花费了更多时间载入。加上 wall 的干涉,所以不容乐观。

总的说来,这是个 fantastic 的 trick,所以如果您感觉很棒的话,去 Blogger Accessories 感谢这位 Blogger 吧。


UPDATE @ 23:18:
搜索了一下,发现使用传统的模板(Template)依然可以通过 Blogger JSON 的方式获得这个翻页功能,请参见这里的文章
由于所有翻页的功能目前都是依赖 /search?updated-max= 这个 URL 实现的,发布内容均为静态页面的 FTP 发布的 Blogger用户还不能享受这样的功能。

29 条评论:

  1. 不错,就是js代码太长了,会不会影响载入速度?

    回复删除
  2. @虚飞 代码不长,对载入速度影响不大,只是调用的/feeds/posts/summary要视博客而定;我这个blog写得久了,文章多,更是达到1M。所以使用与否需要慎重。

    回复删除
  3. @Rickey 方法基本相同,只是这一个图形化,那个纯翻看代码。

    回复删除
  4. 楼主,很感谢你的分享。
    但是我遇到个问题,就是虽然有7篇文章,但一共只有两页,而且第二页还是空的,这是为什么啊?

    我是新手,blogspot默认配置,没有修改上述任何代码。。。请赐教,谢谢!

    回复删除
  5. @cloudyyty 能看下你的blogspot页面吗,留一下地址。

    回复删除
  6. 我还是不做了,以前我用javascript+CSS控制的翻页,当时我的jQuery这个插件。

    回复删除
  7. @枯言 这个功能之前我还真是没见过,这是头一回。要Blogger官方推出这个功能,估计需要个三年五载了……

    回复删除
  8. 貌似分页对读者体验不太好吧,看篇文章还要翻好几页的

    回复删除
  9. @Elton Disney 啊不,这个是像wordpress那种首页可以查看过去文章的那种翻页,不是一篇文章拆作几页的。

    回复删除
  10. @Marcher

    http://cloudyyty.blogspot.com

    我现在不敢放了。。。请你看看是不是我原来的页面代码有问题?谢谢:)

    回复删除
  11. @cloudyyty

    我试了一下,也发现了这个问题。
    你把上面代码中的这一句:
    for(var p =0;p< htmlMap.length;p++){
    if(p>=(thisNum-displayPageNum-1) &&
    把第一行的htmlMap.length改成htmlMap.length-1。

    回复删除
  12. 感谢博主,终于用上这个功能了,不过又让我好奇的是页脚的那个浮动效果是怎么弄出来的?能否告知,感谢

    回复删除
  13. @开源树 是Google的小工具。参见这里:http://www.google.com/friendconnect/

    回复删除
  14. 请看一下我的博客,不明白问题出在哪里,第四页之后就不再显示了。
    我已经试过修改每页的显示篇数,在三页内时都可以正常显示,一但到第四页就不再显示了,而出现一条没有符合要求的查找结果的字符。
    http://xiaojianriji.blogspot.com

    噢,我用的是修改HTML的方法,我试过加入小物件的方法,当时没注意这一点。现在博客已经改好了才发现。如果需要,我可以把code发过去给你
    谢谢

    回复删除
  15. 更正一下我的留言,我又试了一下。问题在最后两页无法显示。
    博客现有21篇文章,设置主页显示6篇,其他显示4,共显示了18篇,而正常只需要5页,但下面还是出现了6页,后面两页是无效的。我想这是因为程序探测到21篇文章除以每页4篇后得出了6页。但第五页就不再显示文章了。但如果我让每页显示7篇的话,就可以用3页正常显示全部内容。一但超过3页就有问题了。
    好象问题出在显示链接上,但不知道怎么该。请指教了。
    http://xiaojianriji.blogspot.com

    回复删除
  16. 不好意思今天如此打扰你,主要为了说明问题是怎样的。我分别改了试每页1篇时可以显示前15篇,试每页2篇可以显示16,每页3篇或更多最后两页不可显示,当点击倒数第二页的时候,就会自动跳到最后一页并且不显示任何内容。
    很希望能帮助我解决这个问题。我可以发code过去,不过没见到你的邮件地址。先谢谢了

    回复删除
  17. @小子狂简 你把代码发过来看看吧。不过这个代码不是我写的,而且有些复杂……我尽力吧。

    回复删除
  18. 以前试过几个page numeber navigation,可是要不就是不成,要不就是效果不咋地...我也懒得去改他们那些代码了,呵呵~

    回复删除
  19. 按照你博客中的步骤,我完成了blogspot的分页功能。我觉得这个方法最简单了,比起其他的一些实现方法。
    看看我的首页 http://www.hxjqr.com/

    回复删除
  20. 唉,这个插件算法乱七八糟,页面数目都算不对啊,错误多多,特别是对标签页和存档页

    回复删除
  21. 同意LS的觀點。

    在标签页和存档页。能否同時封鎖掉該功能的顯示呢。

    回复删除
  22. @or: 确实如此,@ICKITT说得对。一些情况下,最后会多出一页。
    你的意思应该就只是屏蔽掉存档页的这个翻页链接吧。因为Blogger官方好像就是把search和label页看作相同的。而这两个页面的不少属性都和index页类似。
    要是屏蔽archive页的内容,只需在内容外加上
    < b:if cond='data:blog.pageType != "archive"'>< /b:if>
    多余的空格去掉就好了。

    回复删除
  23. 博主~我想问你,怎么用在Blogger回复评论这个功能???
    我的邮箱是[email protected]!麻烦你了

    回复删除
  24. @Roy: 方法就在我这个blog上,搜索就能找到。给你发邮件了。

    回复删除
  25. 博主我想问一下,我感觉这个代码好像有个问题。我把整个代码都添加进去啦。但当我在首页的时候,我想到第2页,第3页去,可是却总是跳到第4页啦,
    我的var pageCount = 8;格式设置里面的帖子数量也是8,var displayPageNum = 3;使用默认的。
    希望你能给我个解决方法。象这样的话,添加不添加翻页都没效果,还影响速度啦~~希望能早点收到你的答复。
    我的博客地址是:http://softfly365.blogspot.com/

    本人邮箱是[email protected]

    回复删除
  26. @滴泪斩: 抱歉,其实我对json不怎么了解,而且有人说这段代码的算法也不太好。如果有问题,还是先停用吧。

    回复删除

请勿张贴商业广告。评论可能需要审核。
No advertisement. Comment review enabled.