2010年11月2日 星期二

Blogger 支援樹狀結構多層次標籤

Blogger 預設的小工具標籤並沒有支援這樣的方式
雖然後來有支援雲端顯示 但是對於結構化整理還是沒支援
當標籤一多的時候 其實很難找到相關的重點了 (平常好好分類標籤也是很重要)

原始的標籤長這樣

網路上有很多人分享類似的改法
不是太難改 就是都拿 javascript 要手動自己加入 不能撈後端的資料
拜託 這也太累了吧 這樣的 blogger 很多 自己搜尋就都可以找到

但也是有找到不錯的 javascript 撈取後端資料的方式
可惜 code 太不直覺 (對於只想改的人倒是沒差 但是我對於非模組化看不懂的 code 拿來用就不喜歡)

首先前置作業要先準備好
1. 一個現成不錯的 javascript 樹狀結構
2. 要怎樣從 blogger 中撈取後端資料? (辦的到嗎)
3. 可是平常打文章的標籤只有一個欄位 夠用嗎??
4. 自己要寫多少 code 把 1/2/3 結合在一起???

第一點就想到從小用到大的那個 dtree 實在經典
先拿來用看看吧
去 Google 打 dtree 就可以找到 dtree網址在這
需要的文件就是裡面的 dtree.js / dtree.css / 跟他預設的 image 檔案
當然你自己有心有創意可以自己再改圖片位置

要怎麼把這邊的 javascript code 加進來
先進入 blogger 修改頁面
設計/修改HTML/展開小裝置範本 (小範本後面會要用到)


如果有網頁空間可以放當然最好 直接把下面的 code 加入在 <head> 裡面就可以
<link rel="StyleSheet" href="http://你的網址/dtree.css" type="text/css" />
<script type="text/javascript" src="http://你的網址/dtree.js"></script>

但是我相信大家幾乎都沒有 那就直接把 code 塞近版面來
把 .css 裡面的內容 前後加上 <style></style> 貼到 <head> 之後
把 .js 裡面的內容前後加上
<script type='text/javascript'>
//<![CDATA[
//]]>
</script>
並且貼到剛剛 </style> 後面

所以最後會變下面這樣
<head>
<style>
dtree.css 內容
</style>
<script type='text/javascript'>
//<![CDATA[
dtree.js 內容
//]]>
</script>

到這邊第一點結束
注意一個地方
在 dtree.js 中有定義圖檔的位置
這邊請改成你網路空間的位置
this.icon = {
root : 'img/base.gif',
folder : 'img/folder.gif',
folderOpen : 'img/folderopen.gif',
node : 'img/page.gif',
empty : 'img/empty.gif',
line : 'img/line.gif',
join : 'img/join.gif',
joinBottom : 'img/joinbottom.gif',
plus : 'img/plus.gif',
plusBottom : 'img/plusbottom.gif',
minus : 'img/minus.gif',
minusBottom : 'img/minusbottom.gif',
nlPlus : 'img/nolines_plus.gif',
nlMinus : 'img/nolines_minus.gif'
};

=======================================================================

第二點要去後台撈資料
因為有加入過 blogger 提供的小工具標籤
研究一下這邊 code 的內容
    <b:if cond='data:display == &quot;list&quot;'>
      <ul>
      <b:loop values='data:labels' var='label'>
        <li>
          <b:if cond='data:blog.url == data:label.url'>
            <span expr:dir='data:blog.languageDirection'><data:label.name/></span>
          <b:else/>
            <a expr:dir='data:blog.languageDirection' expr:href='data:label.url'><data:label.name/></a>
          </b:if>
          <b:if cond='data:showFreqNumbers'>
            <span dir='ltr'>(<data:label.count/>)</span>
          </b:if>
        </li>
      </b:loop>
      </ul>
    <b:else/>
      <b:loop values='data:labels' var='label'>
        <span expr:class='&quot;label-size label-size-&quot; + data:label.cssSize'>
          <b:if cond='data:blog.url == data:label.url'>
            <span expr:dir='data:blog.languageDirection'><data:label.name/></span>
          <b:else/>
            <a expr:dir='data:blog.languageDirection' expr:href='data:label.url'><data:label.name/></a>
          </b:if>
          <b:if cond='data:showFreqNumbers'>
            <span class='label-count' dir='ltr'>(<data:label.count/>)</span>
          </b:if>
        </span>
      </b:loop>
    </b:if>


真難懂 果然沒學過
努力看一下 語法雖然不懂 但是邏輯大概就是
if (data:display == list) // 要用列表的顯示
{
   for (label in data:labels) // 抓取每一項 data:labels
   {
      if (data:blog:url == data:label:url) // 現在網址列的 url 等於現在抓取 label 的 url
         echo(data:label:name); // 就同一頁顯示標籤就好
      else
         echo("<a href=data:label:url>data:label:name</a>"); // 把其他的標籤都給予超連結
      if (data:showFreqNumbers) // 要 show 標籤總和
         echo(data:label:count);
   }
}
else // 雲端顯示
{
   // 不重要了 跟上面差不多 只是差異要改變字體大小
}

所以只需要知道
data:label:url
data:label:name
data:label:count 就夠用了 哈
更詳細的後來有去看 blogger 的一些官方文件
但是其實用不到 以後有熱血再說


到這邊第二點結束
=======================================================================

