分享

不使用views,如何自定义节点列表显示页面 | Drupal China

 gaofrank 2008-10-21

这篇文章针对drupal5写的,在drupal6里,有些查询数据库方式改变了,现在做个一些修正,让下面的方法适用于drupal5.x和drupal6.x。

基本上,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 ‘<h2>最新story</h2>‘;//标题随意
$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).‘<br>‘;
    };
?>

drupal查询数据库语句重新定义过,但基本上和mysql手册上的方法差不多。完整的手册请看这儿。 现在说我们上面的例子,文章的基本信息都存储在node这个表里,因为我们只要显示标题列表,所以查询title和nid字段,条件呢就是限制为 story类型。你可以把条件改为特定的用户(uid),或是否推荐(promote)、置顶(sticky),或是否有评论(comment)等等方 式。最后是排序,这个例子中我们按节点的创建时间倒序,也就是最新文章在前面,数目限制为10条。下面就是一个数组循环了,在这里边可以自行排版,添加 css等。

保存,现在看看效果,最新story文章列表是不是出现了呢?而热门内容呢,statistics模块也提供了一个按点击排序的文章列表,我们可 以直接用上面插入区块的办法把它放到页面里。现在我们页面里有最新文章、最新推荐、最新日志、热门内容、最新评论等区块列表了,看起来像那么回事了,接下 来的事就是排版了。这个就取决于个人的审美观了,熟悉css的就用css,不熟悉的就直接用表格套上去就行了。

可以收工了,可我还想有个more,你看大多数网站的列表下面,不都有个more,点击进去,显示更多的内容,并且这里边的内容还是可以分页的。好,现在我们来解决这个问题。还是举例子吧,也想不到其它更好的手段了。先在首页的列表下面加个more链接:

<?php
echo ‘<h2>最新story</h2>‘;
$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).‘<br>‘;
    };
echo
‘<a href="/story/all">更多</a>‘;
?>

就这么简单?是的,就这么简单,哈哈。可怎么也得加个判断吧,万一只有一篇文章,或者只有0篇文章呢,也显示个“更多”,那多傻。那就修改一下:
适用于5.x:
<?php
echo ‘<h2>最新story</h2>‘;
$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).‘<br>‘;
    };
}else {
//否则就显示
echo ‘没有文章‘;
}

if(
db_num_rows($result) > 9){//如果等于10篇,就显示更多链接。
   
echo ‘<a href="/story/all">更多</a>‘;
}
?>

db_num_rows在6.x中不能使用,适用于6.x:
<?php
echo ‘<h2>最新story</h2>‘;
$result = db_query_range("SELECT n.nid, n.title FROM {node} n WHERE n.type = ‘story‘ ORDER BY n.created DESC", 10);
$i = 0;
while (
$test = db_fetch_object($result)) {
    echo
l($test->title,‘node/‘.$test->nid).‘<br>‘;
   
$i++;
    };
if(!
$i ){
echo
‘没有文章‘;
}

if(
$i > 5){
    echo
‘<a href="/story/all">更多</a>‘;
}
?>

提交保存,有了个“更多”链接,可点击链接不是“找不到页面”吗?别急,下一步。创建一个page节点,标题就写个“新闻列表”吧,输入格式还是选取为 php code,自定义路径呢,就要和上面的一致了:story/all。现在要填内容进来了,怎么把这个最新的story文章列表显示出来呢?
适用于5.x:
<?php
echo ‘<h2>新闻列表</h2>‘;
$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).‘<br>‘;
    };
}else {
//否则就显示
echo ‘没有文章‘;
}
echo
‘<p>‘.theme(‘pager‘, NULL, 15).‘</p>‘;
?>

适用于6.x:
<?php
echo ‘<h2>新闻列表</h2>‘;
$result = pager_query("SELECT n.nid, n.title FROM {node} n WHERE n.type = ‘story‘ ORDER BY n.created DESC", 15);
$i = 0
while ($test = db_fetch_object($result)) {
    echo
l($test->title,‘node/‘.$test->nid).‘<br>‘;
   
$i++;
};
if(!
$i){
echo
‘没有文章‘;
}
echo
‘<p>‘.theme(‘pager‘, NULL, 15).‘</p>‘;
?>

