2006-11-16

增強標籤分類功能: 標籤雲 (Label Cloud)

最早看到類似標籤雲這種東西是在美味書籤 (del.icio.us)裡面,它是用一目了然的顯示方式用來列出所有你做分類的書籤群組、並且用字型顏色和大小來 highlight 群組內的數量,應用在 Blog 標籤 (Label) 上面,一方面可以列出所有分類的標籤、以及被標註的文章數量,方便讀者去找同類型的文章,另一方面可以知道這個 Blog 裡面哪類的文章最多最熱門,也可以提供閒逛的讀者參考。所以我就找來取代 Sidebar 上預設的標籤列表,並且作了一些調整和修改。

修改之前,先確定 Sidebar 上面要已經有標籤 (Label) 的網頁元素(如果沒有記得先加入:範本 Template -> 網頁元素 Page Elements -> 選定 Sidebar 加入網頁元素 -> 標籤 -> 加入 Blog)。我把參考來的作法分類處理了一下,切成三段修改:第一段是關於 CSS 樣式的部分,用來顯示 Label Cloud 裡面文字置中和行距之類的,第二段是 Javascript,實際上用來顯示排序和更改標籤的字型顏色和大小,最後一段是在標籤的 element 裡面 (widget),作為呼叫 Javascript 函示的進入點。

第一個步驟,打開樣版文件 Template,找到 CSS 樣式定義的部分,插入下面的定義:

/* Style for Label Cloud */
#labelCloud {
  text-align: center;
}

#labelCloud .label-cloud li{
  display: inline;
  background-image: none !important;
  padding: 0 5px;
  margin: 0;
  vertical-align: baseline !important;
  border: 0 !important;
}

#labelCloud ul{
  list-style-type: none;
  margin: 0 auto;
  padding: 0;
}

#labelCloud .label-count {
  padding-left: 0.2em;
  font-size: 9px;
  color: #777;
}

接下來,找範本的 </head> 標籤,把下面幾行 javascript 貼到該標籤的前面(如果已經有自訂的 Javascript 函示,可以只貼 <script> 標籤內的那些段 function 進去)。請注意,紅色的部分是需要自行調整的,標籤的字型顏色或大小和網址請根據自己的 Blog 樣式來更改。

<!-- User defined inline javascript -->
<script language='javascript' type='text/javascript'>
<!-- Functions used for Label Cloud: adjustLabel(), generateLabels()-->
var labels = new Object;
function adjustLabel(min, max, weight, total) {
  if (min &gt; max)
    var temp=(min-max)/Math.log(total), result=min-Math.floor(Math.log(weight)*temp);
  else
    var temp=(max-min)/Math.log(total), result=Math.floor(Math.log(weight)*temp+min);
  return result;
}  

function generateLabels(){
  var blogURL = '';
  var maxFontSize = 18;
  var minFontSize = 11;
  var maxColor = [204,204,204];
  var minColor = [119,119,119];
  var showCount = true;
 
  var labelColor= [];
  var labelSize = 0;
  var labelCount = new Array(); 
 
  for (var i in labels)
    if (!labelCount[labels[i]])
      labelCount[labels[i]] = new Array(labels[i])
 
  total = labelCount.length-1;
  section = document.getElementById('labelCloud');
  ul = document.createElement('ul');
  ul.className = 'label-cloud';
 
  for(var tag in labels) {
    for (var i=0; i &lt; 3; i++)
      labelColor[i]=adjustLabel(minColor[i], maxColor[i], labels[tag], total);
   
    labelSize = adjustLabel(minFontSize, maxFontSize, labels[tag], total);
    li = document.createElement('li');
    li.style.fontSize = labelSize+'px';

    a = document.createElement('a');
    a.title = labels[tag]+' articles with Label: '+tag;
    a.style.color = 'rgb('+labelColor[0]+','+labelColor[1]+','+labelColor[2]+')';
    a.href = blogURL+'/search/label/'+encodeURIComponent(tag);
   
    if (showCount) {
      span = document.createElement('span');
      span.innerHTML = '('+labels[tag]+') ';
      span.className = 'label-count';
      a.appendChild(document.createTextNode(tag));
      li.appendChild(a);
      li.appendChild(span);
    }
    else {
      a.appendChild(document.createTextNode(tag));
      li.appendChild(a);
    }
    ul.appendChild(li);
    ul.appendChild(document.createTextNode(' '));
  }
  section.appendChild(ul);   
}
</script>

