您在這裡

不使用views,如何自訂節點清單顯示頁面

原文連結: http://www.500959.com/node/510
基本上,views和cck是大家都建議用的兩個drupal模組,因為這兩個模組太強大了,一個可以自由定制欄位,一個可以自由過濾資料用以顯示, drupal的許多其它模組都是基於這兩個的。正因其強大,所以也龐大,龐大耗費資源,相對來說,配置起來也較複雜。對於一些把drupal做為個人博客來用的朋友來說,通常不想使用這兩個模組,但drupal預設就只有一種排列文章的方式,按時間發表順序,而bloger們可能就需要有多一些的排列顯示方式。

這個時候可以用查詢資料庫再配合drupal的一些核心函數來達到簡單過濾顯示的目的。舉個例子吧,用習慣了國內cms的朋友,都喜歡在首頁上顯示一些區塊,什麼最新文章、最新推薦、最新評論、熱門文章……

咱們先創建一個page節點,標題就看你的愛好了,隨便取吧。內容呢,就隨便寫段代碼吧:
<?php
echo '嘿羅,世界';//反正一般程式測試都這個套路。
?>
然後在輸入格式裡選擇php code模式,自訂路徑呢,隨便想一個吧,這兒就定義為:index.html。提交保存,這不就一個“嘿羅世界”嗎?別著急,這只是第一步。

現在進入第二步,到“網站資訊(admin/settings/site-information)”中,拉到最後面,把默認首頁設置為咱們剛才創建的頁面路徑:index.html,好,現在打開網站,發現默認首頁就剩“嘿羅世界”了,忽悠人啊這不是。別急,接下來做第三步。

第三步,開始往裡邊添加內容了。我想添加個最新blog文章的列表。drupal區塊裡有個默認的最新blog文章,到區塊中,查看最新blog文章的區塊連結是這樣的:admin/build/block/configure/blog/0,注意最後兩層(blog/0),這很重要。這表示這個區塊是由blog.module生成的第0個區塊(從0開始計數的)。現在我們編輯那篇文章,把裡邊的“嘿羅世界”可以刪除了,放這段代碼進去:
<?php
$block = module_invoke('blog', 'block', 'view', 0);
echo $block['subject'];//顯示區塊的標題
echo $block['content'];//顯示區塊的主內容區。
?>
純粹的引用代碼讓人有些糊塗,解釋一下,module_invoke:載入模組,blog:點名要載入這個;block:區塊,view:顯示。後面的就不難理解了,要顯示這個模組的第0個區塊。就這麼簡單,要直接在文章中插入其它區塊也是這個方法。現在提交保存,到首頁看看,是不是出現了最新blog文章的列表(當然,你得先發表幾篇blog文章)。

我想要顯示其它類型,比如story的最新文章呢?因為默認沒有提供區塊,所以一般的做法呢是用views來過濾出來,但文章一開頭就說了,咱們不用views。這就進入另一個重點部分,讀取資料庫來顯示。編輯文章,在後面插入這段代碼:
<?php
echo '

最新story

';//標題隨意
$result = db_query_range("SELECT n.nid, n.title FROM {node} n WHERE n.type = 'story' ORDER BY n.created DESC", 10);
while ($test = db_fetch_object($result)) {
echo l($test->title,'node/'.$test->nid).'';
};
?>
drupal查詢資料庫語句重新定義過,但基本上和mysql手冊上的方法差不多。完整的手冊請看這兒。現在說我們上面的例子,文章的基本資訊都存儲在node這個表裡,因為我們只要顯示標題清單,所以查詢title和nid欄位,條件呢就是限制為 story類型。你可以把條件改為特定的用戶(uid),或是否推薦(promote)、置頂(sticky),或是否有評論(comment)等等方式。最後是排序,這個例子中我們按節點的創建時間倒序,也就是最新文章在前面,數目限制為10條。下面就是一個陣列迴圈了,在這裡邊可以自行排版,添加 css等。

