回到首頁
章魚約翰的Flickr
關於章魚約翰
回到最上方
留言板
訂閱我的RSS
寫信給章魚約翰
Loading...Please wait...
Feed on
Posts

【Blogger】相關文章(Related Posts)

進入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 != &quot;true&quot;'>,</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 != &quot;true&quot;'>,</b:if>
    <b:if cond='data:blog.pageType == &quot;item&quot;'>
      <script expr:src='&quot;/feeds/posts/default/-/&quot; + data:label.name + &quot;?alt=json-in-script&amp;callback=RelatedLabels&amp;max-results=10&quot;' type='text/javascript'/>
    </b:if>

  </b:loop>
</b:if>

上面這段程式,紅色粗體字則決定了抓取的相關文章的母數,這個數字得大於前面決定的列出文章的數量才行。
當然,這個數字越大相關文章的亂數樣本也越大,也就是相關文章可以顯示越多舊的相關文章。相對的耗費的資源也就多了點。
OK,到這邊基本上都做完了,唯一剩下的部份,就是把結果顯示了!!
顯示的部份,只有一個條件,就是必須在上面這一段程式的後面才能顯示(總得讓程式先抓完資料才有東西可以顯示吧^^)
<b:if cond='data:blog.pageType == &quot;item&quot;'>
  <script type='text/javascript'>
  ShowRelatedPosts(&#39;<data:post.url/>&#39;);
  </script>
</b:if>


好了,儲存後就打完收工啦!!!
上一段藍色的判斷式,是用來判斷目前所在頁面是否在文章的連結內頁。所以如果是加上面的方式做的話,這個顯示相關文章效果,在首頁的文章是看不到的,得要點入文章的內頁連結(當然,那篇文章要有加註標籤被分類過),在顯示標籤的後面才會顯示效果哦!!

※參考網站:
Abin's Tech Note:加入相關文章功能(Related Post)

2 Comments:

    请问怎样做可以让Related post空一行后才显示?

     

    dear jackie,

    我不是很了解您的意思,但試試在最後顯示的code加入一個空行,看是不是您所要的效果。
    <b:if cond='data:blog.pageType == "item"'>
    <BR/>
    <script type='text/javascript'>
    ShowRelatedPosts('<data:post.url/>&#39;);
    </script>
    </b:if>

     

張貼留言

 
子物件比較
20090725 20090726