请注意这一段代码,和上面其它的对比,有一些变化,首先是db_query_range变成了pager_query,对于有分页需求的,都使用这个函数 查询。其次当然是下面多了翻页函数:theme(‘pager‘, NULL, 15)。在查询语句中我们定义了数目是15条,翻页里当然也是设置15条。现在保存这个节点,看看,是不是出现了列表,并且有翻页了(当然,前提是你的 story文章得多于15条,如果不够多,把15改成2或3试试)。

这个时候可能又会觉得一个列表就显示个标题,未免太单调了,我还想显示点作者啊,发表时间啊,评论数目啊,点击数量啊等等。好吧,咱们来完成这个需求。
适用于5.x:

<?php
echo ‘<h2>新闻列表</h2>‘;
$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).‘<br>‘;
    };
}else {
//否则就显示
echo ‘没有文章‘;
}
echo
‘<p>‘.theme(‘pager‘, NULL, 15).‘</p>‘;
?>

适用于6.x:
<?php
echo ‘<h2>新闻列表</h2>‘;
$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);
$i = 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).‘<br>‘;
              
$i++;
};
if(!
$i) {
echo
‘没有文章‘;
}
echo
‘<p>‘.theme(‘pager‘, NULL, 15).‘</p>‘;
?>

细心的你肯定发现了,这里使用了多表查询,因为节点的点击量是存放在另外一个表里的,而作者的信息又存在users表里。老套路,提交保存,现在看看列 表,是不是多了作者、评论这些信息。只是排版未免太难看了。那就用css自己调整吧,可我又不想使用css,而且这种列表式的显示,使用表格更有优势,方 便又快捷。那就用表格吧。这样改一改:
适用于5.x:
<?php
echo ‘<h2>新闻列表</h2>‘;

$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 ‘<p>‘.theme(‘pager‘, NULL, 15).‘</p>‘;
?>

适用于6.x:
<?php
echo ‘<h2>新闻列表</h2>‘;

$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);
$i = 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),
            ),
        );
   
$i++;
    };
if(!
$i) {
echo
‘没有文章‘;
}
echo
theme(‘table‘, $header, $rows);//这儿打印出表格。
echo ‘<p>‘.theme(‘pager‘, NULL, 15).‘</p>‘;
?>

提交保存,现在看一看页面,是不是都在一个表格里,排版都省了,整整齐齐。这样就差不多了吧,又有了区块,又有了列表页。不过,也许你突然又觉得全是标题 列表有也点单调,还想看看摘要显示是什么效果。咱们就来把标题列表改为摘要模式,这个更简单一点,直接使用node_view和node_load,这两 个函数,只要你告诉它节点nid,它就能加载节点的摘要或全文视图了。省得麻烦,就直接还是用这个新闻列表页来做试验吧。编辑节点,放入这段代码:
适用于5.x:
<?php
echo ‘<h2>新闻列表</h2>‘;
$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
‘<p>‘.theme(‘pager‘, NULL, 15).‘</p>‘;
?>

适用于6.x:
<?php
echo ‘<h2>新闻列表</h2>‘;
$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);
$i = 0;
    while (
$test = db_fetch_object($result)) {
       
$output .= node_view(node_load(array(‘nid‘ => $test->nid)), 1);//这儿的1或0是全文或摘要。
               
$i++;
   };
if(!
$i) {
    echo
‘没有文章‘;
}
echo
‘<p>‘.theme(‘pager‘, NULL, 15).‘</p>‘;
?>

注意几个变化,首先要查询数据库的时候,只需要节点nid就行了。其次是在数组循环时,直接用node_view和node_load来显示出文章。这儿就用不着排版了,全部是按照你在node.tpl.php中定义的样式来显示。

现在终于可以结束了,好像在节点组织显示方面,也没其它的需求了。上面的内容我是一边试验一边写下来的,在5.x版本上,应该不会有错误。本来准备 截图,嫌上传麻烦,就没截了。如果测试过程中有什么问题,请提出来。希望这篇文章对于喜欢drupal,但又不想使用views的朋友有一定的帮助。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多