保存,現在看看效果,最新story文章列表是不是出現了呢?而熱門內容呢,statistics模組也提供了一個按點擊排序的文章列表,我們可以直接用上面插入區塊的辦法把它放到頁面裡。現在我們頁面裡有最新文章、最新推薦、最新日誌、熱門內容、最新評論等區塊列表了,看起來像那麼回事了,接下來的事就是排版了。這個就取決於個人的審美觀了,熟悉css的就用css,不熟悉的就直接用表格套上去就行了。

可以收工了,可我還想有個more,你看大多數網站的列表下面,不都有個more,點擊進去,顯示更多的內容,並且這裡邊的內容還是可以分頁的。好,現在我們來解決這個問題。還是舉例子吧,也想不到其它更好的手段了。先在首頁的清單下麵加個more連結:
<?php
echo '

最新story

';
$result = db_query_range("SELECT n.nid, n.title FROM {node} n WHERE n.type = 'story' ORDER BY n.created DESC", 10);
while ($test = db_fetch_object($result)) {
echo l($test->title,'node/'.$test->nid).'';
};
echo '更多';
?>
就這麼簡單?是的,就這麼簡單,哈哈。可怎麼也得加個判斷吧,萬一只有一篇文章,或者只有0篇文章呢,也顯示個“更多”,那多傻。那就修改一下:
<?php
echo '

最新story

';
$result = db_query_range("SELECT n.nid, n.title FROM {node} n WHERE n.type = 'story' ORDER BY n.created DESC", 10);
if (db_num_rows($result) > 0) {//加入判斷,查詢結果大於0才顯示;
while ($test = db_fetch_object($result)) {
echo l($test->title,'node/'.$test->nid).'';
};
}else {//否則就顯示
echo '沒有文章';
}

if(db_num_rows($result) > 10){//如果大於10篇,就顯示更多連結。
echo '更多';
}
?>
提交保存,有了個“更多”連結,可點選連結不是“找不到頁面”嗎?別急,下一步。創建一個page節點,標題就寫個“新聞列表”吧,輸入格式還是選取為 php code,自訂路徑呢,就要和上面的一致了:story/all。現在要填內容進來了,怎麼把這個最新的story文章清單顯示出來呢?
<?php
echo '

新聞列表

';
$result = pager_query("SELECT n.nid, n.title FROM {node} n WHERE n.type = 'story' ORDER BY n.created DESC", 15);
if (db_num_rows($result) > 0) {//加入判斷,查詢結果大於0才顯示;
while ($test = db_fetch_object($result)) {
echo l($test->title,'node/'.$test->nid).'';
};
}else {//否則就顯示
echo '沒有文章';
}
echo ''.theme('pager', NULL, 15).'';
?>
請注意這一段代碼,和上面其它的對比,有一些變化,首先是db_query_range變成了pager_query,對於有分頁需求的,都使用這個函數查詢。其次當然是下面多了翻頁函數:theme('pager', NULL, 15)。在查詢語句中我們定義了數目是15條,翻頁裡當然也是設置15條。現在保存這個節點,看看,是不是出現了列表,並且有翻頁了(當然,前提是你的 story文章得多於15條,如果不夠多,把15改成2或3試試)。

這個時候可能又會覺得一個清單就顯示個標題,未免太單調了,我還想顯示點作者啊,發表時間啊,評論數目啊,點擊數量啊等等。好吧,咱們來完成這個需求。

<?php
echo '

新聞列表

';
$result = pager_query("SELECT n.nid, n.title,n.comment, n.created,u.uid, u.name,s.totalcount FROM {node} n INNER JOIN {node_counter} s ON n.nid = s.nid INNER JOIN {users} u ON n.uid = u.uid WHERE n.type = 'story' ORDER BY n.created DESC", 15);
if (db_num_rows($result) > 0) {//加入判斷,查詢結果大於0才顯示;
while ($test = db_fetch_object($result)) {
echo '標題:'.l($test->title,'node/'.$test->nid).
'  作者:'.l($test->name,'user/'.$test->uid).
'  評論:'.$test->comment.
'  點擊:'.$test->totalcount.
'  發表時間:'.format_date($test->created).'';
};
}else {//否則就顯示
echo '沒有文章';
}
echo ''.theme('pager', NULL, 15).'';
?>