第三步,修改網頁元素 (Page Element)。如果你開啟 Template 並編輯 HTML 時沒有展開 widget (小裝置?!),搜尋範本裡的下面這一行(如果你改過 Title,那麼下面紅色的字串就不一定是 Labels):

<b:widget id='Label1' locked='false' title='Labels' type='Label'/>

把它用下面的代碼取代:

<b:widget id='Label1' locked='false' title='Labels' type='Label'>
<b:includable id='main'>  <!-- Add Label Cloud -->
  <b:if cond='data:title'>
    <h2><data:title/></h2>
  </b:if>
  <div class='widget-content'> 
  <div id='labelCloud'/>
    <script type='text/javascript'>
      <b:loop values='data:labels' var='label'>
        labels[&quot;<data:label.name/>&quot;] = <data:label.count/>;
      </b:loop>
      generateLabels();
    </script>
    <noscript>
      <ul>
      <b:loop values='data:labels' var='label'>
        <li>
          <b:if cond='data:blog.url == data:label.url'>
            <data:label.name/>
          <b:else/>
            <a expr:href='data:label.url'><data:label.name/></a>
          </b:if>
          (<data:label.count/>)
        </li>
      </b:loop>
      </ul>
    </noscript>
    <b:include name='quickedit'/>
  </div>
</b:includable>
</b:widget>   

如果編輯的範本有展開 widget,那就是取代掉上面那一行一直到標籤 </b:widget> 裡面的內容。建議當你有多個標籤和很多文章以後再使用這個功能,不然效果會不顯著。

參考文章:
[筆記]標籤雲(Tag Cloud)
Blogger V3.0:添加标签云

回應: 67

提到...

你好~
想請教一個問題,就是我做好lable cloud,不過點選下去,顯示無法開啟該頁面,請問你知道問題在哪裡嘛?

Abin 提到...

沒看到你的頁面,所以也不知怎麼回答起。
程式的原理,是利用 blogger 提供的分類標籤資料,透過 Javascript 去改造,產生 Label Cloud 的效果。如果您的標籤雲有做出來,看起來是正常的,只是連結有誤,可以先檢查原始碼看連結錯在哪裡。
Cloud 的連結產生是在函示 generateLabels() 裡面,Javascript 倒數第二十行(a.href = ...),可以從那邊著手 Debug 看看。

Lung-Chang Chien 提到...

我使用你所提供的標籤雲功能,大致上沒有太大的問題,但點選進去某個標籤裡面之後,原本「文章縮排」的功能就消失了,導致所有文章全部展開。我其實只想像你的標籤雲一樣,點選進去後只出現文章的標題。不知道該怎樣設定比較好?謝謝~~~

Abin 提到...

你的問題和「標籤雲」是兩回事,這牽扯到另外一個 Hack。
我整理了另外一篇文章,在這裡,你可以參考我標籤和搜尋的頁面是怎麼只列出標題的。

:: misty :: 提到...

非常感激~我成功啦^^
謝謝大大分享~

James 提到...

作者已經移除這則留言。

James 提到...

您好,請問安裝完後,在firefox可以正常執行lable cloud,而在ie下卻無法正常執行,可否有解決方法?
http://flytoback.blogspot.com/

Abin 提到...

我幫你檢查過程式碼看不出錯誤,我有懷疑的狀況,不過可能要靠你自己解決。
你的文章數量太少。因為 Label Cloud 的字型大小和顏色會靠文章數量去做權重,你的 Blog 只有三個標籤,偏偏每個標籤都只有一篇文章,計算權重的時候在 IE 發生問題(瀏覽器算錯),因此該 Javascript 計算到第二個標籤權重時就死掉了。我建議你多發表一些文章,每個標籤所屬文章的數量「分出高下」,看看問題會不會解決。