因為編輯文章的標籤只有一個
自己就定義  以後想分樹狀結構 就要自行拆解標籤
[AAA][BBB]C
想當根目錄的就要弄上中括號 到時候程式再來判斷

到這邊第三點結束
=======================================================================

接下來就是自己寫 code
前面的 dtree 使用方式要先知道
可以看看它提供的範例
d = new dTree('d');
d.add(0,-1,'My example tree');
d.add(1,0,'Node 1','example01.html');
d.add(2,0,'Node 2','example01.html');
d.add(3,1,'Node 1.1','example01.html');
document.write(d);


需要知道的地方只有 d.add
第一個參數是流水號 primary key 要唯一
第二個參數是這個節點的父節點是誰 也就是父節點的 primary key
第三個參數是顯示的名稱
第四個參數是連結
其他參數可參考說明檔

要加的 code 再下面 請加在剛剛 dtree.js script 的下面
這邊是主要演算法的內容
<script type='text/javascript'>
function TAG(label, id, sid, pid, count, url)
{
   this.label = label;
   this.id=id;
   this.sid=sid;
   this.pid=pid;
   this.count=count;
   this.url=url;
}
   
var tag = new Object();
var id = 0;

function add_Tag(tagString, count, url, dir)
{
   var seq_id = 0;
   var pre_id = 0;
   var re_all = new RegExp(&quot;\\[(.+)\\]&quot;,&quot;g&quot;);
   var re_array = new RegExp(&quot;\\[(.+?)\\]&quot;,&quot;g&quot;);
   var m_all = tagString.match(re_all);
   var m_array = tagString.match(re_array);

   for (arrayNumber in m_array)
   {
      var same = 0;
      for (labelNumber in tag)
      {
         if (tag[labelNumber].label == m_array[arrayNumber])
         {
            if (tag[labelNumber].sid == seq_id)            
            {
               same = 1;
               pre_id = tag[labelNumber].id;
               tag[labelNumber].count += parseInt(count);
            }
         }
      }
      if (!same)
      {
         id++;
         tag[id] = new TAG(m_array[arrayNumber], id, seq_id, pre_id, parseInt(count), &quot;&quot;);
         pre_id = id;
      }
      seq_id++;
   }
   id++;
   var final_tag = tagString.substring(m_all[0].length,tagString.length);
   tag[id] = new TAG(final_tag, id, seq_id, pre_id, parseInt(count), url);
}
</script>


然後要改掉原來小工具標籤的內容
找到這段落 (第二點有解釋的部份)
<div expr:class='&quot;widget-content &quot; + data:display + &quot;-label-widget-content&quot;'>
要刪除的地方
<b:include name='quickedit'/>


把中間的 code 都刪除 改成
<script>
d = new dTree(&#39;d&#39;);
d.add(0,-1,&#39;標籤分類&#39;);
</script>
      <b:loop values='data:labels' var='label'>
<script>
add_Tag(&#39;<data:label.name/>&#39;,&#39;<data:label.count/>&#39;,&#39;<data:label.url/>&#39;,&#39;<data:blog.languageDirection/>&#39;);
</script>
      </b:loop>
<script>

for (personNumber in tag) {
d.add(tag[personNumber].id, tag[personNumber].pid, tag[personNumber].label+&quot;(&quot;+tag[personNumber].count+&quot;)&quot;, tag[personNumber].url);
}
document.write(d);
</script>



大功告成 !!!
最後結果會是這樣

8 則留言:

  1. 在網路找了這麼久,這一篇是最棒的BLOGGER樹狀標籤解決方案!

    先感謝大大的研究成果,再來試試使用的結果~

    回覆刪除
  2. 愣大,我測試完了,在OPERA與FireFox下均正常,但是在最多人使用的IE下完全錯亂了...雖然我非常討厭IE,但是偏偏IE是最多使用者的瀏覽器,還是必須顧慮網頁在IE下的使用效果。

    我將愣大的BLOG用 "IE8" 來瀏覽,出現的情形與我BLOG是相同的,所有分類都跑到第一個分類去了,而且還是第一個分類的第四層。請愣大有空研究一下吧~~

    回覆刪除
  3. 啊 到現在才發現這個留言
    補一下 在我的 IE8 確實也存在問題
    整個計算都錯了 ...

    有空再來補判斷吧 Orz
    IE 真麻煩 ... (疑 我以為 IE 沒什麼人在用了)

    回覆刪除
  4. 愣大 可以到後台設定,有留言時自動寄信到你的 email 信箱,這樣就可以隨時知道 Blog 的留言了。

    另外,我直接 hack 原始程式碼,寫出了兩層的樹狀結構標籤,有興趣可以到我的 Blog 看看:

    讓Blogger的標籤能樹狀分類

    這樣子不管任何瀏覽器都沒問題了。

    回覆刪除
  5. 愣阿批居,您好。感謝分享。請問文章分類open all | close all的js該如何編寫?謝謝。

    回覆刪除
  6. 文章分類open all | close all已解決。

    回覆刪除
  7. 感謝 WFU大 告訴我可以到後檯設定
    看過您的 blog 整理的真不錯 又更發揚光大了 XD

    回覆刪除
  8. 請問有辦法三層樹狀分類並且有記憶開合功能嗎?因為我看到您目前的樹狀分類應該有用cookie達到有記憶開合功能的效果,不知道這樣的需求是否能達到,謝謝

    回覆刪除

開放匿名留言 請大家注意網路禮儀