在本章中,我们给出了许多的代码小提示和最佳实践,它能帮你成长为一个合格的Drupal开发者,并帮你摆脱电脑的折磨。我们首先学习Drupal的编码标准,接着学习如何为模块创建文档以方便其它开发者理解代码。还介绍了如何在Drupal的核心中快速的查找东西,介绍了版本控制,并详细的说明了如何维护一个第3方模块,最后我们讨论了如何调试和剖析代码。
老葛的Drupal培训班 Think in Drupal
老葛的Drupal培训班 Think in Drupal
标签就是一个特定分支在某个时间的快照。在Drupal世界中,标签用来标记beta,bug-fix,和安全发布。这样就得到了更小的版本,比如Drupal 6.1 和 6.2。规范的标签名有DRUPAL-4-7-1,DRUPAL-4-7-2, DRUPAL-5-7, DRUPAL-6-0, DRUPAL-6-1, 和DRUPAL-6-2(再次注意,在Drupal5中,命名规范改变了)。Drupal核心使用的标签名字的完整列表,可参看http://drupal.org/node/93997。
Drupal遵循大多数的Doxygen注释样式指南。所有的文档区块必须使用下面的语法:
Devel模块是个大杂烩,里面包含了许多实用功能,开发者可用它来调试和检查代码的各种细节。
老葛的Drupal培训班 Think in Drupal
函数文档应该使用下面的语法:
我们将学习如何在命令行中使用CVS。现在有许多图形化的CVS客户端,一旦学会了这些基本的命令以后,你应该能够很容易的实用这些图形化的CVS客户端了。Windows用户通过安装Cygwin环境(参看http://drupal.org/node/150036),就可以使用CVS命令行了。如果你使用的是CVS命令行客户端,那么这会便于你与社区中的其它开发者交流CVS问题。
如果你想将你的站点更新到最新的Drupal代码上,甚至更新到下一个新版本上,那么你可以使用cvs update命令来实现这一点。首先测试一下cvs update命令将做出哪些变更,运行下面的命令:
egrep是一个Unix命令,用来在文件中搜索匹配给定正则表达式的位置。不,它不是一个鸟儿(那是egret(白鹭))。如果你是一个Windows用户,并想学习一下这些例子,你可以先安装一个预编译的版本(参看http://unxutils.sourceforge.net)或者安装Cygwin环境(http://cygwin.com),这样就可以使用egrep了。否则,你只能使用操作系统内置的搜索功能,而不能使用egrep。
我们在前面的“从CVS签出Drupal”一节中,已经学到了如何根据DRUPAL-6分支上的一个标签来获取代码的一个版本。我们以此为基础,做些变通,来取回各种标签和分支下的代码,并把它们放在当前目录中的drupal文件夹下。
老葛的Drupal培训班 Think in Drupal
在http://drupal.org/project/coder,你将找到一个宝贝,它能帮你节省不少的时间,减轻你的烦恼。这就是编码器模块:一个用来评估其它模块代码的模块。
函数调用
当Drupal7出来以后,我们想继续开发Drupal6下的模块。而现在, DRUPAL-5分支的开发工作基本上停止不前了。但是我们也不能在HEAD上同时开发Drupal 7和Drupal 6下的版本啊?现在需要为Drupal 6创建一个分支,将特定于Drupal 6的开发放在那里进行。首先,我们需要确定我们使用的是HEAD的最近版本。接着,为Drupal 6创建分支。
让我们继续前进,来创建分支:
我们已经为Drupal5创建了一个分支,并在该分支上创建了一个标签。现在让我们把精力主要放在Drupal 6上,来添加对badger(徽章)模块的依赖关系。但是首先,我们需要做出一个决定。我们是应该立即创建一个分支呢?还是应该简单的使用HEAD?由于我们可以在任何想要的地方创建标签,所以这个问题就是,又没有必要创建一个DRUPAL-6分支?让我们检查一下这两种不同的方式。
我们知道,还有许多懒惰的用户还在使用Drupal5,现在让我们看看如何为他们创建一个分支。
为了使那些不熟悉CVS的人也可以下载你的模块,你应该在drupal.org上创建一个发布节点。一个发布节点提供了给定发布标签的相关信息,而drupal.org上的打包脚本能够自动的为发布标签指示的文件构建一个tarball(沓包)。例如,你能为你模块的DRUPAL-6--1-3标签创建一个发布节点。打包脚本从DRUPAL-6—1分支取出DRUPAL-6--1-3标签所标示的文件,然后为其创建一个tarball(沓包)和一个链接,这样drupal.org上的访问者就可以下载这个tarball(沓包)了。而tarball(沓包)的名字则应该为foo-6.x-1.3.tar.gz。
现在到了关键时刻了。是时候将你的文件提交到资源库中了!是不是有点紧张。检查/path/to/local/copy/of/contributions/modules/foo,看看它是不是包含了所有的文件并且里面包含了你想要提交的代码。接着,输入决定性的命令。使用一个简洁的句子来描述你模块的功能,接着继续前进:
对于任何软件项目,版本控制都是必须的,同样Drupal也不例外。版本控制用来追踪Drupal中的每个文件上的所有变更。它保存了所有修订本的历史以及每个修订本的作者。你可以从中得到一个逐行的报告,里面包含谁做了变更以及什么时间什么原因。版本控制也可以简化新版本的发布流程。Drupal社区使用久经锤炼的可靠的CVS软件,来维护它的修订本历史。
老葛的Drupal培训班 Think in Drupal
由于你把你的模块贡献给了社区,如果能够使用一种结构化的方式,让模块的其它用户能与你进行交互,这应该是再好不过了。这样,你就不会经常收到哪些不期而遇的电子邮件了,而且还有一种标准的方式用来追踪请求的特性、bug修正、等等。登录到drupal.org以后,访问http://drupal.org/node/add/project,或者使用站点导航菜单导航到“创建内容➤工程”,然后填充表单;你需要格外注意一下“完整描述”字段,在这里你可以描述你的模块(或者主题)。填完表单以后,你就可以访问你的工程了,工程地址为:http://drupal.org/project/yourprojectname。
Drupal的核心代码使用了CVS的,然而你工程的其余部分,可能完全没有使用版本控制,也可能使用了一个不同的版本控制系统。
下面是一个例子,如何使用devel模块识别缓慢的查询,从来提高站点的性能。假定我们已经编写了一个自定义节点模块task(任务),而且使用hook_load()来向节点对象添加关于任务的附加信息。表的模式如下:
老葛的Drupal培训班 Think in Drupal
在命令行中运行下面的命令,来测试是否安装了一个CVS客户端:
当你从drupal.org的下载页面,下载了Drupal压缩包时,代码的这份拷贝没有带有任何版本信息;版本信息可用来告诉你基准代码的当前状态。
老葛的Drupal培训班 Think in Drupal
现在你有了一份贡献资源库中modules子目录的拷贝,你可能想现在就可以将你的模块其它上千个模块放到一起了。我们先不要急!首先,花点时间调查一下资源库中是不是已经有一个模块解决了你的问题。下面是一些资源,可帮你确定这一点:
常量
老葛的Drupal培训班 Think in Drupal
下面的PHP调试器和集成开发环境(IDE),提供了一些强大工具,能够帮你快速找到Drupal的瓶颈所在;它们也能够帮你找出模块中的低效算法:
读完本章后,你应该能够:
控制结构体是程序中用来控制执行流程的指令,比如条件语句和循环语句。条件语句有if, else,elseif,和 switch语句。循环语句有while,do-while,for,和foreach。
如果你的签出正常工作了,那么在sites/all/modules/contrib下,应该包含以下内容:
老葛的Drupal培训班 Think in Drupal
文件名应该是小写的。例外情况就是文档文件,它们全部大写并使用.txt后缀,例如:
让我们从头到脚仔细的看看一个模块的基干,同时将不同类型的文档从中选出来进行单独说明。
打开页面http://example.com/?q=admin/settings/devel(如果你启用了开发区块的话,那么还可点击“Devel 设置”链接),选中“Collect query info”(收集查询信息) 和 “Display query log”(显示查询日志)旁的复选框。
你可以使用cvs log命令来查看一个文件的历史。让我们看看foo.info文件的两次提交:
现在模块已经可用于Drupal 5了。让我们继续前进,来创建一个发布。我们将通过创建一个标签来实现这一点。
打标签和做分支是许多修订本控制系统的标准练习。我们将学习一下,如何在Drupal核心和贡献的模块中使用这些概念。花点时间好好的理解一下这些概念,可帮你节省不少的时间,并减轻不少的烦恼。
在分支名字比如DRUPAL-6—1和标签名字比如DRUPAL-6--1-3中,我们看到有两个连字符是连着的。如果你把紧挨着6的连字符看作是Drupal的一个发布的通配符,那么就不难理解了。也就是说,DRUPAL-6--1-3标签,对应于你模块的6.x-1.3发布,它与Drupal 6的任意发布都兼容(Drupal 6.1, Drupal 6.2, Drupal 6.3,等等)。把标签名中主版本号后面的连字符,想象成可以翻译为发布号的x,如下所示:
永远不要在模块名字中使用下划线。为了理解这一点,考虑以下情景:
老葛的Drupal培训班 Think in Drupal
http://drupal.org/project/module_builder中,有一个很好的模块,它能帮你方便构建出模块的骨架。它向你询问你想要创建的钩子,并帮你创建它们,而且还带有示例代码。接着,你就可以在它的基础上开始工作了!
软件测试就是将一个程序隔离成不同的部分,来判定它们的行为和预期的是否一致。在Drupal的接下来的版本中,测试将会是一个主要的目标。事实上,在Drupal 7中,测试将成为核心的组成部分。测试的好处包含以下几点:
现在,你的模块已被提交到资源库中了,这和其它的第3方模块一样,你可以将它从CVS签出,并放在你的Drupal本地开发拷贝中(你可能首先需要创建modules和contrib目录):
我前面提到了,drupal.org有两个资源库,一个用于核心代码,一个用于贡献的代码包括模块和主题。对于前者,只有很少的人能够访问;而对于后者,许多开发者都可以访问。你可以以匿名或者登录用户的身份,来签出贡献资源库。如果你是为了一个站点从贡献资源库签出代码的话(例如,你只想使用CVS获取一个模块的拷贝,这样你就可以运行它了),那么最好使用匿名用户的身份进行签出。否则,当下一个人来维护你创建的Drupal站点时,他想从CVS上更新模块代码,而系统则提示需要输入你设置的密码,那么此时他会晕死的!
在本节中,我们将详细的学习一下,如何在drupal.org上创建和维护一个模块。我们将覆盖大多数的常见任务。
Drupal社区认为,它的基本代码必须拥有一个标准的外观,从而提高可读性,也使得初学者更容易学习。社区也鼓励第3方模块的开发者采用这些标准。实际上,让我老实的告诉你:如果你没有遵守编码标准,那么你的模块在Drupal社区就不会得到认真对待。我们首先学习一下具体的标准,接着介绍了一些用来检查代码的自动工具(甚至为你纠正代码!)
老葛的Drupal培训班 Think in Drupal
如果你修改了Drupal的核心代码,那么当你执行CVS更新时就可能出现冲突。运行完cvs update命令以后,对于那些带有冲突的文件将会使用一个“C”将其标出,由于这些冲突的存在(CVS插入的用来标记冲突的文本,不是有效的PHP),所以你的站点也将不再工作。CVS尝试着合并文件的新版本和旧版本,但是它没有成功,所以现在需要人工干预,来手工的检查冲突文件。发生冲突时,包含冲突的文件就像下面的这样:
想检查开发小组中是否有人修改了核心文件?对于核心文件上所做的任何变更,想为其生成一个报告?cvs diff命令,根据代码的不同之处(也就是更新和修改),为用户生成一个逐行的输出。
老葛的Drupal培训班 Think in Drupal
有两种主要的方式,可用来检查你的编码风格是否符合Drupal的编码标准:一种方式是使用一个Perl脚本,另一种方式是使用一个第3方模块。
Coding Standards: 编码标准
在前面的例子中,我们假定在一个Drupal主版本下只存在模块的一个主版本,但是这也有例外的情况。例如,假定我们发布了foo模块的6.x-1.3版本。接着,灵感爆发了。我们想到了另外的一种实现方式,只需要一半的代码量,就可以实现同样的功能,而且跑得更快。不过,这需要修改API,而与foo模块相关的一切将全被打乱。解决的方案是使用新API发布一个2.0版本。由于模块仍然兼容于Drupal 6,所以我们使用DRUPAL-6--2-0作为标签名,而对应的发布号就是6.x-2.0。