taxonomy

解決樹狀分類層級不明的問題 solving the unknown level of taxonomy trees

Taxonomy 分類是可以多層的, 樹狀的
但有一個很大的問題, 就是 taxonomy_get_term(), node_load() 的時候的分類並沒有有關層的參數
即是, 雖然分類有層級, 但我並不知道這個分類是最頂層, 中間, 還是最底
這個問題一直很困擾, 因為像以下的例子:

  • China
    • Beijing
    • Shanghai

就不能輕易找出"城巿"了

最近找到一個比較可行的方法
1. hierarchical_select
一個方便的功能, 能令你的層級選擇的時候更人性化
我使用的設定是將每一層的分類都儲存, 而不是只是儲存末諯分類

2. content taxonomy
不使用原生的 分類連到 content type
而使用 cck 將 taxonomy 到 content type

3. computed field
最重要, 作用是將從 hierarchical_select 的分類分層, 再每一層記錄分類
如上例中, 需要建立兩個 computed field, 一個儲存國家, 一個城巿
需要有的資料的時候就從 computed field 取出
而不從一般的 taxonomy 最出

實際的代碼:

<?php
$country
= array_slice($node->field_country,-2,1);
$t = taxonomy_get_term($country[0]['value']);
$node_field[0]['value'] = $t->name;
?>

有關 computed field 的使用方法可參考 Computed Field: 在另一個檔案提供代碼算式 compute in file

處理複雜的 taxonomy 和 breadcrumb 關係

我的一個freelance 之中有一個 Drupal 的普遍問題,
breadcrumb 的作用不太大
Drupal 沒有使用分類輸出一個合適的 breadcrumb

以這次的網站做主軸, 舉個例子(只是個簡化的假設例子):
content type 3個: 經濟, 娛樂, 體育
經濟 type 有一個專屬的 vocab, 有terms: 中國經濟, 美國經濟, 歐洲經濟
娛樂 type 有一個專屬的 vocab, 有terms: 香港娛樂, 日本娛樂
體育 type 有一個專屬的 vocab, 有terms: 足球, 籃球

Primary-links 設定:
為了方便系統管理員, 每一個 vocab 都在 primary-links 內有一個自動更新, 實時的連結
也會顯示該vocab 的terms, 含連結
這樣, 新增了terms 便不需要系統管理員更新 primary-links 了
很容易用 taxonomy_menu 完成

(等一下會講解使用 hierarchy 而不使用 default 的原因)

node/* breadcrumb:
但問題是, node/[nid] 頁面,
不會在breadcrumb 自動算出自己的所屬的 vocab, term
只是一句 Home > [title] 帶過
使用custom_breadcrumb 解決
輸出: Home > [vocab] > [term] > [title]

node/* path:
順便使用pathauto, 建立自動路徑:
設定URL: /admin/build/path/pathauto
Node path settings -> Default path pattern
[type-name]/[term-raw]/[title-raw]
連path 都做成同一個結構, 有利 SEO

taxonomy/term/* breadcrumb:
但 taxonomy/term/[tid] 這種頁面比較麻煩
這頁面來自views, 而views 並沒有對breadcrumb 做優化或者建立輸出選項,
所以要自己用 php 動手了
要在頁面使用php, 要先啟用php filter(Drupal 6 預設關閉)
再在 header 或者 footer 使用php code:

<?php
if ( arg(3)!=null){
 
$term = taxonomy_get_term(arg(3));
 
$vocab = taxonomy_vocabulary_load($term->vid);
 
$breadcrumb[] = l(t('Home'),null);
 
$breadcrumb[] .= l($vocab->name, 'taxonomy/term/'.$vocab->vid);
 
$breadcrumb[] .= l($term->name, 'taxonomy/term/'.$vocab->vid.'/'.arg(3));
 
drupal_set_title($term->name);
}else{
 
$vocab = taxonomy_vocabulary_load(arg(2));
 
$breadcrumb[] = l(t('Home'),null);
 
$breadcrumb[] .= l($vocab->name, 'taxonomy/term/'.$vocab->vid);
 
drupal_set_title($vocab->name);
}
drupal_set_breadcrumb($breadcrumb);
?>

這個修改內建的views 有很多要留意的地方:
1. arguments 不使用多個tid 的方式 (taxonomy/term/[tid1] [tid2] [tid3]) 集合為vocab
而使用 taxonomy/term/vid/tid 表示 term
taxonomy/term/vid 表示vocab
因為: SEO, 和難於使用php 判定這 URL 是 term 還是vocab
例如, argument 傳入 中國經濟 和 足球, 使不能判定 vocab 是 經濟還是體育了
使用上面的方法可以令 views 的 "只容許單一tid" 過濾機制來限制這些可能出現的麻煩
可以得出一定正確的 breadcrumb

2.要小心設定argument (tid 為可選)
所以, URL taxonomy/term 是非法的,
vocab id 為必要, "Hide view / Page not found" 選項
第二個argument 為 tid, 因為 taxonomy/term/[vid] 是合法的, 所以
用 "Display all value" 選項

3.手動設定title
也因為 容許 tid 為可選, title 的設定就變得更複雜
不可以單用 tid 或者 vid 為 title,
所以, 用php 設定 breadcrumb 的時候一次連 title 都設定了

總結:
views 的 breadcrumb 處理的確有不完善的地方
這次在header 做 php code 的方法嚴格來說是一個hack
但這已經是最好的方法
估不到的是, taxonomy_breadcrumb 這個模組不太對頭
設定太少, 所以才不用, 要自己動手

[inmediahk] content type 自動 taxonomy link

要實現的功能是 "自動放一個內容類型連結"
例如一個"專欄文章"的node, 便放一個連結到頁尾, 可以連結到"專欄文章列表"
"站外連結"node 便連到"站外連結列表"
難度在於"自動"的一部份
因為taxonomy 是用戶選的
連內建的forum 也需要用戶選擇正確的分類
所以連結不難, 但"自動化"便難

原本打算使用taxonomy, 再自己hack 一下form api, 讓它自動成為某一taxonomy
但後來用了一個更好, 更方便, 但沒有那麼直觀的方法
便是用views 的argument, 配合themes >Read more