您在這裡

根據node的term開啟相同term的條列block,並且隨著點選node調整block的內容

senkao's 的頭像
senkao 在 2010-02-05 (週五) 14:19 發表

  在網站中,用 Views 建立一個區塊(block),專門條列出某個 term 最新的 node title,例如有個 term 叫「新聞」,而區塊叫「最新新聞」,則這個區塊就是顯示最新的十條新聞標題。現在想要做個功能出來,當使用者點其中一篇node,則區塊就變成以此 node為中心,列出前後幾篇的新聞,每次點選不同的新聞,則條列的新聞也會跟著調整。要如何做呢?下面開始介紹:   首先新建一個區塊,區塊的說明及標題自行設定,在區塊內容中貼上:

<?php if ( arg(0) == 'node' && is_numeric(arg(1)) && ! arg(2) ) { $nodeId = arg(1); } if ($nodeId<1){$nodeId=1;} $sql = "(SELECT nid FROM node INNER JOIN term_node ON node.vid = term_node.vid WHERE term_node.tid = 13 AND node.nid > ".$nodeId." ORDER BY nid ASC LIMIT 0,4) UNION (SELECT nid FROM node INNER JOIN term_node ON node.vid = term_node.vid WHERE term_node.tid = 13 AND node.nid <= ".$nodeId." ORDER BY nid DESC LIMIT 0,6) ORDER BY nid DESC"; $result = db_query($sql); WHILE ($data = db_fetch_object($result)){ $node = node_load($data->nid); if ($node->nid == $nodeId){ echo "".$node->title."
"; }ELSE{ echo l($node->title, "node/".$node->nid)."
"; } } ?>

「13」是我要特別挑選出來的 term 的 id,改成想要的term id即可。而這個是直接去資料庫撈資料出來,應該還有更方便的方法,不過我還沒有研究出來。上面這段程式碼是先取得目前顯示的 node 的 nid,再由 nid 去抓標題,抓取的原則是現在的node往前取4個(nid 大於現在的),往後取6個(nid 小或等於現在的)(限定在同一個 term id 的 node),加上現在的總共十個node,排序是以 node id為主。   接下來是設定區塊顯示的時機,在區塊設定的地方,最下面有一個「特定頁面的顯示設定」,點選第三個 PHP模式,然後貼上下面的程式碼到文字方塊中: <?php $match = FALSE; if ( arg(0) == 'node' && is_numeric(arg(1)) && ! arg(2) ) { $nodeId = arg(1); } if ($nodeId<1){$nodeId=1;} $sql = "SELECT term_node.tid AS tid FROM node INNER JOIN term_node ON node.vid = term_node.vid WHERE node.nid = ".$nodeId; $result = db_query($sql); WHILE ($data = db_fetch_object($result)){ $tid = $data -> tid; if ($tid == 13){ $match = TRUE; } } return $match; ?> 「13」也要改成特定的term id。上面的程式碼是取得 node 的 nid,再去資料庫抓該 node 的 term id,當此 term id 與你設定的 term id 相同時,則顯示此區塊。因此,我們也可以利用相反的設定($match的參數互換),來關閉特定的區塊,這樣就可以做到兩個區塊的切換動作了。   由於這種作法是直接去抓資料庫裡的資料,不清楚這樣的作法是否會有風險,所以使用時請注意。 同步分享於我的部落格

想詢問在node資料表中的vid是什麼

人人把心中的愛發揮出來,就能凝聚善的福業,形成善的循環。 (靜思語錄)

我在想, 用views 的arg 應該是可以做到大部份, 只是 "前4後6" 的node 要用兩個node 處理 (或者都是樓主的custom code 好一點)

但留意, sql 的寫法是使用 %d, 而不使用直接 . 的方法, 防止 sql injection 攻擊 http://api.drupal.org/api/function/db_query/6

又, 避免使用 php code 在 block 的 description 之內, 詳見: Poor-ly structured Drupal site ever seen

Joetsui's blog

nid:節點的唯一標別id。
vid:節點的唯一修正版本id。

好像是建立了一個內容類型自動參生了一個nid於node和node_revisions~之後當它於node_revisions資料表產生一個node後~
它會生成了一個vid並丟到node的資料表中的vid~

>w<不知是不是這意思呢?

有查到這有比較多的資料~http://blog.csdn.net/g089h515r806/archive/2008/02/24/2116943.aspx

人人把心中的愛發揮出來,就能凝聚善的福業,形成善的循環。 (靜思語錄)

vid 就是 node 的版本 id
不過要開啟版本修訂之後
每次更新 node 的時候才會產生新的 vid

通常整個站都沒用到修訂版本功能的話
nid 和 vid 就會變成一致
所以才會看不出來 vid 和 nid 有什麼差別

node.nid => node ID
node.vid => node revisions ID
term_node.vid => The {node}.vid of the node
term_node.tid => term ID

比較不確定的是 term_node.vid
這個到 drupal 6 才加的欄位
查了一下 taxonomy.install 裡建立 term_node 資料表的資料
term_node.vid 的欄位說明是 The {node}.vid of the node
所以應該是用來對應 node revisions ID

所以像分類也是一樣的道理
都有其相對應的nid和vid~

人人把心中的愛發揮出來,就能凝聚善的福業,形成善的循環。 (靜思語錄)

請教 joetsuihk:

你點出了安全性的問題,而這也是我所擔心的部份。

根據你的連結,我相信建一個模組是最好的,不過我沒有經驗,還要再研究。
而你所提到的「%d」是否是由模組所傳進去的參數?還是指其他的東西?
我想%d=13(選定的term id)應該沒錯吧?
還有node 及 term_node table name是否要改為{node}及{term_node}呢?

上面的code是我google之後拼湊出來的,至少可以work,
但安全性的部份就不知道了,能請你多指點一些嗎?

指點不敢當, 交流一下, 例如:
<?php
//一個變數
$result = db_query('select * from {node} where nid = %d', $node->nid);

//兩個變數 (語意無效, 只是例子)
$result = db_query('select * from {node} where nid = %d and vid = %d', $node->nid, $node->vid);

?>

其實寫一個 hook_block() 的 module 真的不困難, 我下星期會在我的blog 寫一寫的.

Joetsui's blog

%d 這是在 drupal 內撰寫 SQL 語法時應該使用的佔位字(placeholder)
drupal 核心的 db_query 函式的第一個參數為要執行的 SQL 指令
指令中會變動的數值應該使用佔位字取代
凡是遇到佔位字的時候,會從第二個參數以後傳入的資料來取代
db_query([SQL], 替代值1, 替代值2, ...... 替代值 n)
從最左邊的佔位字開始使用第一個替代值
往右的下一個佔位字使用第二個替代值,以此類推
(另一種寫法是第二個參數為所有替代值的陣列 => db_query([SQL], Array(替代值1, 替代值2, ...... 替代值 n)) )

替換資料的過程中
會依照不同的佔位字來驗證傳入的資料
譬如說 %d 表示指定傳入的值為數值
%s 表示傳入的值為字串
同時也會針對隱碼攻擊的部份做處理

另外,drupal 除了要求SQL 指令應該使用佔位字以外
同時也應該使用 大括號 {} 標示資料表 (select * from {node} ...)
這一點也需要注意

謝謝這麼詳細的說明,這樣我懂了。
模組的部份我再研究看看,也期待joetsuihk的大作。
感激啊!