James 提到...

嗯...很有可能!因為我其他的blog的cloud皆能正常運行,因此很可能如您所說的問題!感謝您的幫忙!

漂流手記 提到...

你好,我把你的程式作了少許修改,和 Neo 版型結合,效果很棒 !!

http://blurkerlab.blogspot.com/2007/08/neo.html

Davin 提到...

感謝您詳細的教學分享!

bias / 小掰同學 提到...

請問 abin 大大,我之前曾經按部就班依照教學成功掛過標籤雲,但有次在修改版型時不知為何所有網頁元素都只剩標題,叫回 XML 存檔還是救不回來,然後我的標籤雲從此就再也掛不回去了...

我找不出為什麼,也想不起當初又是如何一次直接成功掛好標籤雲的。可以救救我嗎?

GG瑋 提到...

today notebook(23) <- ()的數字要如何刪去?標籤雲裡面的標題都有數字XD

Abin 提到...

To GG瑋:
文章裡面不是有提到,「紅色的部分是需要自行調整的」,其中有一個參數:
var showCount = true;
如果你不需要「數字」,請把上面的參數設成:
var showCount = false;

木白柏 提到...

不好意思..
想請問一下..我已經忘了是在你這用標籤雲的
還是在別的地方
我自己用火狐看標籤雲是有顯示
不過我BLOGGER標籤有兩篇文章
他只顯示1篇的數字
然後IE就都沒顯示..
但是別人說他用火狐跟IE都沒看到標籤雲
好像是最近才變的怪怪的
一開始用的時候明明好好的
麻煩可不可以幫我看一下
我很想把它弄好.
謝謝!!

Abin 提到...

To 木白柏:
我看不到你 Blog 裡有標籤雲,也不知道你的問題在哪裡。我想你應該不是用我的標籤雲,因為我之前用的標籤雲也有 IE 看不到的問題,後來我才改成現在這一版。

木白柏 提到...

因為後來我ㄧ氣之下..不用了..所以你就沒看到了..也有可以當時我文章不夠多..不過現在我用你的..已經ok了..出現效果了..謝謝你^^...!!

木白柏 提到...

呃..不過怎麼點標籤雲裡的標籤進去時..文章只變標題..需要展開才能看..要展開不打緊...問題是..展開文章還不完整..請問你知道如何解決嗎?!謝謝!!

Abin 提到...

To 木白柏:
「點標籤雲裡的標籤進去時..文章只變標題..需要展開才能看」、「展開文章還不完整」 -> 那要問你自己了,標籤功能其實是利用 blogger 內建的 search 做出來的,search 的結果,會是只有標題列表、列表展開多少,都是看你自己的樣板如何配置來決定。
這篇文章中有提到,搜尋和標籤的結果如何修改。
變成現在的狀況,是因為你安裝或使用了其他修改樣板的 HACK,要調整,要從你自己裝或修改的部份下手,這一點和標籤雲是沒有關係的。這也是我說要問你自己的原因了。每個版面修改和畫面呈現結果有的彼此之間是有關係的,你要從你自己改過的樣板下手。

momo 提到...

您好,想請問一下,在增加標籤雲的同時,可不可以也保留原來的文章分類?

Abin 提到...

To momo:
可以,你只要在「範本」-「網頁元素」裡,「加入網頁元素」,選擇一個屬性是是「標籤」的元素,就會多一個文章分類的模組,這樣除了標籤雲,你也可以多一個原來的文章分類。

momo 提到...

謝謝您,我按照您的方法完成了。

但...可不可再請教一下,標籤雲和文章分類的分類內容可以弄成不一樣的嗎?

Abin 提到...

To momo:
「標籤雲」基本上就是以「標籤」來分類,請先去瞭解 Blogger 裡面提供哪些預設的「網頁元素」,再找你要的「分類」種類。
像「Blog 存檔」就是「以時間分類」(還可以日、以月),其他應該就沒有了,都要自己做。

momo 提到...

