- 一个动作,实际上就是Drupal做的一件事。以下是一些例子: • 把一个节点推荐到首页
- 理解事件和触发器 Drupal在运行时,会经历一系列的事件。这些内部事件实际上是一种时间点,在这些时间点上,可以通过代码介入Drupal的运行过程,并与其进行交互。下图显示了某些Drupal的事件:
当使用Drupal时,一种常见的目标是,当某个事件发生时,能够执行一段操作。例如,网站管理员可能希望当有新的消息发布时,能够收到一封email。或者是如果用户发布了一些包含敏感词的评论,用户应该被禁止继续操作。本章讨论了如何在Drupal的事件发生时,能够触发一些你自己定义的代码。
- 在这一章的学习结束之后,你应该可以做到以下几点: • 从头开始创建一个Drupal模块
- 我们将会在开源社区中分享这一模块,那么自然就需要一个README.txt文件,就建在annotate目录下,放在annotate.info,annotate.module和annotate.install文件的旁边吧。README.txt文件大致内容就是谁开发了这个模块以及如何安装它。版权信息不必包含在内,因为所有上传到drupal.org的模块都要求是GPL许可的,而且网站在为你的软件打包的时候会自动加入LICENSE.txt文件。
- 在这个例子中,改变设定并点击“Save configuration”按钮,结果就被储存下来。而点击“Reset to defaults”按钮,字段就都被重置成默认值。接下来的内容就讲明了这一切的工作机制。 使用Drupal的变量表 我们先看一下“Annotations per node”。它的#default_value键的值被设置成variable_get('annotate_limit_per_node', 1)
- 如果说system_settings_form()为我们做了存储表单的取值的工作,那我们如何检验在“Annotations per node”区域中输入的内容是不是一个数字呢?我们能用某种方法让钩子来控制表单的提交进程么?当然能!我们只需要定义一个验证函数,并用它对我们找到的错误进行报错就行了,它应该在sites/all/modules/custom/annotate/annotate.admin.inc文件中: /**
- 在annotate模块中,我们给了管理员以设置哪些节点类型可以支持注释功能的权限。(如图2-1)。现在让我们深入了解一下其工作原理吧。
- 为了让用户可以在网页上输入注释内容,我们需要为此提供一个区域。让我们再为annotate.module添加一个表单吧: /** * Implementation of hook_nodeapi(). */ function annotate_nodeapi(&$node, $op, $teaser, $page) {
- Drupal有各种节点类型(在用户界面叫做内容类型),例如新闻和页面。为了达到只对其中一些做出注释的目的,我们需要建立一个页面用来告知模块究竟有哪些节点类型是我们想注释的。在此页面中,我们需要有一个对每一个存在的节点类型都生效的复选框(check boxes)。这样用户就可以通过是否选中某些选项来决定是否对相应的节点类型进行注释。这种页面叫做管理页面,其代码只在有必要的时候才会进行读取和分析。所以,我们不将它放在每次有页面请求都会被读取的annotate.module文件中,而是单独的放在一个名为annotate.admin.inc的文件里。 首先要做的是建立sites/all/modules/custom/annotate/annotate.admin.inc文件,然后把下面这段代码添加进去:
- 让我们再回忆一下:Drupal的建立是基于一个钩子系统的,有时我们也称之为回调系统。在Drupal运行的过程中,会询问模块是否有什么要做的。例如,当需要确定哪个模块该对当前请求做出回应的时候,所有模块都会被要求将自己所处理的路径提供出来。这个行为是如何实现的呢?Drupal会将所有模块进行列表,然后调用这些模块中以模块名加上“_menu”命名的函数。当进行到annotate模块(将会在早些时候按照字母表的顺序被默认定义在列表中)的时候,就会调用annotate_menu()函数——其返回值是一个由菜单项组成的数组。每一项(我们此时只有一项内容)都以路径为键,在这个例子中,路径是admin/settings/annotate。而我们的菜单项的内容是由键和值组成,并用来描述当这个路径被访问Drupal应该做些什么事情。如果想详细了解这些,请阅读第四章,在那里我们将会讨论Drupal的menu/callback系统。 下面是将要加入到我们的模块中的内容:
- Drupal有几种不同类别的管理设定,像内容管理,用户管理,都是展现在主管理页面上的。如果你的模块需要一个自己的分类,创建它是非常容易的事情。在这个例子中,我们通过修改模块的menu钩子来创建一个新的、名为“Node annotation”的分类,依然是用黑体部分代表添加或修改: /** * Implementation of hook_menu(). */ function annotate_menu() {
- 我们要做的第一件事就是为我们的模块起个名字。“annotate”(注释)就很不错——简洁而且具有一定的描述性。然后,我们要找个地方放置它。可以选择和核心模块一起放在modules目录下,但这样维护就会变得很困难,因为必须记住哪些是核心模块哪些是我们自己的。所以,让我们把它和核心模块分开放置吧,就在sites/all/modules目录下。
在许多开源软件中,你可以通过修改核心代码的方式来定制软件。这确实是得到你想要的功能的方法之一,但一般来说Drupal社区中都不太赞成这么做,而只是把它作为一种万不得已的选择。因为定制了代码意味着每次Drupal升级,你就要多做很多额外的工作——你必须再次调试以确定你定制的内容是否还能继续工作。然而,Drupal从整体上都是高度模块化和可扩展的。
阅读本章后,关于Drupal是如何工作的,读者应该已经有一个基本的概念,同时读者也应该对Drupal是如何处理一个Web请求也有了大致的了解。构成处理流程的各部分模块,将会在后面的章节进行详细描述。