分享

使用开源软件设计、开发和部署协作型 Web 站点,第 14 部分: announcemen...

 昵称67743 2008-06-20
 
在这个文章系列中,在 IBM Internet Technology Group 团队的带领下使用一套可免费获得的软件为虚构的 International Business Council(IBC) 公司设计、开发和部署一个外部网 Web 站点。在本文中,将研究整个系列中作为示例使用的 announcement 模块,展示此模块中的所有函数,这些函数可从一个文件中下载。在最后一期(第 15 部分)中,将简要回顾整个系列。

简介

本文研究在本系列中作为示例使用的 announcement 模块的源代码。这里讨论这个模块中的所有函数;大多数函数是第 6 部分 “在 Drupal 中构建定制模块” 中描述的 hook 接口的实现。这个模块是用 Drupal 4.7 编写的。下一篇文章(第 15 部分)将介绍如何将这个模块从 Drupal 4.7 迁移到 5.0。

announcement.module 的代码清单

announcement_help

这是 hook_help 的实现。这个函数让 announcement 模块能够向 Drupal 界面提供文档。(细节参见 http://api./api/HEAD/function/hook_help。)

输入参数:$section
决定界面的哪个部分正在请求帮助内容。在这里,我们在管理界面 admin/modules#description 下返回模块描述的内容,并在表单的顶部添加一个新的公告 node/add#announcement
返回值
一个包含帮助内容的字符串。

清单 1. hook_help 的实现
                                    function announcement_help($section) {
                                    switch ($section) {
                                    case 'admin/modules#description':
                                    return t('Enables the creation of announcement pages ' .
                                    'that are presented on the home page.');
                                    case 'node/add#announcement':
                                    return t('An Announcement. Use this page to add an announcement page.');
                                    }
                                    }
                                    

announcement_perm

这是 hook_perm 的实现。这个函数提供 announcement 模块定义的权限。可以在 Drupal 用户权限管理页面上选择这些权限,从而限制通过 announcement 模块执行的操作。(细节参见 http://api./api/HEAD/function/hook_perm。)

返回值
用来标识允许执行的操作的字符串数组。

清单 2. hook_perm 的实现
                                    function announcement_perm() {
                                    return array('create announcement', 'edit announcement');
                                    }
                                    

announcement_node_info

定义一个或多个节点类型的模块都需要这个函数。它使 Drupal 能够判断 announcement 模块节点类型的名称和属性。(细节参见 http://api./api/HEAD/function/hook_node_info。)

返回值
关于模块的节点类型的信息数组。至少需要返回可读的模块名、用来构建 hook 函数名的 Drupal 模块名以及对节点类型的简短描述。

清单 3. hook_node_info 的实现
                                    function announcement_node_info() {
                                    return array('announcement' => array(
                                    'name'        => 'Announcement',
                                    'description' => 'An Announcement. Use this page to add an announcement page.',
                                    'module'      => 'announcement'));
                                    }
                                    

announcement_access

这是 hook_access 的实现。这个函数使 announcement 模块能够根据当前执行的操作和 Drupal 用户权限管理页面上定义的权限,限制对它定义的节点类型的访问。(细节参见 http://api./api/HEAD/function/hook_access。)

输入参数:$op
当前执行的 Drupal 操作。在这里,我们希望控制对 “create”、“view”、“update” 和 “delete” 操作的访问。
输入参数:$node
将执行此操作的节点对象。
返回值
一个布尔值,表示是否可以执行此操作。

清单 4. hook_access 的实现
                                    function announcement_access($op, $node) {
                                    global $user;
                                    if ($op == 'create') {
                                    return user_access('create announcement');
                                    }
                                    else if ($op == 'view') {
                                    return user_access('access content');
                                    }
                                    else if ($op == 'update' ||  $op == 'delete') {
                                    if($user->uid == $node->uid || user_access('edit announcement')) {
                                    return true;
                                    }
                                    else {
                                    return false;
                                    }
                                    }
                                    else {
                                    return false;
                                    }
                                    }
                                    

announcement_menu

这是 hook_menu 的实现。这个函数使 announcement 模块能够注册 URL 路径并判断如何处理这些请求。根据注册,可以将链接放在菜单中,也可以作为选项卡放在页面顶部。(细节参见 http://api./api/HEAD/function/hook_menu。)

注意:对于版本 5.X,不使用 hook_settings 函数在管理 UI 中生成论坛,而是需要注册 URL 路径 admin/settings/announcement 来映射到创建这个表单的回调函数。

输入参数:$may_cache
这是一个布尔值,用来决定注册的 URL 路径是否应该缓存。通常情况下,包含某些动态值的 URL 路径不应该缓存。
返回值
注册的 URL 路径对象的数组。其中至少包含注册的 URL 路径、用作路径标题的文本字符串、通过测试访问列表建立的访问标志、用来决定应该如何使用这个注册的类型以及在请求这个 URL 路径时应该调用的回调函数的名称。

清单 5. hook_menu 的实现
                                    function announcement_menu($may_cache) {
                                    $items = array();
                                    if ($may_cache) {
                                    $items[] = array('path'     => 'announcements/add',
                                    'title'    => t('Add a new Announcement'),
                                    'access'   => node_access('create', 'announcement'),
                                    'type'     => MENU_CALLBACK,
                                    'callback arguments' => array('announcement'),
                                    'callback' => 'node_add');
                                    $items[] = array('path'     => 'announcements',
                                    'title'    => t('Announcements'),
                                    'access'   => user_access('access content'),
                                    'type'     => MENU_CALLBACK,
                                    'callback' => 'announcement_all');
                                    }
                                    else {
                                    $items[] = array('path'     => 'announcements/pager',
                                    'title'    => t('Announcements Pager Example'),
                                    'access'   => user_access('administer site'),
                                    'type'     => MENU_CALLBACK,
                                    'callback' => 'announcement_pager');
                                    if(is_numeric(arg(1))) {
                                    $node = node_load(arg(1));
                                    $items[] = array('path'     => 'announcements/' . arg(1),
                                    'title'    => t('View an Announcement'),
                                    'access'   => node_access('view', $node),
                                    'type'     => MENU_CALLBACK,
                                    'callback' => 'node_page');
                                    $items[] = array('path'     => 'announcements/' . arg(1) . '/view',
                                    'title'    => t('View an Announcement'),
                                    'access'   => node_access('view', $node),
                                    'type'     => MENU_CALLBACK,
                                    'callback' => 'node_page');
                                    $items[] = array('path'     => 'announcements/' . arg(1) . '/edit',
                                    'title'    => t('Edit an Announcement'),
                                    'access'   => node_access('edit', $node),
                                    'type'     => MENU_CALLBACK,
                                    'callback' => 'node_page');
                                    $items[] = array('path'     => 'announcements/' . arg(1) . '/delete',
                                    'access'   => node_access('delete', $node),
                                    'type'     => MENU_CALLBACK,
                                    'callback' => 'node_delete_confirm');
                                    }
                                    }
                                    return $items;
                                    }
                                    

announcement_pager

这个函数构建一套主题化的链接(称为 pager),它们链接到标明页号的公告列表的每一页。这常常放在每个标明页号的页面底部。

返回值
一个用来显示 pager 的 XHTML 字符串。

清单 6. announcement_pager 的实现
                                    function announcement_pager() {
                                    $result = pager_query(db_rewrite_sql("SELECT n.nid, n.created FROM {node} n " .
                                    "WHERE type = 'announcement' ORDER BY n.created DESC"),
                                    variable_get('default_nodes_main', 10));
                                    while ($announcement = db_fetch_object($result)) {
                                    $output .= node_view(node_load($announcement->nid), 1);
                                    }
                                    $output .= theme('pager', NULL, variable_get('default_nodes_main', 10));
                                    return $output;
                                    }
                                    

announcement_cron

这是 hook_cron 的实现。这个函数使 announcement 模块能够在 cron.php 脚本运行(常常是通过 cron 系统)时插入自己的操作。这在执行周期性异步任务时很有用,比如在当前的情况中检查是否有公告过期了。我们使用这个 hook 将过期的公告标为未发布(unpublished),这样的话,非管理员用户就不能通过标准的节点机制在站点上看到它们。(细节参见 http://api./api/HEAD/function/hook_cron。)


清单 7. hook_cron 的实现
                                    function announcement_cron() {
                                    $queryResult = db_query("UPDATE {node} AS n INNER JOIN {announcement} AS a " .
                                    "ON n.nid = a.nid SET n.status = 0 " .
                                    "WHERE n.type='announcement' AND n.status = 1 AND " .
                                    "a.expiration_date < %d", time());
                                    }
                                    

announcement_link

这是 hook_link 的实现。这个函数使 announcement 模块能够将自己的链接插入 Drupal 生成的内容的特定部分中。在这个示例中,根据当前用户的访问权限,将 Add、Edit 和 Delete 链接添加到 Drupal 显示的公告中。(细节参见 http://api./api/HEAD/function/hook_link。)

输入参数:$type
一个表示请求的链接类型的字符串。在这个示例中,就是放在公告节点下面的链接。
输入参数:$node
当前请求的节点对象。
输入参数:$teaser
一个布尔值,表示是显示整个公告,还是显示它的摘要。
返回值
l() 函数创建的链接对象的数组。

清单 8. hook_link 的实现
                                    function announcement_link($type, $node = NULL, $teaser = FALSE) {
                                    global $user;
                                    $links = array();
                                    if($type == 'node' && $node->type == 'announcement') {
                                    if(node_access('create', 'announcement')) {
                                    $links[] = l(t('Add'), "node/add/announcement",
                                    array('title' => t('Add a new announcement')));
                                    }
                                    if(node_access('update', $node)) {
                                    $links[] = l(t('Edit'), "announcements/$node->nid/edit",
                                    array('title' => t('Edit Announcement ') . $node->title));
                                    $links[] = l(t('Delete'), "announcements/$node->nid/delete",
                                    array('title' => t('Delete Announcement ') . $node->title));
                                    }
                                    }
                                    return $links;
                                    }
                                    

announcement_settings

这是 hook_settings 的实现。这个函数提供一个管理界面,用来控制 announcement 模块的各种设置。(细节参见 http://api./api/4.7/function/hook_settings。)

注意:Drupal V5 中不使用这个 hook(http:///node/64279#hook-settings)。

返回值
一个 Drupal Forms API 格式的元素数组描述,用来呈现设置界面。

清单 9. hook_settings 的实现
                                    function announcement_settings() {
                                    $form = array();
                                    $form['announcement_block_max_list_count'] = array('#type' => 'textfield',
                                    '#title'         => t('Maximum number of block announcements'),
                                    '#default_value' => variable_get('announcement_block_max_list_count', 3),
                                    '#description'   => t('The maximum number of items listed in the announcement block'),
                                    '#required'      => FALSE,
                                    '#weight'        => 0
                                    );
                                    $form['announcement_display_classification'] = array('#type' => 'checkbox',
                                    '#title'         => t('Display additional announcement classification'),
                                    '#default_value' => variable_get('announcement_display_classification', 1),
                                    '#description'  => t('Insert the additional classification in the announcement modules'),
                                    '#required'      => FALSE,
                                    '#weight'        => 0
                                    );
                                    return $form;
                                    }
                                    

announcement_form

这是 hook_form 的实现。当要创建或编辑公告时,调用这个函数来创建要显示的表单。(细节参见 http://api./api/HEAD/function/hook_form。)

输入参数:$node
要创建或编辑的节点。
返回值
一个 Drupal Forms API 格式的元素数组描述,用来呈现公告表单。

清单 10. hook_form 的实现
                                    function announcement_form(&$node) {
                                    if ($node->expiration_date == NULL) {
                                    $node->expiration_date = time() + (365 * 86400);
                                    }
                                    if ($node->publish_date == NULL) {
                                    $node->publish_date = time();
                                    }
                                    $form['title'] = array('#type' => 'textfield',
                                    '#title'         => t('Title'),
                                    '#default_value' => $node->title,
                                    '#description'   => t('Title of the announcement'),
                                    '#required'      => TRUE,
                                    '#weight'        => 1
                                    );
                                    $form['publication'] = array('#type'=> 'fieldset',
                                    '#collapsible'   => FALSE,
                                    '#title'         => t('Publication dates'),
                                    '#weight'        => 5
                                    );
                                    $form['publication']['publish_date'] = array(
                                    '#prefix'        => '<div class="date_widget">',
                                    '#suffix'        => '</div>',
                                    '#type'          => 'date',
                                    '#title'         => t('Publication date'),
                                    '#default_value' => _announcement_unixtime2drupaldate($node->publish_date)
                                    );
                                    $form['publication']['expiration_date'] = array(
                                    '#prefix'        => '<div class="date_widget">',
                                    '#suffix'        => '</div>',
                                    '#type'          => 'date',
                                    '#title'         => t('Expiration date'),
                                    '#default_value' => _announcement_unixtime2drupaldate($node->expiration_date)
                                    );
                                    $form['abstract'] = array('#type' => 'textarea',
                                    '#title'         => t('Abstract'),
                                    '#default_value' => $node->abstract,
                                    '#rows'          => 3,
                                    '#description'   => t('Short summary of the full announcement'),
                                    '#required'      => TRUE,
                                    '#weight'        => 9
                                    );
                                    $form['body'] = array('#type' => 'textarea',
                                    '#title'         => t('Body'),
                                    '#default_value' => $node->body,
                                    '#description'   => t('Full content for the announcement which is shown ' .
                                    'with the abstract on the details page'),
                                    '#required'      => TRUE,
                                    '#weight' => 10
                                    );
                                    return $form;
                                    }
                                    

announcement_all

这个函数创建一个主题化的公告列表。对于一般用户,只显示没有过期的公告。如果用户有权编辑公告,则显示所有公告。

返回值
显示所有公告的格式化内容。

清单 11. 显示所有公告的函数
                                    function announcement_all() {
                                    if (user_access('edit announcement')) {
                                    $queryResult = db_query(
                                    "SELECT n.nid FROM node n INNER JOIN announcement a ON n.nid = a.nid " .
                                    "WHERE n.type='announcement' ORDER BY n.sticky DESC, A.publish_date DESC");
                                    }
                                    else {
                                    $queryResult = db_query(
                                    "SELECT n.nid FROM node n INNER JOIN announcement a ON n.nid = a.nid " .
                                    "WHERE n.type='announcement' AND a.expiration_date > %d " .
                                    "ORDER BY n.sticky DESC, a.publish_date DESC", date("U"));
                                    }
                                    $page_content = array();
                                    $page_content[] = "<h2 class='category'>Announcements</h2>";
                                    while ($announcement = db_fetch_object($queryResult)) {
                                    $announcement = node_load($announcement->nid);
                                    $announcement->url = url('announcements/' . $announcement->nid);
                                    $page_content[] = theme('announcement_compact', $announcement);
                                    }
                                    return implode('', $page_content);
                                    }
                                    

announcement_view

这是 hook_view 的实现。这个函数使 announcement 模块能够在 Drupal 系统显示任何公告节点之前添加额外的变量。在这里,我们将公告细节的 URL 插入公告节点对象。(细节参见 http://api./api/HEAD/function/hook_view。)

输入参数:$node
要显示的节点。
输入参数:$teaser
是生成摘要,还是整个节点。
输入参数:$page
节点是否显示为单独的页面,也就是是否应该显示页面标题。
返回值
修改后的节点对象。

清单 12. hook_view 的实现
                                    function announcement_view(&$node, $teaser = FALSE, $page = FALSE) {
                                    if ($page) {
                                    $node->url = url('announcements/' . $node->nid);
                                    }
                                    }
                                    

announcement_validate

这是 hook_validate 的实现。当用户提交了创建或编辑表单之后,调用这个函数。在这里,我们检查过期日期是否在发布日期之后。(细节参见 http://api./api/HEAD/function/hook_validate。)

输入参数:$node
要检验的节点。

清单 13. hook_validate 的实现
                                    function announcement_validate($node) {
                                    if ($node) {
                                    $publish_date    = _announcement_drupaldate2unixtime($node->publish_date);
                                    $expiration_date = _announcement_drupaldate2unixtime($node->expiration_date);
                                    if ($publish_date >= $expiration_date) {
                                    form_set_error('publish_date',
                                    t('The publish date of an announcement must be before its expiration date.'));
                                    }
                                    }
                                    }
                                    

announcement_submit

这是 hook_submit 的实现。这个函数使 announcement 模块能够在将数据保存到数据库中之前修改节点对象信息。在这里,我们将日期值转换为整数,并确保公告按照分类法正确地分类。(细节参见 http://api./api/HEAD/function/hook_submit。)

输入参数:$node
要提交到数据库的节点。

清单 14. hook_submit 的实现
                                    function announcement_submit(&$node) {
                                    $node->publish_date    = _announcement_drupaldate2unixtime($node->publish_date);
                                    $node->expiration_date = _announcement_drupaldate2unixtime($node->expiration_date);
                                    $now = time();
                                    if($now > $node->publish_date && $now < $node->expiration_date) {
                                    $node->status = 1;
                                    }
                                    else {
                                    $node->status = 0;
                                    }
                                    $vocab = announcement_get_vocabulary_by_name('IBC');
                                    $term  = taxonomy_get_term_by_name('announcements');
                                    $node->taxonomy = _announcement_merge_tid($vocab->vid,
                                    $term[0]->tid,
                                    $node->taxonomy);
                                    }
                                    

announcement_get_vocabulary_by_name

这个 helper 函数返回与给定的词汇表名称对应的词汇表对象。

输入参数:$name
要获取的词汇表的名称。
返回值
词汇表对象。

清单 15. 按名称寻找词汇表
                                    function announcement_get_vocabulary_by_name ($name) {
                                    $results = db_query('SELECT * FROM {vocabulary} WHERE name = "%s"', $name);
                                    if (db_num_rows($results) > 0) {
                                    return db_fetch_object($results);
                                    }
                                    else {
                                    return null;
                                    }
                                    }
                                    

_announcement_merge_tid

这是一个本地函数(由函数名前面的下划线表示),它合并词汇表中的词汇。

输入参数:$vid
词汇表 id。
输入参数:$tid
词汇 id。
输入参数:$taxonomy
词汇所属的分类法。
返回值
更新后的分类法。

清单 16. 合并词汇表的词汇
                                    function _announcement_merge_tid($vid, $tid, $taxonomy) {
                                    $values = array_values($taxonomy[$vid]);     // get all tid values for vocabulary
                                    if (!in_array($tid, $values)) {              // if the tid is not there
                                    $taxonomy[] = $tid;                      // add it
                                    }
                                    return $taxonomy;
                                    }
                                    

announcement_load

这是 hook_load 的实现。这个函数使 announcement 模块能够在公告节点对象中添加额外的数据。在这里,我们合并来自 announcement 表的相关日期。(细节参见 http://api./api/HEAD/function/hook_load。)

输入参数:$node
要从数据库装载的节点。
返回值
返回来自数据库的任何额外值,这些值将合并进节点中。

清单 17. hook_load 的实现
                                    function announcement_load(&$node) {
                                    $additions = db_fetch_object(db_query('SELECT * FROM {announcement} ' .
                                    'WHERE nid = %d', $node->nid));
                                    return $additions;
                                    }
                                    

announcement_insert

这是 hook_insert 的实现。这个函数使 announcement 模块能够在将新节点插入数据库时执行操作。在这里,我们使用节点对象中的数据在 announcement 表中插入一个新记录。(细节参见 http://api./api/HEAD/function/hook_insert。)

输入参数:$node
要插入数据库中的节点。

清单 18. hook_insert 的实现
                                    function announcement_insert($node) {
                                    db_query("INSERT INTO {announcement} (nid, abstract, publish_date, expiration_date) " .
                                    "VALUES (%d, '%s', '%d', '%d')", $node->nid, $node->abstract,
                                    $node->publish_date, $node->expiration_date);
                                    }
                                    

announcement_update

这是 hook_update 的实现。这个函数使 announcement 模块能够在数据库更新现有的公告节点时执行操作。在这里,我们执行自己的数据库更新,比如将信息放进 announcement 表中。(细节参见 http://api./api/HEAD/function/hook_update。)

输入参数:$node
数据库中要更新的节点。

清单 19. hook_update 的实现
                                    function announcement_update($node) {
                                    db_query("UPDATE {announcement} SET abstract='%s', publish_date = '%s', " .
                                    "expiration_date = '%s' WHERE nid = %d", $node->abstract,
                                    $node->publish_date, $node->expiration_date, $node->nid);
                                    }
                                    

announcement_delete

这是 hook_delete 的实现。这个函数使 announcement 模块能够在数据库中删除公告节点时执行操作。(细节参见 http://api./api/HEAD/function/hook_delete。)

输入参数:$node
要从数据库中删除的节点。

清单 20. hook_delete 的实现
                                    function announcement_delete($node) {
                                    db_query('DELETE FROM {announcement} WHERE nid = %d', $node->nid);
                                    }
                                    

announcement_block

这是 hook_block 的实现。这个函数定义两个提供给 Drupal 系统的区块。站点管理员可以使用 Drupal 界面根据需要选择将它们放在页面上的什么位置。第一个区块列出最近更新的公告,第二个区块使用第 11 部分 “在 Drupal 中使用分类法” 中描述的 IBC 词汇表按类别列出公告。(细节参见 http://api./api/HEAD/function/hook_block。)

输入参数:$op
要获取的关于公告区块的信息种类。
输入参数:$delta
要返回的区块号。
输入参数:$edit
如果 $op 是 ‘save’,那么这个变量包含提交的区块配置表单数据。
返回值
如果 $op 是 ‘list’,那么它返回一个数组的数组,每个子数组必须定义一个描述区块的 info 元素。如果 $op 是 ‘view’,那么它返回一个数组,这个数组定义 ‘subject’ 和 ‘content’ 元素,这些元素定义以 $delta 为索引的区块。

清单 21. hook_block 的实现
                                    function announcement_block($op = 'list', $delta = 0, $edit = array()) {
                                    global $user;
                                    if ($op == 'list') {
                                    $blocks[0]['info'] = t('Recently updated announcements');
                                    $blocks[1]["info"] = t('List nodes in the IBC vocabulary');
                                    return $blocks;
                                    }
                                    else if ($op == 'view')	{
                                    $block	= array();
                                    switch ($delta) {
                                    case 0:
                                    $announcement_items	= array();
                                    if (user_access('access content')) {
                                    $q = 'SELECT N.uid,N.nid,N.title,A.publish_date,N.status '.
                                    'FROM {node} N JOIN {announcement} A USING(nid) '.
                                    "WHERE N.type='announcement' ".
                                    'AND N.status = 1 '.
                                    'AND A.publish_date < %d ' .
                                    'AND A.expiration_date > %d ' .
                                    'ORDER BY A.publish_date DESC ';
                                    $now = time();
                                    $items = variable_get('announcement_block_max_list_count', 3);
                                    $announcements = db_query_range($q, $now, $now, 0, $items);
                                    while (db_num_rows($announcements) > 0 and
                                    $announcement = db_fetch_object($announcements)) {
                                    $announcement_items[] = $announcement;
                                    }
                                    }
                                    $block['subject'] = t('Announcements');
                                    $block['content'] = theme('announcement_block_list',
                                    $announcement_items);
                                    break;
                                    case 1:
                                    if (user_access("access content")) {
                                    $vocabulary = announcement_get_vocabulary_by_name('IBC');
                                    $block["subject"]= t('IBC');
                                    $block["content"]= announcement_vocab_vert($vocabulary->vid);
                                    }
                                    }
                                    return $block;
                                    }
                                    }
                                    

announcement_vocab_vert

这个函数来自 taxonomy_dhtml 模块,用来构建在按照词汇表分类的节点区块中显示的内容。它构建一个数组,其中包含当前词汇的所有子词汇。在 HREF 中构建正确的 or 值时需要这个函数。

输入参数:$vocabulary_id
词汇表的 ID。
输入参数:$op
一个可以添加进列出的节点 URL 的操作。
返回值
用来显示区块的内容。

清单 22. 显示按照词汇表词汇分类的节点
                                    function announcement_vocab_vert($vocabulary_id, $op = NULL) {
                                    $tree = taxonomy_get_tree($vocabulary_id);
                                    foreach ($tree as $term) {
                                    $url = "taxonomy/term/$term->tid";
                                    if ($op) {
                                    $url .= "/$op";
                                    }
                                    $link = l(t($term->name), $url, array("title" => t($term->description)));
                                    $out .= _taxonomy_depth($term->depth, " ")."- $link";
                                    $count = taxonomy_term_count_nodes($term->tid);
                                    if ($count) {
                                    $out .= " ($count)";
                                    $out .= _announcement_by_terms($term->tid);
                                    }
                                    else {
                                    $out .= " (0)";
                                    }
                                    $out .= "<br/>";
                                    }
                                    return $out;
                                    }
                                    

_announcement_by_terms

这个本地函数返回一个主题化的链接列表,它们链接到与给定的词汇表词汇对应的公告。

输入参数:$tid
要呈现的词汇的 ID。
返回值
要输出的词汇。

清单 23. 输出词汇的显示
                                    function _announcement_by_terms($tid) {
                                    $result = '';
                                    $tids   = array( $tid );
                                    $nodes  = taxonomy_select_nodes($tids, 'or', 0, FALSE);
                                    while ($r = db_fetch_object($nodes)) {
                                    $url = "announcements/". $r->nid;
                                    $result .= "
  -  " . l($r->title, $url, array("title" => t($r->title))); } return $result; }

announcement_nodeapi

这是 hook_nodeapi 的实现。这个函数使 announcement 模块能够在 Drupal 意识到要执行特定操作时执行适当操作。在这里,如果当前的 Drupal 操作是 “update index”,就将这个公告的摘要添加到搜索索引中。(细节参见 http://api./api/HEAD/function/hook_nodeapi。)

输入参数:$node
要处理的节点。
输入参数:$op
节点上要执行的操作,比如 “delete”、“update index”。
返回值
这取决于我们需要的操作,在我们的示例中返回要添加进索引的节点信息。

清单 24. hook_nodeapi 的实现
                                    function announcement_nodeapi(&$node, $op) {
                                    switch ($op) {
                                    case 'update index':
                                    if ($node->type == 'announcement') {
                                    $text = '';
                                    $q = db_query(
                                    'SELECT a.abstract FROM node n LEFT JOIN announcement a ON '.
                                    'n.nid = a.nid WHERE n.nid = %d', $node->nid);
                                    if ($r = db_fetch_object($q)) {
                                    $text = $r->abstract;
                                    }
                                    return $text;
                                    }
                                    }
                                    }
                                    

主题函数

主题设计人员可以使用以下函数改变这个模块生成数据的方式。有两类主题函数:

theme_announcement
泛型的主题函数,适用于所有主题和主题引擎
phptemplate_announcement
由 phptemplate 引擎使用的主题函数

 

对于本系列来说,我们不在默认主题函数中插入任何数据构造代码,而是关注如何覆盖 phptemplate 主题函数来构造数据。通常情况下,这些 phptemplate 函数放在主题目录中的 phptemplate.php 文件中。


清单 25. 主题函数
                                    function theme_announcement($announcement) {
                                    return '';
                                    }
                                    function theme_announcement_compact($announcement) {
                                    return '';
                                    }
                                    function theme_announcement_block_list($announcement_list) {
                                    return '';
                                    }
                                    function phptemplate_announcement($announcement) {
                                    return _theme_phptemplate_announcement($announcement, 'announcement');
                                    }
                                    function phptemplate_announcement_compact($announcement) {
                                    return _theme_phptemplate_announcement
                                    ($announcement, 'announcement_compact');
                                    }
                                    function phptemplate_announcement_block_list($announcement_list) {
                                    global $user;
                                    return _phptemplate_callback('announcement_block_list',
                                    array('announcements' => $announcement_list,
                                    'user'=> $user));
                                    }
                                    function _theme_phptemplate_announcement
                                    ($announcement, $announcement_template) {
                                    $expired = FALSE;
                                    if ($announcement->expiration_date < time()) {
                                    $expired = TRUE;
                                    }
                                    $variables = array(
                                    'title'      => $announcement->title,
                                    'body'    => $announcement->body,
                                    'links'     => $announcement->links ? theme('links', $announcement->links) : '',
                                    'abstract'  => $announcement->abstract,
                                    'published' => format_date($announcement->publish_date,'custom','j M, Y'),
                                    'expires'   => format_date($announcement->expiration_date,'custom','j M, Y'),
                                    'expired'  => $expired,
                                    'node'      => $announcement
                                    );
                                    return _phptemplate_callback($announcement_template, $variables);
                                    }
                                    

_announcement_drupaldate2unixtime

这是一个本地实用程序函数,它将一个包含日期的结构化数据数组转换为整数。

输入参数:$drupal_date
一个用数组表示的日期,数组中包含日、月和年信息。
返回值
日期的整数表示。

清单 26. 将日期由 Drupal 内部表示转换为整数
                                    function _announcement_drupaldate2unixtime($drupal_date) {
                                    $year  = $drupal_date["year"];
                                    $month = $drupal_date["month"];
                                    $day   = $drupal_date["day"];
                                    return mktime(0,0,0, (int)$month, (int)$day, (int)$year);
                                    }
                                    

_announcement_unixtime2drupaldate

这是一个本地实用程序函数,它将日期的整数表示转换为结构化数据数组。

输入参数:$unixtime
日期的整数表示。
返回值
一个用数组表示的日期,数组中包含日、月和年信息。

清单 27. 将日期由整数转换为 Drupal 内部表示
                                    function _announcement_unixtime2drupaldate($unixtime) {
                                    return array('day'   => format_date($unixtime, 'custom', 'j'),
                                    'month' => format_date($unixtime, 'custom', 'n'),
                                    'year'  => format_date($unixtime, 'custom', 'Y'));
                                    }
                                    

分享这篇文章......

digg 将这篇文章提交到 Digg
del. 发布到 del.
Slashdot 提交到 Slashdot!

结束语

本文介绍了 announcement 模块。除了提供下载文件之外,还描述了每个函数,提供了关于所使用的 Drupal hook 函数的更多信息。我们希望本文能够回答关于 announcement 模块源代码的一些常见问题。

下一篇文章是本系列的最后一篇,将总结已经学到的知识并展望 Drupal 5 的发展方向。






回页首


下载

描述 名字 大小 下载方法
announcement 模块源代码 announcement.module 24KB HTTP
关于下载方法的信息


参考资料

学习

获得产品和技术

讨论


作者简介

Alister's photo

Alister Lewis-Bowen 是 IBM 的 Internet Technology Group 的高级软件工程师。他从 1993 年开始作为 IBM 英国职员从事互联网和 Web 技术方面的工作。Alister 后来到美国为 IBM 赞助的体育活动的 Web 站点工作,之后成为 ibm.com 的高级网管。他当前正在帮助创建语义 Web 原型。可以通过 alister@us.ibm.com 联系 Alister。


Louie's photo

Louis Weitzman 是 IBM 的 Internet Technology Group 的高级软件工程师。他从事设计和计算已经有 30 年了。他曾经帮助开发 ibm.com 使用的基于 XML 片段的内容管理系统,当前正在从事将设计过程融入新项目的工作。可以通过 louisw@us.ibm.com 联系 Louis。


Stephen's photo

Stephen Evanchik 是 IBM 的 Internet Technology Group 的软件工程师。他是许多开放源码软件项目的代码贡献者,其中最著名的是 Linux 内核中的 IBM TrackPoint 驱动程序。Stephen 当前从事语义 Web 技术。可以通过 evanchik@us.ibm.com 联系 Stephen。




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

将您的建议发给我们或者通过参加讨论与其他人分享您的想法.


 


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

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多