本部分为各种 Drupal 开发文档及资源,包含 Drupal API 示例、模块开发教程、模块开发技巧文档等各类与 Drupal 开发相关的文档及资源。
详细说明请参见官方文档:Writing .info files (Drupal 6.x)
详细说明请参见官方文档:Writing .info files (Drupal 7.x)
要写一个符合标准的 Drupal 模块,确实有很多标准需要遵循,下面提供模块中要用到的 README.txt 文件的模板,需要创建 README.txt 文档时复制粘贴再稍作修改就行了。(懒人有懒福,呵呵)
CHANGELOG.txt 用于记录模块的变更记录,是 Drupal 模块包的一部分。下面提供一个 CHANGELOG.txt 的文件模板,在创建自己的 CHANGELOG.txt 文档时按以下格式编写即可:
hook_block() 用于为自己的模块添加一系列区块。
<?php
function mymodule_block($op = 'list', $delta = 0, $edit = array()) {
if ($op == 'list') {
$blocks[0] = array(
'info' => t('My Module Block'),
);
return $blocks;
}
elseif ($op == 'view') {
switch ($delta) {
case 0:
$block = array(
'subject' => t('My Block'),
'content' => "My Block Content",
);
break;
}
return $block;
}
}
?>
熟悉 Drupal 开发的人都知道 API 中的 hook_xxx 函数是可被调用的钩子函数,比如 book_nodeapi(), comment_nodeapi() 都是应用了 hook_nodeapi() 这个钩子。一般情况下,大家都知道应用钩子后, 应用了钩子的函数就会在调用时执行。但是,一般都不会太关注模块被调用的顺序,比如 book_nodeapi() 和 comment_nodeapi() ,Drupal 是先调用 book_nodeapi(),还是先调用 comment_nodeapi() 呢?
Drupal 在调用模块时,遵循两个顺序,首先是模块的权重,即 weight 值,其次是按模块的名称首字母排序。默认时,book 模块和 comment 的模块权重都为 0,因此这两个模块在被调用时是根据名称首字母来排序,即先调用 book_nodeapi(), 再调用 comment_nodeapi().
大多数情况下,并不需要关心模板的权重,因为模块之前通常都是独立工作,因此模块的调用顺序如何并不会对函数执行的效果形成影响。——不过,在一些情况下,开发人员需要为模块设置一个权重值,以确保某个模块最先被调用,或最后被调用。或者更复杂的调用顺序(当然这种情况就更难遇上了)。
模块的权重存储在 Drupal 数据库的 system 表名为 weight 的字段中,默认情况下,模块的权重都是0。通过改变模块的 weight 值,就能够改变模块在调用时的调用顺序了。例如 devel 模块希望比其它的模块都后被调用到,所以作者把它的权重设置成了 88.
改变模块的权重有两种方式,一种是直接对数据库中的 system 表进行修改——找到 name 为模块名的对应的条目,编辑 weight 值就可以。也许有些人觉得直接操作数据库不够优雅,也可以选择使用 util 模块。util 模块同 devel 模块一样是个开发辅助模块,util 提供了一个更改模块权重的子模块,使得管理员可以在模块管理页面对模块权重值进行修改。
使用 Drupal API 函数 node_type_save($info) 可以为 Drupal 添加新的内容类型,使用这个API创建内容类型的主要工作,是构造一个包含内容类型所需要的信息的 $info 对象。
$info 对象中用到的成员有 type, name, module, has_title, title_label, has_body, body_label, description, help, min_word_count, custom, modified, locked, orig_type 等,以下是有关各个成员的说明:
新建内容类型的代码片段
<?php
function foo_node_type() {
// 定义数组
$info = array(
'type' => 'foo',
'name' => t('foo'),
'module' => 'node',
'description' => t('Blah Blah Blah...'),
'help' => '',
'min_word_count' => 0,
'custom' => TRUE,
'modified' => TRUE,
'locked' => FALSE
);
// 为 $info 数组中未定义的配置设置默认值
$info = (object) _node_type_set_defaults($info);
// 将新的内容类型写入数据库
node_type_save($info);
// 更新菜单.
menu_rebuild();
}
?>
与创建内容类型相对应,如果在卸载模块时希望删除创建的内容类型,可以使用 node_type_delete($type)
<?php
function foo_node_type_delete() {
// 删除机器名为 'foo' 的内容类型
node_type_delete('foo');
}
?>
Drupal 使用 taxonomy_save_vocabulary() 函数创建词汇表(Vocabulary),通过定义词汇表数组,然后作为参数传入 taxonomy_save_vocabulary() 函数,程序执行时便可将定义的词汇表添加进数据库。
<?php
$article_category = array(
'name' => t('Article Categories'),
'description' => t('Select the appropriate category for your article.'),
'nodes' => array('article' => st('Article')),
'help' => '',
'hierarchy' => 1,
'relations' => 0,
'tags' => 0,
'multiple' => 0,
'required' => 0,
);
taxonomy_save_vocabulary($article_category);
?>
向 drupal.org 社区提交模块时,通常会将代码放在分支上进行开发,而对于主分支 master,则习惯只在其下保留一个 README.txt 文件,这个 README.txt 文件中包含各个版本的模块的代码和位置,用于帮助人们找到合适的版本。
以下是一个 master 主分支中的 README.txt 文件的样本,感谢 drupal.org 社区的 ELC 提供:
在普通情况下,当用户提交节点表单后会被重定向到对应的节点页面,如果在 URL 中传入了 ?destination=path/xxx 这样的参数,提交表单后用户就会被重定向到 destination 设置的页面。
除此之外,开发人员还可以通过为节点表单设置重定向属性,来控制表单提交后的重定向路径。
下面的代码通过应用 hook_form_alter(),判断当表单ID为"story_node_form"时,设置表单的重定向属性(#redirect)
<?php
/**
* Implements hook_form_alter().
*/
function test_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'story_node_form') {
// Your code goes here
// ...
// Set a '#redirect' key and value for $form,
// after users submit the node, they will be redirect to specific path.
$form['#redirect'] = 'node';
}
}
?>