05. 生成区块内容

主要内容描述:通过区块建立内容
Drupal"钩子“描述:hook_block

现在,我们需要在区块里生成'onthisdate'的内容。这里我们来看一种访问数据库的基本方法。

我们的目标就是得到一星期前建立的内容的列表(以'nodes'的形式存放在数据库里)。具体的说,我们要得到在当天午夜到一星期前的那天晚上11:59分之间建立的内容。当一个节点被建立的时候,建立的时间就会被储存到数据库里。我们将用它来找到我们需要的数据。

首先,我们来计算从一周前的午夜到一周前11:59分的时间(从epoch开始以秒计算, 到http://www.php.net/manual/en/function.time.php 来查看更多关于时间的信息) 。这一部分代码是何Drupal没有关系的,到PHP网站查看更详细的内容(http://php.net/)。

<?php
/**
* Generate HTML for the onthisdate block
* @param op the operation from the URL
* @param delta offset
* @returns block HTML
*/
function onthisdate_block($op='list', $delta=0) {

 
// listing of blocks, such as on the admin/block page
 
if ($op == "list") {
   
$block[0]["info"] = t('On This Date');
    return
$block;
  } else if (
$op == 'view') {

   
// our block content
    // Get today's date
   
$today = getdate();

   
// calculate midnight one week ago
   
$start_time = mktime(0, 0, 0,
                        
$today['mon'], ($today['mday'] - 7), $today['year']);

   
// we want items that occur only on the day in question, so 
    // calculate 1 day
   
$end_time = $start_time + 86400;
   
// 60 * 60 * 24 = 86400 seconds in a day
   
...
  }
}
?>

下一步是从数据库里得到我们想展示的内容的SQL语句。我们从节点table(Drupal内容的核心table)里取出内容。我们将用这条查询语句得到各类的内容类型:blog文章,论坛帖子等等。在本手册里,这样的做法是可以的。在真正的模块里,你应该调整SQL语句去选择具体内容的类型(通过加入'type'类型和一个WHERE语句来检查'type'列)。

注意:table名字包含大括号:{node}。只有这样,你的模块才能支持数据库table名字前缀。你可以通过阅读Drupal手册来获得更多关于这点的资料Table Prefix (and sharing tables across instances)

<?php
$query
= "SELECT nid, title, created FROM " .
        
"{node} WHERE created >= '" . $start_time .
        
"' AND created <= '". $end_time . "'";
?>

Drupal使用数据库帮助函数来执行数据库查询。所以,你只需要去写你的数据库SQL语句而不需要担心后面具体是怎样执行的。

我们将用db_query()(例如数据库行)来得到满足我们SQL查询的记录,并用db_fetch_object()去查看具体每一条记录:

<?php
 
// get the links
 
$queryResult db_query($query);

 
// content variable that will be returned for display  
 
$block_content = '';
  while (
$links = db_fetch_object($queryResult)) {
   
$block_content .=  l($links->title, 'node/' . $links->nid) . '<br />';
  }

 
// check to see if there was any content before setting up
  //  the block
 
if ($block_content == '') {  
   
/* No content from a week ago.  If we return nothing, the block 
     * doesn't show, which is what we want. */
   
return;
  }

 
// set up the block
 
$block['subject'] = 'On This Date';
 
$block['content'] = $block_content;
  return
$block;
}
?>

注意,实际的URL要包含在l()函数里面。l函数可以生成<a href="link">连接,通过调整URL不仅可以设置成干净的URL连接:http://(sitename)/node/2, 还可以生成这种http://(sitename)/?q=node/2的形式。

同时,我们返回一个包含'主题'和'内容'('subject' and 'content')元素的数组。这就是Drupal希望的从区块函数里得到的东西。如果不包含这些,区块将不能正确运行。

你应该还注意到内容和版面设计混合在一起的编程手段。如果你要为其他人来写模块,你应该为其他人(特别是那些不是程序员的人)提供一种可以很简单就可以调整内容版面的方法。一种简单的方法就是在你的连接里包含类属性,或者围绕着标签的并且有模块专用的CSS类,但不必要在连接最后加上。我们在这里先忽视这一点,但是在为他人写模块的时候应该注意这点问题。

把上面所说的都放到一起,我们的区块函数将是这样的:

<?php
function onthisdate_block($op='list', $delta=0) {
 
// listing of blocks, such as on the admin/block page
 
if ($op == "list") {
   
$block[0]["info"] = t("On This Date");
    return
$block;
  } else if (
$op == 'view') {
 
// our block content
    // content variable that will be returned for display
   
$block_content = '';

   
// Get today's date
   
$today = getdate();

   
// calculate midnight one week ago
   
$start_time = mktime(0, 0, 0,$today['mon'],
                               (
$today['mday'] - 7), $today['year']);

   
// we want items that occur only on the day in question, so
    //calculate 1 day
   
$end_time = $start_time + 86400;
   
// 60 * 60 * 24 = 86400 seconds in a day

   
$query = "SELECT nid, title, created FROM " .
            
"{node} WHERE created >= '" . $start_time .
            
"' AND created <= '". $end_time . "'";

   
// get the links
   
$queryResult db_query($query);
    while (
$links = db_fetch_object($queryResult)) {
     
$block_content .= l($links->title, 'node/'.$links->nid) . '<br />';
    }
   
// check to see if there was any content before setting up the block
   
if ($block_content == '') {
     
// no content from a week ago, return nothing.
     
return;
    }
   
// set up the block
   
$block['subject'] = 'On This Date';
   
$block['content'] = $block_content;
    return
$block;
  }
}
?>

把上述代码加到你的模块文件里。我们的模块现在就有功能了 - 我们可以安装,启动并且测试它了。

原文:http://drupal.org/node/82963