Drupal 模块的安装路径
在 Drupal 中模块可以安装在3个路径下
- 根目录下的 modules, 这个目录下都是 Drupal 的系统模块, 这个目录还是不动为好免得升级的时候麻烦.
- /sites/all/modules, 这个目录下的模块可以被所有站点共享, 公共服务的模块可以放在这里.
- /sites/www.somesite.com/modules, 这个目录下的模块只能被所在的站点使用, 私有服务的模块可以放在这里.
Drupal 模块的组成部分
模块说明文件 - x.info
info 是纯文本文件使用简单的 key = value 数据结构, 类似于 window 下常用的 ini 文件. 文件包含了模块名称,功能简介, Drupal 版本, 模块依赖等的运行信息. 详细结构如下:
- name = 模块名称
- description = 功能简介
- core = 要求的 Drupal 的版本(常用的是 5.x / 6.x)
- package = 模块的分组
- php = 要求的 php 版本
- dependencies[] = 依赖的模块1
- dependencies[] = 依赖的模块2
- ..
- dependencies[] = 依赖的模块n
代码示例 annotate.info
模块实现文件 - ×.module
module 是标准的php文件, 其内容大致上就是实现 Druapl 的各种 hook, hook 是 Drupal 的核心结构也是其可扩展性的基础, 在 Drupal 中 hook 可以说是无处不在无所不能, 大部分模块的功能都是通过实现各种 hook 来完成的. 常见的 hook 有
- menu_hook, 实现这个 hook 一般情况下是为了显示模块的用户界面或是配置界面.
- nodeapi_hook, 在 Drupal 里所有的内容类型都是 node, 所以要对内容做加工处理这个 hook 就必不可少.
代码示例 annotate.module
$items['admin/annotate/settings'] = array (
'title' => 'Annotation settings',
'description' => 'Change how annotations behave',
'page callback' => 'drupal_get_form',
'page arguments' => array('annotate_admin_settings'),
'access arguments' => array('administer site configuration'),
'type' => MENU_NORMAL_ITEM,
'file' => 'annotate.admin.inc',
);
return $items;
}
/**
* Implementation of hook_nodeapi().
*/
function annotate_nodeapi(&$node, $op, $teaser, $page) {
global $user;
switch ($op) {
// The 'view' operation means the node is about to be displayed.
case 'view':
// Abort if the user is an anonymous (not logged in) or
// if the node is not being displayed on a page by itself
// (for example, it could be in a node listing or search result).
if ($user->uid == 0 || !$page) {
break;
}
// Find out which node types we should annotate.
$types_to_annotate = variable_get('annotate_node_types', array('page'));
// Abort if the node is not on of the types we should annotate.
if (!in_array($node->type, $types_to_annotate)) {
break;
}
// Get the current annotation for this node from the database
// and store it in the node object
$result = db_query('SELECT note from {annotations} WHERE nid = %d AND uid = %d',
$node->nid, $user->uid);
$node->annotation = db_result($result);
// Add our form as node item.
$node->content['annotate_form'] = array(
'#value' => drupal_get_form('annotate_entry_form', $node),
'#weight' => 10,
);
break;
case 'delete':
db_query('DELETE FROM {annotations} WHERE nid = %d', $node->nid);
break;
}
}
模块安装文件 - x.install
install 文件中要实现模块安装和卸载所需的2个 hook, hook_install 和 hook_uninstall, 如果有数据库的更改还要实现 hook_schema, 这里值得说明的是 hook_schema 中 Druapl 不支持直接使用 DDL 来操作数据库, 而是使用自定义的 table schema 模型来支持多种数据库.
代码示例 annotate.install
/**
* Implementation for hook_uninstall().
*/
function annotate_uninstall() {
// Use schema API to delete database table.
drupal_uninstall_schema('annotate');
// Delete our module's variable from the variables table.
variable_del('annotate_node_types');
variable_del('annotate_limit_per_node');
variable_del('annotate_deletion');
}
/**
* Implementation for hook_schema().
*/
function annotate_schema() {
$schema['annotations'] = array(
'description' => t('Stores node annotations that users write.'),
'fields' => array(
'nid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'description' => t('The {node}.nid to which the annotation applies.'),
),
'uid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'description' => t('The {user}.uid of the user who created the annotation.')
),
'note' => array(
'description' => t('The text of the annotation.'),
'type' => 'text',
'not null' => TRUE,
'size' => 'big'
),
'created' => array(
'description' => t('A Unix timestamp indicating when the annotation was created.'),
'type' => 'int',
'not null' => TRUE,
'default' => 0
),
),
'primary key' => array(
'nid', 'uid'
),
);
return $schema;
}