【Blogger】相關文章(Related Posts)
2008-05-22 by tacojohn
進入Web2.0後,標籤(tag)的使用無疑是最具影響力之一的突破。
不同於傳統的樹狀分類,tag的運用可以是一對一、一對多甚至是多對多。
以Blog而言,tag的標示使用便相對的方便且重要了!!
當在觀看一篇特定文章時,能夠自動將相關的文章給列示出來,就可以可讓讀者看到可能同樣有興趣的文章,更可吸引讀者去瀏覽自己其他的文章。
由於Blogger會賦予每篇文章靜態連結網址,所以我們很容易便可透過RSS來達成上面我們要的功能了!!
意即,只要透過文章tag的RSS Feed,抓出所有擁有相同tag的文章,並將之列出(或亂數選擇幾篇)即可。
以下的做法是參考自ABIN'S TECH NOTE,該網站有很多很有用的blogger hack,而且在blogger的基礎教學上也很豐富,是玩blogger的template或是widget一定要去逛逛的好站哦!!
要改之前,請千萬記得要先備份template。
首先,要先在<head>及</head>之間加入下面這一段JavaScript的程式<script type='text/javascript'>
//<![CDATA[
var relatedPostsNum = 0;
var relatedTitles = new Array();
var relatedUrls = new Array();
var relatedDates = new Array();
function RelatedLabels(json) {
for (var i = 0; i < json.feed.entry.length; i++) {
var entry = json.feed.entry[i];
relatedTitles[relatedPostsNum] = entry.title.$t;
relatedDates[relatedPostsNum] = entry.published.$t.substr(0,10);
for (var j = 0; j < entry.link.length; j++) {
if (entry.link[j].rel == 'alternate') {
relatedUrls[relatedPostsNum] = entry.link[j].href;
relatedPostsNum++;
break;
}
}
}
}
function RemoveDuplicatedPosts(PostUrl) {
var tmpUrls = new Array(0);
var tmpTitles = new Array(0);
var tmpDates = new Array(0);
function contains(a, e) {
for(var j = 0; j < a.length; j++)
if (a[j]==e)
return true;
return false;
}
for(var i = 0; i < relatedUrls.length; i++) {
if(!contains(tmpUrls, relatedUrls[i]) && PostUrl != relatedUrls[i]) {
tmpUrls.length += 1;
tmpUrls[tmpUrls.length - 1] = relatedUrls[i];
tmpTitles.length += 1;
tmpTitles[tmpTitles.length - 1] = relatedTitles[i];
tmpDates.length += 1;
tmpDates[tmpDates.length - 1] = relatedDates[i];
}
}
relatedTitles = tmpTitles;
relatedUrls = tmpUrls;
relatedDates = tmpDates;
}
function ShowRelatedPosts(PostUrl) {
RemoveDuplicatedPosts(PostUrl);
var r = Math.floor((relatedTitles.length - 1) * Math.random());
var i = 0;
if (relatedTitles.length > 0) {
document.write('Related Posts: <ul>');
while (i < relatedTitles.length && i < 5) {
document.write('<li><a href="' + relatedUrls[r] + '">' + relatedTitles[r] + '</a> - ' + relatedDates[r] + '</li>');
if (r < relatedTitles.length - 1)
r++;
else
r = 0;
i++;
}
document.write('</ul>');
}
}
//]]>
</script>
可以看到上面,其實是透過JSON去抓取RSS Feed的內容,並且只抓取文章的標題、連結及日期的部份。另外,ABIN前輩還透過RemoveDuplicatedPosts這支程式將文章自身給排除在候選名單之外,更顯得合理,否則在文章內的相關文章還出現自身就有點脫褲子放屁的感覺了!!
此外,在ShowRelatedPosts這支函式中,有兩個部份比較需要注意,一是我用紅色粗體字標示的部份,就是要亂數選取文章的篇數,意即要列出的文章篇數。
二則是document.write的部份,這部份就是要如何顯示在文章內的格式(並非顯示的位置),這兩個部份非常方便讓使用者來修改!!
再來便是要決定何時呼叫上面的函式來抓取文章了。
先找到在文章裡顯示該文所擁有tag的程式,在列出tag的同時,就順便做過濾RSS Feed的動作,避免重新再做一次浪費資源及時間!!<b:if cond='data:post.labels'>
<data:postLabelsLabel/>
<b:loop values='data:post.labels' var='label'>
<a expr:href='data:label.url' rel='tag'><data:label.name/></a><b:if cond='data:label.isLast != "true"'>,</b:if>
</b:loop>
</b:if>
在上面這段程式中的每個迴圈最後,就執行程式去抓取!!
也就是將上面這段程式加入下面藍色的部份<b:if cond='data:post.labels'>
<data:postLabelsLabel/>
<b:loop values='data:post.labels' var='label'>
<a expr:href='data:label.url' rel='tag'><data:label.name/></a><b:if cond='data:label.isLast != "true"'>,</b:if>
<b:if cond='data:blog.pageType == "item"'>
<script expr:src='"/feeds/posts/default/-/" + data:label.name + "?alt=json-in-script&callback=RelatedLabels&max-results=10"' type='text/javascript'/>
</b:if>
</b:loop>
</b:if>
上面這段程式,紅色粗體字則決定了抓取的相關文章的母數,這個數字得大於前面決定的列出文章的數量才行。
當然,這個數字越大相關文章的亂數樣本也越大,也就是相關文章可以顯示越多舊的相關文章。相對的耗費的資源也就多了點。
OK,到這邊基本上都做完了,唯一剩下的部份,就是把結果顯示了!!
顯示的部份,只有一個條件,就是必須在上面這一段程式的後面才能顯示(總得讓程式先抓完資料才有東西可以顯示吧^^)<b:if cond='data:blog.pageType == "item"'>
<script type='text/javascript'>
ShowRelatedPosts('<data:post.url/>');
</script>
</b:if>
好了,儲存後就打完收工啦!!!
上一段藍色的判斷式,是用來判斷目前所在頁面是否在文章的連結內頁。所以如果是加上面的方式做的話,這個顯示相關文章效果,在首頁的文章是看不到的,得要點入文章的內頁連結(當然,那篇文章要有加註標籤被分類過),在顯示標籤的後面才會顯示效果哦!!※參考網站:
.Abin's Tech Note:加入相關文章功能(Related Post)
请问怎样做可以让Related post空一行后才显示?
dear jackie,
我不是很了解您的意思,但試試在最後顯示的code加入一個空行,看是不是您所要的效果。
<b:if cond='data:blog.pageType == "item"'>
<BR/>
<script type='text/javascript'>
ShowRelatedPosts('<data:post.url/>');
</script>
</b:if>