嗯嗯,是我問得不清楚,我是希望把「標籤雲」和原來「文章分類」的「標籤」方式/內容弄成不一樣(這樣講好像並沒有比較清楚...囧)。看來是要自己做了。
謝謝您細心的指點~~

CancerJay 提到...

作者已經移除這則留言。

CancerJay 提到...

對不起,剛剛打錯,重發一篇

請問該怎麼做才可以讓 label 不會斷字,例如我有個標籤叫"生活雜記(2)",因為版面的關係,"生活"在第一行,"雜記(2)"卻跑到了第二行...
我的blog
謝謝!

Abin 提到...

To cancerjay:

換行的問題,不是我們能解決的。從程式上來看,標籤是一個「字串」,不管有沒有「空格」,原理上都不會換行。
瀏覽器上看到被換行的問題影響因素很多,像是瀏覽器設定、版面(側邊欄大小)、字型大小、字串長短,其中字串長短又會因為文章數量加權讓字體變大,你很難去「強制」該標籤不被換行到,程式上能做的已經都做了,除非標籤一行一個、或是字串很短,才能「」儘量」避免。(我的標籤分類也是有被換行的啊)

CancerJay 提到...

我了解了,謝謝你的解說!

Megan 提到...

請問Abin,很高興看到你的部落格,雖然我已經在別人的部落格學到如何使用標籤雲,不過我想要請問你一些其他的問題;為什麼當你在回答別人的意見時,你的意見是別的顏色的,這個功能是要到哪裡做調整呢?謝謝你喔!

Abin 提到...

To megan:
針對作者回應的部份,我有一篇 Hack 的文章介紹,在這裡,你可以參考。

Megan 提到...

非常感謝你的解答,我已經改好了!以後還請你多多指教喔!
還有啊!當我在留意見時,上面有你放的這串字"歡迎隨便亂哈啦留言或發表意見,不過要理性、不做人身攻擊~匿名的朋友,得到 Abin 回應的速度會比較慢喔~",你是怎麼放的?(非常感激)

Abin 提到...

To megan:
這是 Blogger 內建的設定功能,你可能要多摸一下管理介面喔~登入管理介面以後,在「設定」->「意見」的畫面裡,下方有個「意見表單訊息」,裡面就是讓你自己填寫留言時顯示的提示訊息。

Megan 提到...

作者已經移除這則留言。

Megan 提到...

To:Abin
我找到了。
不好意思,這麼簡單的問題還麻煩你,我的確是要去多瞭解一下管裡介面!
Anyway..非常謝謝你!
你的部落格真的很棒,我學到了很多!

憨人阿傑 提到...

看到此部落格有提供很多不錯的部落格教學,但是希望可以貼圖,不然有時候都不知道那些語法做出來是長什麼樣子,所以希望可以貼個圖,這樣我會比較了解那些語法,最後做出來是什麼樣子。

Abin 提到...

To 憨人阿傑:
「所以希望可以貼個圖」?首先,這個 Blog 裡面的文章是我個人的「筆記」,不是「教學」,所以我不會去寫到「老嫗能解」、詳細到讓什麼都不懂的人去「學會」,我沒有義務讓你一定會瞭解(因為部份觀念是需要門檻的),只是經驗分享。
再者,絕大部份的筆記,我都套用在自己的 Blog 上,也就是說,用不著貼圖,我的 Blog 就都有用到(除非是我已經作廢的功能),如果你有仔細看一下,就知道我的 Blog 就是實際的範例(還有原始碼可以參考),這樣絕對比貼圖好吧!

宗諺 提到...

程式碼
var blogURL = 'http://abinlee.blogspot.com';
是做什麼用的呢?
我看了網站
http://phy3blog.googlepages.com/Beta-Blogger-Label-Cloud.html
上是沒有blogURL這一段的
我該採用那一個標籤雲的hack呢?

Abin 提到...

