TOP

2020年11月19日 星期四

[Blogger] 顯示相關文章連結

這篇文章記錄如何在 Blogger 的每篇文章下方隨機顯示相同標籤的文章連結,方便使用者快速點選相關文章。這個功能需於主題下修改 HTML 原始碼,在修改前請記得備份。


效果如下:

 

 

流程:

[1] </head> 前加入下面程式碼,可調參數如下:

var numMaxPosts = 10;                         

可顯示最大的文章數量

var strCaption = '隨機相關文章: <ul>';

標題文字

 

<!-- Ankas(相關文章#1): begin -->

<script type='text/javascript'>

      //<![CDATA[

      <!-- Script functions for Related Posts: RelatedLabels(), RemoveDuplicatedPosts(), contains(), ShowRelatedPosts()-->

 

      var numMaxPosts = 10;                     // max. posts

      var strCaption = '隨機相關文章: <ul>';          // caption

      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(strCaption);

          while (i < relatedTitles.length && i < numMaxPosts) {

            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>

<!-- Ankas(相關文章#1): end -->

 

[2] 搜尋字串 data:post.labels,在下方出現的 </b:loop> 前面加入以下程式碼,可調參數如下:

10 為隨機相關文章的亂數樣本數目

<!-- Ankas(相關文章#2): begin -->

<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>

<!-- Ankas(相關文章#2): end -->

 

[3] 搜尋字串 post-footer-line-3 並於下一行加入下面程式碼,可調參數如下:

15 為顯示的字型大小

<br /> 個數為分隔的間隔數

<!-- Ankas(相關文章#3) : begin -->

<div style='font-size: 15px;'>

<br />

<br />

<br />

<b:if cond='data:blog.pageType == &quot;item&quot;'>

  <script type='text/javascript'>

    ShowRelatedPosts(&#39;<data:post.url/>&#39;);

  </script>

</b:if>

</div>

<!-- Ankas(相關文章#3): end -->

  

 

結語/心得:

[1] 程式碼分析

<1> RelatedLabels

<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>

點選文章後,傳入標籤名稱等資訊建構 feed 網址,要求以 json-in-script 方式回傳資料並呼叫 RelatedLabels,而後由 json.feed.entry 逐一取出相關文章的標題網址... 等資料儲存於下面 3 個陣列中:

      ◎ var relatedTitles = new Array();
◎ var relatedUrls = new Array();
◎ var relatedDates = new Array();

 

<2> ShowRelatedPosts

<div class='post-footer-line post-footer-line-3'>

<b:if cond='data:blog.pageType == ";item";'> 

<script type='text/javascript'> 

ShowRelatedPosts(';<data:post.url/>';);

</script> 

</b:if>

</div>

建構 footer-line-3 時會呼叫 ShowRelatedPosts,傳入的 <data:post.url/> 代表目前文章的 URLShowRelatedPosts 先呼叫 RemoveDuplicatedPosts 將重覆出現的文章去除(透過比對文章的 URL),並更新 3 個陣列:

      ◎ relatedTitles
◎ relatedUrls
◎ relatedDates

而後再由更新後的陣列中隨機設定起始 index,取用 numMaxPosts 個文章來建立 HTML 列表元素。

 

[2] JSON feed

這兒的方法主要是使用 json-in-script 為參數傳入網站以取得 json feed 資料後逐一列出。例如:為 [軟體操作] 標籤產生 json feed 所需的網址為:

http://ankas-ni.blogspot.com/feeds/posts/default/-/軟體操作?alt=json-in-script&max-results=10

 

[3] entry.media$thumbnail 並不一定出現於 JSON feed 的資料中:

某些文章會沒有縮圖,即:entry.media$thumbnail 值為 undefined,因此,讀取 url 時需先檢查是否存在:

if (entry.media$thumbnail) {    // 判斷 entry.media$thumbnail 是否存在                  relatedThumbnails[relatedPostsNum] = entry.media$thumbnail.url;
}

 

[4] HTML tips

&#39        

'

&quot        

"

&amp        

&

data:label.name

標籤名稱

 

[5] 上述改動在 Mobile view 無作用

 

 

參考:

免外掛在Blogger加入文字版相關文章

Recent posts with thumbnails


沒有留言:

張貼留言