細心的你肯定發現了,這裡使用了多表查詢,因為節點的點擊量是存放在另外一個表裡的,而作者的資訊又存在users表裡。老套路,提交保存,現在看看列表,是不是多了作者、評論這些資訊。只是排版未免太難看了。那就用css自己調整吧,可我又不想使用css,而且這種清單式的顯示,使用表格更有優勢,方便又快捷。那就用列表吧。這樣改一改:

<?php
echo '

新聞列表

';

$header = array(//這裡增加了,先定義個表格頭部
array('data' => '標題'),
array('data' => '作者'),
array('data' => '評論'),
array('data' => '點擊'),
array('data' => '發表時間')
);
$tablesort = tablesort_sql($header);
$result = pager_query("SELECT n.nid, n.title,n.comment, n.created,u.uid, u.name,s.totalcount FROM {node} n INNER JOIN {node_counter} s ON n.nid = s.nid INNER JOIN {users} u ON n.uid = u.uid WHERE n.type = 'story' ORDER BY n.created DESC".$tablesort, 15);
if (db_num_rows($result) > 0) {//加入判斷,查詢結果大於0才顯示;
while ($test = db_fetch_object($result)) {
//這兒不直接列印,而是定義成一個陣列了。
$rows[] = array( 'data' =>
array(
l($test->title,'node/'.$test->nid),
l($test->name,'user/'.$test->uid),
$test->comment,
$test->totalcount,
format_date($test->created),
),
);
};
}else {//否則就顯示
echo '沒有文章';
}
echo theme('table', $header, $rows);//這兒列印出表格。
echo ''.theme('pager', NULL, 15).'';
?>

提交保存,現在看一看頁面,是不是都在一個表格裡,排版都省了,整整齊齊。這樣就差不多了吧,又有了區塊,又有了列表頁。不過,也許你突然又覺得全是標題列表有也點單調,還想看看摘要顯示是什麼效果。咱們就來把標題清單改為摘要模式,這個更簡單一點,直接使用node_view和node_load,這兩個函數,只要你告訴它節點nid,它就能載入節點的摘要或全文視圖了。省得麻煩,就直接還是用這個新聞列表頁來做試驗吧。編輯節點,放入這段代碼:
<?php
echo '

新聞列表

';
$result = pager_query("SELECT n.nid FROM {node} n INNER JOIN {node_counter} s ON n.nid = s.nid INNER JOIN {users} u ON n.uid = u.uid WHERE n.type = 'story' ORDER BY n.created DESC", 15);
if (db_num_rows($result) > 0) {//加入判斷,查詢結果大於0才顯示;
while ($test = db_fetch_object($result)) {
$output .= node_view(node_load(array('nid' => $test->nid)), 1);//這兒的1或0是全文或摘要。
};
}else {//否則就顯示
echo '沒有文章';
}
echo ''.theme('pager', NULL, 15).'';
?>

注意幾個變化,首先要查詢資料庫的時候,只需要節點nid就行了。其次是在陣列迴圈時,直接用node_view和node_load來顯示出文章。這兒就用不著排版了,全部是按照你在node.tpl.php中定義的樣式來顯示。

現在終於可以結束了,好像在節點組織顯示方面,也沒其它的需求了。上面的內容我是一邊試驗一邊寫下來的,在5.x版本上,應該不會有錯誤。本來準備截圖,嫌上傳麻煩,就沒截了。如果測試過程中有什麼問題,請提出來。顯示需求不是很多,可以使用這種查詢資料庫的方式,如果有許多自訂的顯示需求,建議還是用views,畢竟它內置了緩存,而且和其它模組的互動也更好,當然,用起來也更方便。希望這篇文章對於喜歡drupal,但又不想使用views的朋友有一定的幫助。