Drupal 开发文档及资源

  本部分为各种 Drupal 开发文档及资源,包含 Drupal API 示例、模块开发教程、模块开发技巧文档等各类与 Drupal 开发相关的文档及资源。

 

 

Drupal 模块 .info 文件的基本写法

Drupal 6 模块 .info 文件示例

name = "Example module"
description = "Gives an example of a module."
core = 6.x
package = Views
dependencies[] = views
dependencies[] = panels

详细说明请参见官方文档:Writing .info files (Drupal 6.x)

 

Drupal 7 模块 .info 文件示例

name = Example module
description = Gives an example of a module.
core = 7.x
package = Views
dependencies[] = views
dependencies[] = panels
files[] = example.test
configure = admin/config/content/example

详细说明请参见官方文档:Writing .info files (Drupal 7.x)

Drupal 模块包中的 README.txt 文件模板

  要写一个符合标准的 Drupal 模块,确实有很多标准需要遵循,下面提供模块中要用到的 README.txt 文件的模板,需要创建 README.txt 文档时复制粘贴再稍作修改就行了。(懒人有懒福,呵呵)

 

-- SUMMARY --

[Module summary]


-- REQUIREMENTS --

None.


-- INSTALLATION --

* Install as usual.


-- CONFIGURATION --

[Configuration and Usage info]



-- CONTACT --

Current maintainers:
* Lugir - http://drupal.org/user/842094
* Homepage - http://lugir.com

 

Drupal 模块包中的 CHANGELOG.txt 文件模板

  CHANGELOG.txt 用于记录模块的变更记录,是 Drupal 模块包的一部分。下面提供一个 CHANGELOG.txt 的文件模板,在创建自己的 CHANGELOG.txt 文档时按以下格式编写即可:

 

Image Link 6.x-1.1, 2011-11-01
------------------------------
by Lugir: Changed add link action from 'node_view' stage to 'node_load'.
by Lugir: Fixed can't add links to images which in teaser mode or RSS.

Image Link 6.x-1.0, 2011-10-29
------------------------------
by Lugir: Initial release of ImageLink module.

 

hook_block() 代码示例

  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;
  }

}
?>

使用模块的 weight 值调整模块加载/调用顺序

  熟悉 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.

如何改变模块的权重(weight)?

  改变模块的权重有两种方式,一种是直接对数据库中的 system 表进行修改——找到 name 为模块名的对应的条目,编辑 weight 值就可以。也许有些人觉得直接操作数据库不够优雅,也可以选择使用 util 模块。util 模块同 devel 模块一样是个开发辅助模块,util 提供了一个更改模块权重的子模块,使得管理员可以在模块管理页面对模块权重值进行修改。

Util 模块 module weights 子模块

使用 Drupal API 添加内容类型

  使用 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 等,以下是有关各个成员的说明:

  • type - 内容类型的机器名,此字串应该只包含小写字符、数字和下划线,如"story", "page"等等
  • name - 内容类型的用户可读名称,如“新闻”,“页面”等
  • module - 创建此内容类型的模块,使用规范的模块名称,如"node",(使用其它的名称结果不显示,必须是 node ???)
  • has_title - 是否有标题,FALSE 为无,TRUE为有
  • title_label - 标题标签,如“标题”
  • has_body - 是否有正文,FALSE 为无,TRUE为有
  • 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 API 添加词汇表

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 模块 master 主分支中的 README.txt 文件示例

  向 drupal.org 社区提交模块时,通常会将代码放在分支上进行开发,而对于主分支 master,则习惯只在其下保留一个 README.txt 文件,这个 README.txt 文件中包含各个版本的模块的代码和位置,用于帮助人们找到合适的版本。

  以下是一个 master 主分支中的 README.txt 文件的样本,感谢 drupal.org 社区的 ELC 提供:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Where is the module?                                                   +
+========================================================================+

Since branching to support D6 and D7, the master branch that you are looking at has been cleared of content to avoid old code being used.

If you did a full git clone, then you should have all the code hidden away in two additional branches:

- 6.x-1.x
- 7.x.1.x

While "git branch" will only show locally tracked branches, in this case master, the other branches are hidden in the .git repository.

Running "git branch -a" will show something like this:
* master
  remotes/origin/6.x-1.x
  remotes/origin/7.x-1.x
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

To checkout one of those branches so you can use the code, type:
git checkout -b 7.x-1.x remotes/origin/7.x-1.x

This created a local tracking branch called 7.x-1.x which tracks the remote remotes/origin/7.x-1.x branch. You will also now have all the files to use the git version of the module.

Have fun!

处理节点表单提交之后的页面跳转

  在普通情况下,当用户提交节点表单后会被重定向到对应的节点页面,如果在 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';

  }
  
}
?>