To 宗諺:
該變數的目的,是告訴程式,該透過哪裡的 RSS 資訊來產生標籤雲。你參考的另一個網址,他用的是「相對路徑」: a.href = '/search/label/..',只能用「自己的」blog 內容來做,我用的是「絕對路徑」: a.href = blogURL+'/search/label/..',好處是只要改這個變數內容,你也可以把「別人」的 blog 標籤雲生在你的 blog 裡面(看該變數你設成誰)。
你該採用哪一個標籤雲當然看你自己需要,就原理上兩邊的作法是一模一樣的。不過如果要用我的,記得把該變數內容改成你自己的 blog 網址,不然,標籤雲會變成我 blog 的內容標籤。

Mango 提到...

首先先感謝您無私的教學,讓我這門外漢也可以用出標籤雲的功能,哈!
這裡有個小問題想向您請教一下:關於標籤換色的部分(你所標示紅色的部分),我想更改顏色,不知道該如何下手;因為那邊的格式是var maxColor = [204,204,204];
var minColor = [119,119,119];
是要改[.....]裡面的數字嗎?而如何代表顏色呢?
我只懂六碼的那種~ 囧>

Abin 提到...

To Mango:
是的,如果要修改顏色,就是更改 maxColor & minColor 這兩個陣列變數。
為什麼要定義成三個數字的陣列呢?這是為了用程式做出「漸層色」的效果,這三個數字代表的是 R、G、B 的值,和一般「六碼」的一樣(所謂六碼,其實也是兩個字元為一組、總共三組來表示 RGB 三原色)。轉換方法,只要把你的六碼兩個一組拆成三組,每組是一個「十六進位」的數字,你轉成十進位(小算盤可以轉)再帶進程式裡就好了。
舉例:#FFFF10 = (255, 255, 16)

Mango 提到...

謝謝你清楚的講解喔,我又上了一課了^^

PlanyKao 提到...

你好,我套用了你的程式碼後,文章數多的tag是在下方,文章數少的是在上方。想請問一下,要怎麼將文章數多的tag給排在上面,而文章數少的tag排在下面呢?

PlanyKao 提到...

Orz 忘了修改成以頻率來排序...請自動呼略上方留言....

那山。那人。那國 提到...

你好,我也套用了你的程式碼,真的很有用,謝謝!但是我不知道如何修改以頻率來排序,要改哪裡呢?還有為何我套用出來是有底線呢?要如何去除?

Paine 小不點 提到...

版大,我最近一直在研究怎麼在讓標籤雲更有變化性,不過研究好久沒結果,所以來請教版大。

在我的網頁中,標籤雲是放在main下,我想要讓分類標籤前面有 + 的分類顯示,至於其他用數字開頭的(用數字開頭是因為要做側欄折合分類)不要顯示在標籤雲中。

不曉得版大有沒有甚麼好的方法呢?

感謝你的指導!

flower 提到...

對不起,又來麻煩Abin,
我用了標籤雲,不知為何字體大小沒有變化,我改了級數也一樣。
請問我是不是有那裡設定錯了?

Abin 提到...

To Paine 小不點:
看不大懂你的意思,你是說,某些標籤要出現在標籤雲裡,某些不要?基本上每個標籤是以 li 形式被一個個 appendChild 到 ul 元素中,你只要在 ul.appendChild(li); 這一行前面加一些判斷(例如 tag 的第一個字元是不是數字),合乎條件的才被 append 進去,這樣你不想顯示的標籤就不會被加進標籤雲了。

Abin 提到...

To flower:
你沒有設定錯,只不過,和你「樣板」內對字體大小的定義相互衝突,因此後來對字體大小更改的語法無法生效。每個模組內的樣式變化還是會因為每個人樣板不同而受影響的。
我幫你 debug 了一下,關鍵是你對 sidebar-right 中的連結 a 定義了字型大小固定為 12px,因此標籤雲更改字體大小的程式碼沒有生效。請搜尋你樣板裡這樣一行:
#sidebar-right a{color:#2D8930; text-decoration:none; font-size:12px;}
把 font-size:12px; 這一句拿掉,字體大小就有變化了。不過請你自己取捨,拿掉這一句對你其他 sidebar 模組的字體大小會不會有影響。

flower 提到...

謝謝Abin! 我改好了!...^^

Paine 小不點 提到...

