Blog外挂之:文章置顶

Blog外挂之:文章置顶

By 刘未鹏(pongba)

C++的罗浮宫(http://blog.csdn.net/pongba)

许多朋友想要文章置顶的功能。比如博客园的这个样子:

Blog外挂之:文章置顶

<shapetype id="_x0000_t75" stroked="f" filled="f" path="[email protected]@[email protected]@[email protected]@[email protected]@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 381pt; HEIGHT: 264.75pt" type="#_x0000_t75"><imagedata o:title="top_posts_demo1" src="file:///C:%5CDOCUME~1%5Cpongba%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.jpg"></imagedata></shape>

图片截自爆牙齿的blog

CSDN blog的用户建议列表里面也有许多人提出这个要求。

那么,在blog系统还没有内建文章置顶支持的时候,能不能自己实现呢?看图:

Blog外挂之:文章置顶

<shape id="_x0000_i1026" style="WIDTH: 415.5pt; HEIGHT: 238.5pt" type="#_x0000_t75"><imagedata o:title="top_posts_demo2" src="file:///C:%5CDOCUME~1%5Cpongba%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image002.jpg"></imagedata></shape>

博客园的文章置顶功能是将置顶文章放在首页的顶端但每篇独立的文章里面并不能看到置顶文章。鉴于用户绝大多数时候访问的并非首页而是某篇特定的文章,所以把置顶文章框放在每篇文章而不是首页的顶部能够取得更好的显示效果

文章置顶的实现

文章置顶的实现其实非常简单。第一步,在该系列第一篇里面提到的准备工作是必不可少的,即把你blog上的文章收藏到一个专门的del.icio.us帐号上(如果你只想实现置顶功能,不想实现站内相关文章的话,那么只收藏你想置顶的那几篇也行)。第二步是将所有你认为应该置顶的文章加上一个名叫“topPost”(名字随你取)的tag第三步就是用javascript显示出来了:

function showTopPosts()

{

var availElem =

document.getElementById('viewpost.ascx_PreviousAndNextEntriesUp');

if(!availElem)return;

availElem.parentNode.insertBefore(

document.createElement('br'), availElem);

var topPostsDiv = document.createElement('div');

topPostsDiv.setAttribute('id', 'topPosts');

availElem.parentNode.insertBefore(topPostsDiv, availElem);

topPostsDiv.innerHTML = '<h1>置顶文章</h1>';

for(var i = 0; i < Delicious.posts.length; ++i){

if(IsIn('topPost', Delicious.posts[i].t)){

topPostsDiv.innerHTML +=

'<a href = "' + Delicious.posts[i].u +

'" style = "font-size:<chmetcnv w:st="on" unitname="pt" sourcevalue="12" hasspace="False" negative="False" numbertype="1" tcsc="0">12pt</chmetcnv>;">' + Delicious.posts[i].d + '<' + '/a>';

topPostsDiv.innerHTML += '<br/>';

}

}

availElem.parentNode.insertBefore(

document.createElement('br'), availElem);

}

showTopPosts();

topPosts这个div的位置在正文post的正上方。原本csdn blog在正文正上方没有带id属性的element,导致定位困难。但最近的修正bug版本加上了一个“前一篇文章|后一篇文章”的div在正文的上方和下方,如图:

<shape id="_x0000_i1027" style="WIDTH: 265.5pt; HEIGHT: 148.5pt" type="#_x0000_t75"><imagedata o:title="top_posts_demo3" src="file:///C:%5CDOCUME~1%5Cpongba%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image004.jpg"></imagedata></shape>

Blog外挂之:文章置顶

这是个有iddividviewpost.ascx_PreviousAndNextEntriesUp(但愿CSDN blog的开发人员不要取消这个div或改这个divid:-))。所以只需定位到这个div,往其上方插入一个新的idtopPosts(这个id待会要用到)的div。再将从del.icio.us获取到的tagtopPost的所有文章插入到这个div中即可。

最后一步是调整topPosts这个div的格式,要想实现截图中的效果,需要在后台加入如下CSS代码:

#topPosts {

border: 1px solid #CCCCCC;

text-align: center;

margin-left: 15%;

margin-right: 15%;

}

h1 {

background: #EEEEEE none repeat scroll 0%;

border-bottom: 1px solid #CCCCCC;

margin-bottom: 10px;

padding-bottom: 5px;

padding-top: 5px;

padding-left: 0px;

}

Further work

这个置顶算法很简单,把所有tagtopPost的链接显示出来就完事了。但这就有一个问题,如果你觉得值得置顶的文章比较多,那么显示在页面上方的置顶框就会很大,影响正文阅读。解决这个问题有一个简单的办法,就是设置一个置顶文章数上限maxTopPostsShown,然后每次从所有的topPost文章中随机选取出maxTopPostsShown个文章显示出来。进一步还可以这么做:基于当前文章的tag,显示与它亲缘关系最近的topPost文章,如果没有就退回到随机选取。如果你的blog有这个需求就自己实现一下吧。

[1] js代码中的Delicious.posts是一个全局对象。通过del.icio.us的开放JSON接口获得。使用方法见这里