.
.
.
之所以沒使用下面這些, 來呈現『相關文章』, 有幾個原因 :
- 無法呈現文章的相關性, 也無法處理重複文章
- Google Ajax Search API 處理的是『關鍵字』, 而非『標籤』
- 另外兩個某種程度上比較像『標籤文章選台器』, 而不是『相關文章』
.
不過, 還是列出它們的效果, 說不定你用得上。
.
.
建議大家先看一下原始版本的『相關文章』做法 (加入相關文章功能, Abin's Tech Note 2007-03-05), 或者是 替Blogger加入相關文章功能(二)(挖哩勒~胡說八道, 2008-06-30)
裡面, 詳細介紹了『相關文章』的做法, 還有程式碼要安裝在模版的什麼地方。
簡單的說, ABIN 的做法如下 :
- 集合A = 目前文章的標籤 * (每個標籤取出10 篇最新的文章, 並且不包含目前文章)
- 集合B = 集合A 的 不重複文章
- 相關文章 = 從 集合B 隨機取出 5 篇文章
.
再來看看我的做法, 不同之處以紅色標示 :
- 集合A = 目前文章的標籤 * (每個標籤取出10 篇最新的文章, 並且不包含目前文章), 並記錄目前的文章有幾個標籤 (labelNum)
- 集合B = 集合A 的 不重複文章, 並順便統計 每篇文章 在 集合A 出現的次數 (relatedStar),
- 集合C = 將 集合B 依 文章次數 排序
- 相關文章 = 從 集合C 依 文章次數, 由多到少列出, 相關度以 relatedStar / labelNum 表示
.
另外, 我還朝減少記憶體 (陣列) 使用量, 和減少迴圈次數的方向改寫, 所以直接就產生 集合B, 而且 集合C 也只是一個『索引』而已。這樣,『理論上』會跑快一點, 只是不知如何測試。
假設你已經安裝完成原始版本的『相關文章』([1] 或 [2]), 只要將 </head> 之前的程式碼整個換成我的版本, 就會有『依相關度排序』的效果。
.
其中的 optionRGB, 請改成適合的顏色設定
var optionRGB = [ {P: 100, R :208, G: 0, B: 0}, {P: 50, R: 255, G: 204, B: 0}, {P: 0, R: 0, G: 64, B: 128} ];
P = 百分比, (R, G, B) = 該百分比的顏色設定。如果介於兩個百分比之間, 則會使用中間色。也可以 增加 或 減少 顏色的組別, 但要維持 P (百分比) 由大到小排列, 還有注意語法即可。
| P | R | G | B |
| 100 | 208 | 0 | 0 |
| 50 | 255 | 204 | 0 |
| 0 | 0 | 64 | 128 |
.
如果不想使用顏色, 則將以下紅色部分刪去, 並注意 myRBG (內含 <span>) 和 </span> 是成對的。
myRBG = spanRGB(myP, optionRGB);
document.write('<h4>' + myRBG);
document.write('相關度 ' + myStars + ' ' + myP + '% 的文章 :</span></h4> <ul>' );
.
如果想用『分數』(例: 3/5 ) 來表示, 可以將灰色部份與前一行替換,
// document.write('相關度 ' + myStars + ' (' + relatedStar[r] + '/' + labelNum + ') 的文章 :</span> </h4> <ul>' );
.
再來是列出的文章總數, 目前是 20 則, 如藍色部分, 可以自行修改
for (var j=0; j<u_IdxNum && j<20 ; j++)
.
尚待努力之處
- 看能不能再增進執行效率
- 將程式主體搬到側邊欄, 縮短文章載入的時間, 之後再插入相關文章的結果
.
</head> 之前的程式碼如下 :
<script type='text/javascript'> //<![CDATA[ <!-- Script functions for Related Posts: RelatedLabels(), RemoveDuplicatedPosts(), contains(), ShowRelatedPosts()--> var relatedPostsNum = 0; var labelNum = 0; var maxStar = 1; var relatedStar = new Array(); var relatedTitles = new Array(); var relatedUrls = new Array(); var relatedDates = new Array(); var u_Idx = new Array(); var u_IdxNum = 0; function RelatedLabels(json) { var regex1=/</g, regex2=/>/g; var entryURL = ""; labelNum += 1; for (var i = 0; i < json.feed.entry.length; i++) { var entry = json.feed.entry[i]; entryURL = ""; for (var j = 0; j < entry.link.length; j++) { if (entry.link[j].rel == 'alternate') { entryURL = entry.link[j].href; break; } } if (entryURL != "") { for (var j = 0; j <= relatedPostsNum; j++) { if (relatedUrls[j] == entryURL) { relatedStar[j]++; if (relatedStar[j]>maxStar) maxStar=relatedStar[j]; entryURL = ""; break; } } } if (entryURL != "") { relatedPostsNum++; relatedTitles[relatedPostsNum] = (entry.title.$t.replace(regex1, '<')).replace(regex2, '>'); relatedDates[relatedPostsNum] = entry.published.$t.substr(0,10); relatedUrls[relatedPostsNum] = entryURL; relatedStar[relatedPostsNum] = 1; } } } function SortRelatedPosts(PostUrl) { for (var j = maxStar; j > 0 ; j--) { for(var i = 0; i < relatedUrls.length; i++) { if (relatedStar[i]==j && PostUrl != relatedUrls[i]) { u_Idx[u_IdxNum] = i; u_IdxNum++; } } } } function spanRGB(myP, PRGB) { var myR, myG, myB; for (var i=0; i< PRGB.length; i++) { if (myP >= PRGB[i].P) { if (i==0) { myR = PRGB[i].R; myG = PRGB[i].G; myB = PRGB[i].B; } else { var P0 = myP - PRGB[i].P; var P1 = PRGB[i-1].P - myP; var deltaP = PRGB[i-1].P - PRGB[i].P; myR = Math.floor( (PRGB[i-1].R*P0 + PRGB[i].R*P1) / deltaP ); myG = Math.floor( (PRGB[i-1].G*P0 + PRGB[i].G*P1) / deltaP ); myB = Math.floor( (PRGB[i-1].B*P0 + PRGB[i].B*P1) / deltaP ); } return('<span >'); break; } } return('<span>'); } function ShowRelatedPosts(PostUrl) { var r = 0; var i = 0; var currStar = 0; var myStars = ""; var myRBG; var optionRGB = [ {P: 100, R :208, G: 0, B: 0}, {P: 50, R: 255, G: 204, B: 0}, {P: 0, R: 0, G: 64, B: 128} ]; SortRelatedPosts(PostUrl); if (relatedTitles.length > 0) { for (var j=0; j<u_IdxNum && j<20 ; j++) { r = u_Idx[j]; if (currStar!=relatedStar[r]){ if (currStar != 0) document.write('</ul>'); currStar = relatedStar[r]; myStars = ""; for (i=0; i<currStar; i++) myStars = myStars + '★'; var myP = Math.floor(100*relatedStar[r]/labelNum); myRBG = spanRGB(myP, optionRGB); document.write('<h4>' + myRBG); document.write('相關度 ' + myStars + ' ' + myP + '% 的文章 :</span></h4> <ul>' ); // document.write('相關度 ' + myStars + ' (' + relatedStar[r] + '/' + labelNum + ') 的文章 :</span> </h4> <ul>' ); } document.write('<li><a href="' + relatedUrls[r] + '">' + relatedTitles[r] + '</a> - ' + relatedDates[r] + '</li>'); } if (currStar != 0) document.write('</ul>'); document.write('== 以上 ' + j + ' 則 ==, <a href="http://eucaly61.blogspot.com/2008/07/related-posts-with-correlation.html" target="_blank">相關文章及相關度說明</a>'); } } //]]> </script> |
.
.
至於『隨機文章』, 可以參考底下的做法, 將它的精神改寫到 ABIN 的程式裡面。
Blogger Feeling Lucky Widget (Random Post)
- 按鈕呼叫 feelingLucky()
- feelingLucky()
/feeds/posts/summary?max-results=0&alt=json-in-script 傳給 readLucky()
取得 文章總數, parseInt(feed.openSearch$totalResults.$t,10)
產生 亂數
將 亂數 傳給 fetchLuck()
/feeds/posts/summary?start-index=+亂數+&max-results=1&alt=json-in-script 傳給 showLucky()
秀出文章
.