謝謝版大的回覆,您講的正是我要的喔!︿︿

不過我參考了 http://become.wei-ting.net/2008_02_01_archive.html 這個版大的
在ul.appendChild(li);前面加了

if(encodeURIComponent(t).substring(0,3)=='+';) 的判斷,不過沒有用耶~
是不是語法還有哪裡有錯誤呢

Paine 小不點 提到...

你好,我找到錯誤了,原來是多了一個 ;
謝謝你喔~^^

花小豬 提到...

您好,假如標籤是我自己定義的,那文章數要如何讓他顯示在標籤後呢??謝謝^^"

Abin 提到...

To 花小豬:
我不懂你所謂「自己定義的標籤」是什麼,這個 Hack 的作法是透過 Blogger 提供的標籤訂閱功能 (RSS) 去產生標籤雲,這個訂閱功能裡面有變數可以知道該標籤有多少文章,如果不是透過 Blogger 去定義出來的標籤,自然沒有支援訂閱功能,也沒辦法得知文章的數量。

St. 提到...

謝謝您的教學
我更換新模板
參考您的解說
現以搞定
謝謝

Ms. Bonnie 提到...

謝謝你的教學說明
我終於可以變動一下我的Blog啦~

DirtyMan 提到...

很感謝你~我成功了,媽!我真的成功了~呀乎~!!

通達人 提到...

Hi Abin,
請問一下,如果要讓Label Cloud內的每一個Label前都有一個RSS Icon的話,該怎麼作呢?

Abin 提到...

To 通達人:
如果只是要加圖示,很簡單,只要改 label 的 li 標籤樣式就行了。舉例說明,原來我的範例樣式背景是設空白:
#labelCloud .label-cloud li{
...
background-image: none !important;
只要把 background-image 改成你要的圖示,像這樣:
background-image: url(圖示網址) !important;
就行了,至於圖示的位置和對齊問題,自己依照情況改像 padding 和 vertical-align 後面的參數值。

通達人 提到...

Hi Abin,
謝謝你這麼快回應,但是我不只是要加icon這麼簡單,還要加RSS Feed,我看到的範例是這個:
http://angelo-nmb.blogspot.com/2007/01/rss.html
但我發現這個使用的不是Feedburner的RSS Feed,所以有點傷腦筋怎麼整合呢!

Bryan 提到...

Blogger後台已經新增「標籤雲」顯示功能,提供給大家參考。

Yuki 提到...

請問為什麼標籤雲不能顯示特殊符號呢?像是我標籤打♪,標籤也顯示正常,但是在標籤雲上就會變成♪.非常感謝.

Abin 提到...

To Yuki:
這是特殊字元在做字串轉換時發生的 Bug,我研究了一下還挺棘手的,如果你一定要用這類特殊符號當標籤,建議你先用官方版的標籤雲頂一下。

Yuki 提到...

這樣阿...我是比較不喜歡官方的標籤雲旁邊會顯示數啦,但也只能妥協了.非常感謝Abin大的回答.是說你的文章淺顯易懂真的幫了我很多忙也讓我學到了很多東西.真的非常感謝^^

白花花 提到...

樓上啊~官方標籤現在可以自己決定要不要顯示文章數目囉

Abin 提到...

To Yuki:
是啊!記得取消勾選「顯示每個標籤的文章數」就不會有數量了。

Wendy 提到...

請問現在新的格式也適用嗎?!我還是不太懂耶>_<

J.C. 提到...

您好,不曉得版主還有沒有follow這邊的留言,有一關於Google搜尋標籤的問題想請教。

多篇文章,每篇均含有3個以上label,如要以其中2個label為條件顯示搜尋結果,請問如何修改template。

原thread如下:
expr:href='data:blog.homepageUrl + "search/label/China"'

欲搜尋同時包含China及labor標籤的文章。

感恩!

張貼留言

歡迎留言或發表意見,不過要理性不做人身攻擊。匿名的朋友得到回應的速度會比較慢喔~
發問相關的禮貌和規矩請先參考這篇文章,不當留言、和本文無關的回應可能會被直接刪除無視喔!