Drupal 是全球最流行的CMS,被广泛应用于网站建设和系统开发。目前国内也有越来越多的爱好者看上了 Drupal,然而因为 Drupal 学习曲线陡峭,且没有很好的Drupal 中文教程,使得很多 Drupal 爱好者苦恼不已。
本站本着学习交流的目的,编写此 Drupal 中文教程,抛砖引玉,以吸取更多更好的 Drupal 资源,供大家参考、交流、学习。
内容不断更新中……
本教程面向所有 Drupal 8 用户,由原创文章与论坛的交流帖合并整理而成,希望对 Drupal 8 使用者有所助益。不定期更新,欢迎约稿、欢迎催更……
本节将介绍 Drupal 中的一些常用词语/术语,了解这些概念对你探索 Drupal 将会有莫大的帮助。
模块是用于扩展 Drupal 特性和功能性的一些代码文件。Drupal 发行包中包含了一系列核心模块,你可以直接启用这些模块来增加 Drupal 的功能。不过 Drupal 核心模块的功能比较简单,提供了一些基本的功能。Drupal 有非常丰富的第三方模块可供使用,你只需要从 Drupal 第三方模块下载页面下载并安装启用即可。你也可以创建自己的自定义模块,不过这需要对 Drupal 有比较深入的了解,也需要熟悉 Drupal API 和具备一定的 PHP 编程能力。
Drupal 第三方模块下载页面:http://drupal.org/project/modules
每一位网站的访问者,不论是使用帐户登录的注册用户,还是匿名用户,都被视为 Drupal 的用户。每个用户都有一个用户ID(User ID - uid),非匿名用户还有用户名、电子邮箱等信息,并且注册用户还可以通过模块为其增加一些其它信息。例如,如果启用了 Drupal 核心的 Profile 模块,就能够为用户定义和添加不同的配置文件字段。
匿名用户的 uid 是 0,安装 Drupal 时创建的超级用户的 uid 是 1。uid = 1 是 Drupal 中的一个特殊用户,他具备在 Drupal 站点中执行所有操作的权限。
除 uid 0 和 uid 1 用户之外,Drupal 中的其它用户通常都通过分配角色(roles)来为他们赋予不同的权限。通过创建新的角色,为角色赋予不同的权限,然后再将用户分配为某种角色,从而使用户具备在网站中执行某些特定操作的能力,例如创建文章、发表评论等。用户所能执行的操作,依照分配给他所属的角色的权限而定。
Drupal 默认有 匿名用户 和 注册用户 两个角色,管理员同样可以通过权限管理页面为这两个角色分配不同的权限。Drupal 的权限管理功能十分精细和灵活,能够为特定的角色分配不同的权限组合。
节点是 Drupal 中的一个通用术语,表示网站中的各种内容(content)。通俗来讲,节点就是网站中的各种文章页面,以下这些在 Drupal 中都称为“节点”:
每个节点都有与之对应的内容类型(Content Type)、节点ID(nid)、标题、正文、作者、发布日期等字段。也可以通过启用核心的 Taxonomy 模块来为节点增加分类/标签字段、使用第三方的 Location 模块为节点增加地点字段,以及使用功能十分强大的 CCK 模块为内容增加各种其它字段。
评论是 Drupal 站点中的另一种内容,需要启用核心的 comment 模块才可以使用。评论是用户提交到某个节点下的一小段内容,例如,对博客的回复/留言都是评论,论坛主题的回帖也是评论。
Drupal 通过核心的 Taxonomy 模块为内容提供了一个分类系统。它允许管理用户定义词汇表(Vocabularies),并向词汇表中添加术语(Terms)。每个词汇表可以关联到一个或多个内容类型,如此一来,就可以通过不同的词汇实现对网站内容的分类。
Drupal 的信息存储在数据库中,不同类型的信息有各自的数据库表,例如节点的基本信息都存储在 node 表中,此外评论、用户、角色、权限、术语表及其它信息都有各自对应的数据库表。
当你通过 URL 访问 Drupal 站点时,URL中位于站点根目录后的部分被称为路径。当你在访问一个 Drupal 路径时,Drupal 将判断将哪种信息返回给浏览器。Drupal 允许启用的模块定义各自的路径,并对这些路径的请求进行响应。当有人访问这些路径的时候,Drupal 就会通过指定的模块将页面内容返回显示给用户。
例如,当你访问 http://lugir.com/node/447 这个URL,路径就是 node/447。对这个路径进行响应的模块是核心的 node 模块,当你访问这个路径时,node 模块将处理这个请求,并将内容返回给你。
当 Drupal 站点没有启用“简洁链接”,路径是URL中位于 '?q=' 之后的部分。当站点启用了简洁链接后,路径则是URL中位于站点根目录后的部分。
Drupal 通过主题(Theme)来控制网站的显示,其它包括网站的外观、色彩、布局和效果。一个 Drupal 主题通常包含一个或多个PHP文件,它们用于控制页面不同部分的 HTML 输出。主题中通常也会包含 CSS、JS 和 图片,它们用于定义网页的布局、字体、颜色和其它风格。
Drupal 的页面可以分为不同的区域(Regions),也可以说,Drupal 的页面由不同的区域组成。Drupal 主题中包含的常见区域有页头(header)、页脚(footer)、侧边栏(sidebar)、主内容(content),不同的主题定义的区域并不相同,例如 zen 主题中还有左边栏(first sidebar)、右边栏(second sidebar)、内容上方区域(content top)和 内容正文区域(content bottom)。
区块(Blocks)是一些用于放置到区域(region)中的内容块,因此被称为区块。
Drupal 默认包含三个菜单——主菜单、次菜单和导航。在大多数主题中,只要向主菜单和次菜单中添加了菜单项,它们便会自动出现在网站的页头或页脚部分,如果没有显示,则可能需要对主题进行一些配置。导航菜单包含了管理菜单中的所有菜单项,方便用户通过导航进行一些操作。用户也可以创建自己的菜单。
Drupal 中文安装教程以图文结合的方式,一步步讲解如何安装Drupal,只需要按照教程,就可以简单的安装Drupal。
目前 Drupal 有 5,6,7,8 四大版本(分别简称 D5,D6,D7,D8),以下是这几大版本的状态:
Drupal 6 中文安装教程
如果安装 Drupal 时没有导入中文语言包,则 Drupal 默认的语言界面是英文,我们可以根据需要导入 Drupal 中文语言包,然后开始使用中文版的 Drupal。
1. 下载中文语言包
访问 http://localize.drupal.org/translate/languages/zh-hans 页面,根据 Drupal 版本类型,下载对应的语言包文件(.po),以备稍后使用
2. 启用模块
2-1. 通过导航 Administer > Site Building > Modules,或者通过在浏览器输入 http://你的Drupal安装路径/admin/build/modules 地址来访问模块管理页面
2-2. 找到 Locale 模块,勾选前面的复选框,然后到页面最下方点击保存(Save Configuration)按钮
3. 导入中文语言包
3-1. 通过导航 Administer > Site Building > Translate interface,或者访问 admin/build/translate 页面,点击"Import"面板进入导入语言包界面
3-2. 向 Language File 文件框中加入第一步下载下来的 .po 语言包文件,将 Import into 选项设置为“Chinese, Simplified(简体中文)”,点击页面最下方的"Import"按钮
4. 将中文设置为默认的界面语言
完成 3-2 步的操作即会返回到翻译界面的概览页面,可点击此页面的 language page 链接,或者通过导航 Administrator > Site Configuraton > Languages 访问"语言设置"页面
在语言设置页面,选中“简体中文”语言项后面的 Default 单选项,点击下面的保存(Save Configuration)按钮
哇啦……之后我们就不用中英结合着来看教程了 :D
安装配置文件(Installation Profiles)为 Drupal 网站实现一站式安装。通过使用安装配置文件,可以轻松地安装具备某些特性和功能的网站(如企业网站、电影网站、SNS社区),而无需手动一个个地启用和配置模块。
安装配置文件中可能包含 Drupal 核心文件、第三方模块、第三方主题,以及一些预定义的配置。
要使用 Drupal 安装配置文件(Installation Profiles),可以先到Drupal 安装配置文件页面进行下载。下载下来的安装配置文件分为两种,一种是与Drupal 核心一起打包的安装配置文件,一种是单独的Profile(配置文件)包。如果下载下来的安装配置文件名为 project-版本号-core.tar.gz,则是包含了 Drupal 核心的安装配置文件。
使用整合了 Drupal 核心的安装配置文件,直接解压缩,按照普通的 Drupal 安装教程 执行安装即可,只是注意在第一个安装界面选择需要使用的安装配置文件
如果下载的是单独的Profile包,则按以下步骤进行安装
如果使用模块时遇到问题,可以到模块项目页面(http://drupal.org/project/主题名称)搜索issues,或者到论坛或QQ群去寻求他人帮助。
说明:建议将使用的主题保持为最新的稳定版本,以保证大多数已经的问题都已被修复。可以通过在 drupal.org 上创建帐户,跟踪你所使用的模块,以获得主题的最新动态。
D7 安装主题较D6有一些改进,除了通过下载主题,手动放置/上传到主题目录下进行安装之外,D7还提供了2种在线安装新主题的新功能,一种是通过URL进行在线安装,一种是通过Drupal上传主题包进行安装。
需要注意的是,通过 URL 安装主题需要事先为 Drupal 配置好 FTP 信息,因为我没有配置 FTP 环境,这里只是简单介绍一下在线安装主题的流程。
访问 外观 > 安装新主题(admin/appearance/install)页面,就可以看到 D7 在线安装主题的界面了
将主题包的 URL 粘贴到“从URL安装”的地址框中,或者选择本地文件上传主题包,点击“安装”来执行主题的安装操作。
zen 主题是 Drupal 主题开发中用得最多的基主题(Base Theme)之一,通过使用 zen,创建 zen 的子主题做为网站的主题,可以节省大量主题开发工作,让主题开发人员将主要注意力集中的主题的结构和布局上,而较少关注一些函数的实现。
本文介绍如何为 zen 主题创建子主题,此教程主要参考 zen 主题的 README 说明文档:
其它操作
安装第三方Drupal模块十分简单,只需从 http://drupal.org/project/modules 下载第三方模块的压缩包,然后将压缩包解压放到 sites/all/modules 目录下,阅读模块说明文件(通常是模块目录下的 README 文档),如果说明文档里面没有要求做其它操作,直接在模块管理页面(管理 > 站点构建 > 模块)选择并启用模块即可。
如果使用模块时遇到问题,可以到模块项目页面(http://drupal.org/project/模块名)搜索issues,或者到论坛或QQ群去寻求他人帮助。
说明:建议将使用的模块保持为最新的稳定版本,以保证大多数已经的问题都已被修复。可以通过在 drupal.org 上创建帐户,跟踪你所使用的模块,以获得模块的最新动态。
本手册参考 Drupal 7 发行包里面的 UPGRADE.txt 文档及 Drupal 在线文档,详解 Drupal 6 到 Drupal 7 的升级过程。
在进行网站升级之前,还有一大堆事情需要先做。在升级前了解已有网站如何建设是非常重要的。在真正升级站点之前在开发环境先进行测试是最好不过的了。
找出网站上安装的模块(包括那些已安装,但之后被禁用的模块)
找出网站上安装和使用的主题
将这些模块和主题列成一张清单,这样有利于升级时进行核对,这份清单还为升级过程中禁用和重新启用模块带来方便。
当对网站中的模块进行完调查之后,能够知道哪些模块实际上并未使用。出于安全性和性能的考虑,我们总是推荐将未使用的模块卸载并移除。
在升级前调查关于模块的情况:
如果网站使用了第三方的主题,就需要研究主题是否能升级到 Drupal 7
如果网站的主题是自定义开发,或者修改自第三方的主题,则需要考虑到主题升级将会花上一些时间,可参考《Converting 6.x themes to 7.x》
使用 Drupal 的原则之一就是“绝对不要修改内核”,然而有时确实更改了内核的一些文件和模块。对于这些修改,进行操作的人应该承担起进行标注和升级的责任。对于第三方模块的修改也是如此。
基于之前对于网站中模块和主题的调查创建网站升级规划文档,文档应包含《从 Drupal 6 升级到 Drupal 7 步骤详解》中的所有步骤。因为升级过程中有许多事情很可能会被遗漏,创建一份核对清单,便于自己查看升级完成的项目和跟踪进度,而且能够节省很多时间。将升级过程中遇到的问题做一些记录,这对以后再进行升级操作是非常宝贵的资源。
以下内容可以考虑加入到文档中:
参考文档:Make an Upgrade Plan
对 Drupal 版本进行升级之前,建议先检查第三方代码与自定义代码与新版本的兼容性,在完成这些检查并了解新旧版本的可升级部分之后,便可通过以下步骤开始升级了。
执行完以上步骤,便完成了 Drupal 6 到 Drupal 7 的升级操作,有关 Drupal 7 的管理功能介绍,可参考 http://drupal.org/getting-started/7/admin
到目前为止,以上步骤只完成了 Drupal 核心文件从 6.x 到 7.x 的升级,对于个别模块的升级,请单独参考模块对应的 7.x 版本中的 UPGRADE.txt 文件,并根据模块作者的说明进行升级。
参考资料:
本文档记录 Drupal 6 升级到 Drupal 7 的一些注意事项和处理技巧,从而避免在升级过程中遇到一些常见问题。
注意事项:
如果没有执行以上操作,常常会出现找到不指定函数而导致网站无法打开的情况,因此在执行升级前,请确保禁用了所有的主题和模块。
如果升级之后网站不能打开,查看 Web 服务器日志,一般能够定位到出问题的原因。
技巧:在升级之后发现有模块和主题没有禁用,可以通过修改 Drupal 数据库中 system 表中 status 列的值来设置主题或模块的状态(并不推荐这个办法,但这样做确实能解决一些问题。大家最好还是在进行升级前确认禁用了所有第三方和自定义的模块和主题)
如果网站数据较多,升级过程会变得十分漫长,可能会长达几个小时,因此在进行数据库更新之前,可以:
说明:cache 开头的数据库表都是缓存数据,search 开头的数据库表保存是的搜索相关的索引数据,尤其是 search_index 表中的数据量巨大(几百万、千万、上亿)。这些表中的数据都是可以自动再生成的内容,因此清空这些表对于减少数据库体积十分有效果。
注意:有关清空所有 search 开头数据库表的作法并不知道有没有什么副作用,有顾虑的朋友请进行一些研究。(cache 开头的表可以安全清空)。
技巧:对于中大型网站,建议使用 drush 来执行数据库更新操作(drush updatedb),因为对于数据库的升级可能长达几个小时,通过访问 update.php 来执行升级操作可能出现PHP脚本执行超时和AJAX的错误。
如果您在升级过程中遇到其它一些常见问题,欢迎分享您的经验或者提问 :)
执行 Drupal 升级进行之前,请务必先备份好所有的文件和数据库。因为,如果升级过程中出现任何问题,除了使用备份,没有其它更好的办法让你的站点恢复原状。并且,如果在升级过过程中遇到任何错误,都不应该再执行任何更进一步的操作。
备份数据库:
备份 Drupal 数据库,可根据用户的实际情况使用命令行或者 PhpMyAdmin 进行备份。因为 PHP 脚本有最大执行时间限制,因此在使用PhpMyAdmin备份较大的数据库文件时可能会因超时而导致备份失败。MySQLDumper 和 Bigdump 是两个可选的数据库备份工具。
备份文件
升级 Drupal 前需要备份的文件包核心文件与非核心文件,核心文件即为 Drupal 发行包中包含的文件,非核心文件通常是指第三方模块、第三方主题或其它用户生成的文件,默认情况下,这些非核心文件都位于Drupal安装目录的 sites 目录下。
所以升级之前,应该备份 Drupal 数据库与 Drupal 安装目录下的所有文件,以确保升级出错后可以使用这些备份来还原站点。
参考文档:
本文档提供了一份模块清单,这些模块有 Drupal 6 版本,在升级到 Drupal 7 之后,这些模块的功能已经部分或已完全被整合到 D7 的核心了。
以个列表还在不断更新,因此并非最终版本,最新版本的原文可以查看《Drupal 6 contributed modules that are in Drupal 7 core》
以下这些模块的功能已经包含在 Drupal 7 的核心中,它们的升级不涉及数据迁移。当网站从 D6 升级到 D7 时,可以将这些模块从模块目录下移除。升级完成后,可能需要对这些模块进行重新配置以便恢复 D6 时的功能。(对于包含复杂配置的模块,我们也希望模块维护人员提供自动化升级能力)
以下模块的部分功能被集成到 D7 核心,但其自身仍然具备一些额外的功能,如果你没有用到这些额外的功能,则可以卸载这些模块。
以下这些模块在站点升级时需要被保留,首先需要完成《从 Drupal 6 升级到 Drupal 7 步骤详解》中的所有步骤,然后安装一些处理数据迁移的辅助模块。
本文档整理了一些与使用 Drupal 相关的教程,如 Drupal 的配置、如何使用 Drupal 实现某些功能、如何使用和配置 Drupal 模块、Drupal 使用小技巧等。
使用 Drupal 核心模块的 Taxonomy 模块,将创建的词汇表(Vocabulary)与指定的内容类型想关联,很容易就可以实现对内容进行分类。一旦对内容进行分类之后,就可以执行一些基于分类的操作,比如显示某一分类下的所有内容,基于分类显示内容列表区块等。
访问 管理 > 内容管理 > 分类 > 添加词汇表(admin/content/taxonomy/add/vocabulary)页面
填写“术语表标识”
选择将使用此术语表的内容类型。内容类型配置项会列出 Drupal 中所有的内容类型,我这里并没有添加其它内容类型,所以只有默认的新闻(Story)和页面(Page)
设置术语表类型。
术语表类型配置的前两项会决定术语表在添加节点页面的显示方式。
创建完词汇表之后,便可以在术语表管理页面(admin/content/taxonomy)看到刚才新建的“栏目分类”词汇表
点击词汇表后面的“添加术语”链接,进入添加术语页面,简单创建几个术语,然后对术语层级进行一下调整,得到如下的词汇结构:
经过前面创建词汇表(将词汇表关联到内容类型Story),然后向词汇表中添加了词汇,之后,便可以在管理 > 内容管理 > 创建内容 > Story(node/add/story)页面,看到并使用新添加的“栏目分类”术语表了
在 Drupal 7 中,使用术语表为内容添加分类,与《Drupal 6使用术语表为内容添加分类》的步骤基本一样,稍有不同的一点在于,D7 没有在词汇表的配置页面将词汇表与内容类型进行关联,而是需要稍后将术语表做为内容类型的一个字段添加到内容编辑表单。
本文将介绍如何在 Drupal 7 中,使用术语表为内容添加分类的做法。
访问 管理 > 结构 > 分类 > 添加词汇表(admin/structure/taxonomy/add)页面,填写词汇表的基本信息并点击保存
创建完词汇表之后,便可以在术语表管理页面(admin/structure/taxonomy)看到刚才新建的“栏目分类”词汇表
点击词汇表后面的“添加术语”链接,进入添加术语页面,简单创建几个术语,然后对术语层级进行一下调整,得到如下的词汇结构:
访问 管理 > 结构 > 内容类型(admin/structure/types)页面,可以看到系统中存在的内容类型的列表
点击“基本页面”所在行的“管理字段”链接,进入“基本内容”内容类型的字段管理页面。在添加新字段处填写以下信息,然后点击“保存”:
在字段设置页面,选择术语来源,然后点击“保存字段设置”
选择“术语来源”之后,点击“保存字段设置”之后,会进入到字段详细配置页面,根据自己的需要对字段进行配置,因为这里只是做演示,直接点击页面最下方的“保存设置”即可
在返回的字段管理页面中,就可以看到“栏目分类”字段已经成功显示在内容类型的字段列表中了。拖动标签前面的十字架,将栏目分类移动到Title后面,结果如图示
访问 管理 > 信息面板 > 添加内容 > 基本页面(node/add/page)页面,已经可以在标题(Title)字段下方看到“栏目分类”字段了
各种类型的网站都可以用到幻灯片,不论是用途网站首页的图片展示还是用于制作大气的图片轮换Banner。Drupal 中用得较多的幻灯片模块有 Views Slideshow 和 DDBlock 两种,本文将以 Views Slideshow 为例,详细介绍使用 Drupal 制作幻灯片的步骤:
用到的模块:
确认安装并启用以上模块之后,便可以按照以下步骤来创建 Drupal 幻灯片了 :D
提示:本文最后提供了一个打包好的幻灯片配置包,大家直接下载并启用就可以得到按照本文配置的基本幻灯片了 :D
添加内容类型,访问管理 > 内容管理 > 内容类型 > 添加内容类型页面 (admin/content/types/add),按以下配置创建内容类型之后点击保存
名称: slideshow
类型: 幻灯片
新添加的 Slideshow 会出现在内容类型管理列表中,点击 Slideshow 对应的“管理字段" (manage fields) 链接,进入 Slideshow 编辑页面
添加幻灯片图片字段:在管理字段页面,按以下配置添加图片 (ImageField) 字段后点击“保存字段设置”按钮
配置幻灯片图片字段:在图片字段配置页面,配置以下信息及根据你的需要进行配置后点击“保存”
添加幻灯片链接字段:在管理字段页面,按以下配置添加链接 (Link) 字段后点击“保存”
配置幻灯片链接字段:在链接字段配置页面,根据需要配置后点击“保存字段配置”按钮
调整字段顺序:在管理字段页面,将幻灯片图片和幻灯片链接拖动到正文的前面,然后点击“保存”
访问创建内容 > 幻灯片 (node/add/slideshow) 页面,填写标题、上传图片、填写幻灯片链接标题和URL,正文可以留空,然后保存即可
重复此步骤创建大概5张不同的幻灯片图片
访问管理 > 站点构建 > ImageCache > 添加 ImageCache 预设页面 (admin/build/imagecache/add),设置名称后点击保存
ImageCache 预设名称:Slideshow
在运作中,点击"添加 Scale And Crop "链接,在新窗口设置幻灯片大小后点击"创建动作"
注意:点击创建动作后,可以在页面下方看到缩放成 300 x 240 大小的图片,如果看不到图片预览,请查看模块管理页面,确保 ImageAPI GD2 和 ImageAPI ImageMagick 至少有一个是启用状态。
访问管理 > 站点构建 > 视图 > 添加 页面(admin/build/views/add),配置以下信息后点击“前进”
添加区块:在 View 配置页面的最左边,从下拉框中选择“区块”, 点击“添加显示”
配置幻灯片区块:按照以下顺序和配置对幻灯片区块进行配置
访问管理 > 站点构建 > 区块管理页面 (admin/build/block),找到 slideshow: 区块,将其分配到指定的区域后,点击保存。
为幻灯片区块添加 CSS,做一些美化,使幻灯片看起来更漂亮。
本文介绍了配合 Views Slideshow 创建幻灯片的基本用法,大家可以根据需要,自行添加一些字段以及更改 Views Slideshow 的配置更幻灯片变得更加丰富。使用 Views Slideshow 可以创建各种类型的幻灯片片,下面提供几个幻灯片示例以供大家参考交流。欢迎留言交流 :D
1. 只带页码的幻灯片
2. 包含页面和标题的幻灯片
3. 纵向带页码的幻灯片
4. 带标题、缩略图和控件的复杂幻灯片
虽然本文介绍了制作幻灯片的步骤,但每次在不同的网站上又重新配置一遍也比较辛苦,为了节省重复的配置工作,我制作了一个特性包,大家直接下载且启用就可以得到一个基于本教程的简单幻灯片了,详情请参考《Fox Slideshow - 基于 Views Slideshow 的幻灯片 Features 包下载》
Drupal 的评论功能,默认可以配置成允许匿名用户填写联系信息,使匿名用户可以使用任意昵称发表评论。而 Drupal 注册用户,在登录之后,默认只能使用用户名进行回复,无法像匿名用户那样使用任意昵称。
本文通过创建一个简单的 Drupal 模块,为拥有 set comment name 权限的登录用户,能够在发布评论时手动设置昵称。
创建模块文件夹: sites/all/modules/comment_name
创建模块信息文件:在comment_name模块目录下创建模块信息文件, comment_name.info,并将以下内容写入到 comment_name.info 文件中
创建模块文件:在 comment_name 目录下创建 comment_name.module 文件,将以下内容写入到 comment_name.module 文件中
<?php
/**
* Implementation of hook_perm().
*/
function comment_name_perm() {
return array('set comment name');
}
/**
* Implementation of hook_form_alert().
*/
function comment_name_form_alter(&$form, $form_state, $form_id) {
//dsm($form);
global $user;
if ($form_id == 'comment_form' && $user->uid != 0 && (user_access('set comment name') || $user->uid == 1) ) {
// add comment name textfield
$form['comment_name'] = array(
'#type' => 'textfield',
'#title' => t('Authored by'),
'#size' => 30,
'#maxlength' => 60,
'#default_value' => '',
'#weight' => -1,
);
}
}
/**
* Implementation of hook_comment().
*/
function comment_name_comment(&$comment, $op) {
switch ($op) {
case 'view':
// When comment load, use comment_name value replace username
$_comment = _comment_load($comment->cid);
$comment->name = $_comment->name;
break;
case 'insert':
// After comment saved, use comment_name value replace username
$query = "UPDATE {comments} SET name = '%s' WHERE cid = %d";
db_query($query, $comment['comment_name'], $comment['cid']);
break;
}
}
?>
启用模块:访问 管理 > 站点构建 > 模块(admin/build/modules)页面,启用 Comment Name 模块
设置权限:访问 管理 > 用户管理 > 权限(admin/user/permissions)页面,为指定的用户角色启用 set comment name 权限
完成以上操作之后,访问某个可评论的节点,拥有 set comment name 权限用户和 Drupal 管理员在发布评论时就能够以匿名用户的身份,使用任意名称发表评论了。
像 Google Book 和 百度文库 那样的文档在线阅读功能非常实用,要想为 Drupal 站点实现这样的文档在线阅读功能,可以通过 SWF Tools 模块来实现。
A. 启用并配置 SWF Tools 和 FlexPaper
B. 制作可通过 FlexPaper 在线浏览的电子书
C. 上传转换后的 .swf 格式电子书
[swf file="http://lugir.com/sites/default/files/test.swf"]
以下是使用 SWF Tools 模块和 FlexPaper 实现的在线电子书的效果截图
PS: 安装好的 FlexPaper 无法显示放大缩小的工具条,我为SWF Tools的这个功能写了一些补丁文件,有需要可以到下面的地址下载和使用:
http://drupal.org/node/1159076
如果想要为 Drupal 站点生成一个评论数量最多的用户排行榜,可以在区块或内容中使用以下 PHP 代码片段来实现
<?php
$query = "SELECT COUNT(*) AS count, c.uid, u.name FROM {comments} c
LEFT JOIN {users} u ON c.uid = u.uid WHERE c.uid != 0 AND c.uid != 1
GROUP BY c.uid ORDER BY count DESC LIMIT 10";
$result = db_query($query);
$output = "<ul>";
while ($user = db_fetch_object($result)) {
$output .= "<li>" . l($user->name, drupal_get_path_alias("user/{$user->uid}")) . " (" . $user->count . ")</li>";
}
$ouput .= "</ul>";
echo $output;
?>
以上代码默认显示10位用户,要更改显示的用户数量,更改 "LIMIT 10" 中的数值即可。
另外,此代码将匿名用户(uid=0)和管理用户(uid=1)排除在统计之外,如有需要,可更改 WHERE 选择语句的条件。
本文介绍如何为 Drupal 站点准备和安装 Boost 模块,以及在成功配置 boost 模块后如何检验模块是否正常工作。
完成以上所有操作后,Boost 就可以正常运行了
注意:因为服务器配置的不同,Boost的默认配置可能不会生效,此时可尝试修改Boost配置中的 Server URL or Name 及 Document Root 两项以解决问题
使用 diff 命令可以为文件创建 patch 文件,通过执行以下代码即可
以上命令的意思是,对比 file_new 与 file_old 的不同,将两者的差异导入到 file.patch 文件中。以便于其它人可以使用这个 file.patch 为 file_old 文件打补丁
关于如何应用 .patch(补丁)文件,可参考《使用 patch 命令为文件打补丁》http://lugir.com/node/419
下载及安装
可选,如果希望 JQuery Easing 效果,可以到下载 JQuery Easing 插件
本文介绍 DDBlock 的基础用法,即使用指定目录下的图片,创建一个简单的图片幻灯片
添加、启用和配置 DDBlock
说明:所创建的 DDBlock 会按照第4, 5步的配置,从指定的目录中取得图片并显示。
Drupal 核心提供了 Locale 模块用于为 Drupal 站点提供本地化的功能,使用 Locale 模块创建本地化的站点非常实用,并且能够制作较为简单的多语言站点。不过,我们更推荐使用 i18n 模块,通过 Drupal 创建多语言站点。有关 i18n 模块及其它多语言站点相关的模块的使用,将会再本教程中陆续介绍。
*说明:本文虽然是在D6时代撰写,但大部分内容对于现今版本的Drupal依然适用。
本教程将介绍以下内容:
接下来我们就开始使用 Drupal 创建包含中文和英文两种语言的多语言站点 :D
现在,我们已经创建了可以切换语言界面的 Drupal 站点,以下分别是站点的中文界面截图和英文界面截图
Drupal 多语言站点中文界面截图
Drupal 多语言站点英文界面截图
相信大家也发现了,在切换语言时,尽管界面语言都进行了中英文的切换,但是像“网站标题”这样存储在数据库里面的配置项,却没能被翻译过来。Locale 能够做到界面内容的翻译已经很不错,至于网站变量的多语言化,以及术语表、内容、CCK、菜单、区块等元素的多语言化,就交给接下来要介绍的 i18n 模块来做吧。
上一节我们已经使用 Drupal 核心的 Locale 模块为 Drupal 站点启用了多语言的功能,并且对 Drupal 界面进行了翻译。不过还遗留了一点点小问题,就是 Drupal 的站点标题没有翻译过来。
Drupal 中的一些文本和配置存储在数据库的variables表中。比如“站点名称”和“站点口号”这样的配置文本,Drupal 核心的 Locale 模块不能实现这些配置变量的多语言化。因此创建一个更彻底的多语言站点,还需要用到 Internationalization(i18n)模块,i18n 模块提供了 Drupal 变量多语言化的功能。
要实现对 Drupal 变量的多语言化操作,需要知道要翻译的变量的名称,这一步可以通过搜索 Drupal 数据库的 variables 表来实现。
当你确定要对哪些变量进行多语言化操作时,你只需要按照以下格式,将变量添加到 settings.php 文件中即可。以下添加了 Drupal 站点的一些常见变量:
当启用了 i18n 模块,并且向 settings.php 配置文件中添加了以上代码之后,可以在 管理 > 站点设置 > 语言 > Multilingual system > Variables(admin/settings/languages/i18n/variables)页面中,看到可以实现多语言化的变量名称及翻译状态。
尝试在语言间进行一些切换,可以看到中文界面使用了中文的标题和口号,英文界面则使用英文的标题和口号
Drupal 多语言站点中文界面截图
Drupal 多语言站点英文界面截图
Drupal 核心提供的 Content translation 模块,为创建多语言的 Drupal 站点提供了内容多语言化的支持,本教程将介绍如何为内容创建不同语言的翻译版本。
创建翻译之后,可以在节点页面的下方看到一个翻译链接,点击翻译链接即可看到内容的翻译版本。
只使用 Drupal 核心所提供的功能,还不能菜单项的多语言化/翻译。不过使用 i18n 模块包中提供的 Menu translation 模块,可能很好的实现菜单、主链接/次链接的多语言化功能。
i18n 模块包中的 Menu translation 模块,提供了以下特性:
访问 管理 > 站点构建 > 菜单 > 设置(admin/build/menu/settings)页面,可以看到“主导航菜单来源”及“次级菜单来源”都被标识为“多语言化变量(This is a multilingual variable)”,这说明这两项值,在不同的语言环境下,可以设置不同的值,并被数据库分开保存。(更多关于多语言化变量请参考《站点变量(Variables)多语言化》)
在中文语言下,为主链接/次链接选择恰当的中文链接,在英文语言下,为主链接/次链接选择恰当的英文链接,从而实现在不同语言下,使用不同语言的菜单项,以此来实现 Drupal 网站中菜单的多语言化。
为 Drupal 创建多语言化支持的区块,需要 i18n 模块包中的 Block Translation 提供相应的支持。有两种方式可以实现区块的多语言化,一种是对区块(Blocks)中的字段进行翻译,另一种是为每一种语言创建一个对应的区块。本文将介绍这两种区块多语言化的方法。
在迁移 Drupal 站点时,数据库迁移是非常重要的一步。一般来讲,数据库迁移包含从老服务器上导出数据库,及在新服务器上导入数据库。
备份数据库非常简单,使用 phpMyAdmin 或者其它数据库管理工具都可以实现。但是在将数据导入到新的服务器时,常常会遇到一些错误而导致数据库迁移失败(如图)。通常情况下,都是因为缓存数据的原因。即 cache 表及以 cache_ 作为前缀的数据库表。
Drupal 在启用缓存的情况下,会在 cache 及 cache_ 前缀的数据库表中写入许多缓存数据,但这些数据对于数据迁移并不是必须的,因为当站点转移到新服务器之后,这些缓存数据又可以重新生成。但是这两个表里面的数据结构,常会出现SQL语法错误而导致数据库导入失败。
以下是处理这些问题的一些方法:
总之,导出时保证 cache 及 cache_ 为前缀的表中无数据即可。
然后将备份的数据导入到新的服务器中,即可完成 Drupal 数据库的迁移。
大家在上网时经常能够看很多网站都有很酷很实用的多条件过滤,通过组合许多不同的过滤条件,帮助用户逐渐缩小内容的显示范围,逐渐找到最需要的内容。
比如像优酷这样的电影过滤
不过相信更多的Drupaller是在做商城类的项目时遇到这样的需求,即便如此,换汤不换药 :D 大家很困惑,甚至觉得有些压力山大,究竟用 Drupal 能不能为产品实现这样的多条件过滤呢?
——当然可以了,除了给你生个孩子,还有什么是 Drupal 做不到的呢 ;)
在开始介绍如何实现这样的功能前,我们先统一一下对需求的认识。并且在这里希望大家认识到随着网站信息量的增大,内容标识维度的增加,不只是电影网站、网上商城,多条件过滤可以应用的范围是非常广泛的,旅行、美食、创业、图书管理、同城交友哪里都可以它的身影,希望大家开动脑筋、发散思维 :D
好了,下面我们一起来整理一下多条件过滤的一般需求,同时我们也提出一些高级的需求,一方面是挑战自我,另一方面也是因为现一个功能很简单,但要把一个功能在现实世界中用好用强,要考虑的东西还会多很多。
如果能实现基本需求,已经很好了,如果能够把高级需求一并实现,那就真是太酷了。当然这一切对 Drupal 而言只是不能生孩子之外能够做的众多事情中的一件,下一篇我们就来分享实现这样的多条件过滤的思路和流程 ;)
在上一篇《 Drupal实现多条件过滤导航(上)》中我们已经了解到多条件过滤导航的基本需求和高级需求,下面就来看看通过Drupal如何得以实现。
需求拿到手上,首先要想的即是有哪些第三方的模块可以供我们使用,如果还不知道哪些模块可供使用,使用 Google 或者 drupal.org 进行简单的搜索即可得到一些常用的解决方案。
在开始搜索之前,有几个关键词可以帮助我们进行搜索——search(搜索)、filter(过滤)、faceted(分面搜索)、Solr(Apache Solr)。因为 filter 在 Drupal 里是“输入格式”的专有名词,进行这个搜索得到的结果往往并非是我们所需要的。另一方面我们希望通过尽可能简单的方式来实现这一功能,因此也不希望还要做到与 Apache Solr 进行整合。所以,最终我们通过 search 和 faceted 两个关键词展开搜索。
……
经过一番搜索和尝试之后,大致得到以下一些模块可以帮助我们实现所需的功能,这些模块是:
与此同时,搜索过程中还能找到一些非常实用的教程,如 Ivan Zugec 的 《How to setup Search API with Apache Solr》——尽管这篇文章里面是用 Solr 作为后端搜索引擎,如果我们希望简单地实现这一功能,使用前面提到的 Search API Database Search 来替换教程中要用到的 Search API Solr Search 模块即可。
当按照教程完成分页搜索的配置后,即可得到类似以下截图的搜索页面,根据需要创建相应的 Faceted Block View,分配到指定的位置,然后使用CSS控制区块的样式布局(如将所有链接显示在同一行)即可
对于基本的过滤搜索,使用 Search API 来实现就能足够了,即使当数据量较大时,使用Solr作为后端搜索引擎,效率和性能也会相当出色。
在使用 Search API 结合 Database Search 或 Solr Search 时,对于中文站点而言,更适合用于条件过滤或非搜索过滤上,因为不论是 Database Search 还是 Solr Search,在不添加分词工具的情况下它们不具备合适的中文分词能力,因此如果是需要的支持中文且需要结合搜索过滤的情况下,我们则应该考虑另一种解决方案。
下一篇我们将接着介绍使用Drupal实现多条件过滤导航的另一种解决方案,不但配置简单,而且可以满足我们在需求篇中提到的两大高级功能——即除链接过滤之外的其它过滤方式(字符串搜索、价格区间、星级……)以及全局过滤条件(当页面有多个相关的内容块时,过滤条件同时作用于多个内容块)
在 D6 时代,Views 更多只是用于构造各种新闻列表、图文列表、图片集、幻灯片之类的列表或结果集。进入 D7 之后,因为 Views 被应用得更广泛,以及更多基于 Views 的第三方模块的出现,使用得 Views 的功能越发的强劲。而在 D8 中,Views 更是直接被加入了内核,可见 Views 的实用性非同一般。
很多朋友从来只用 Views 做过简单的内容列表,不曾玩过太多基于 Views 的花样,今天我们也借着多条件过滤导航这样一个功能的需求,小窥一下 Views 不太一样的用法。
有前两篇的基础,这里就不再介绍需求和背景了,直接切入正题,理一理思路,看看如何使用 Views 来实现上图的多条件过滤导航。
首先,上图应该是由三个 Views 组成,即左上的“热点真题”、左下的“精选真题”以下右侧的“最新真题”
我们在此要实现的功能呢,即当用户使用右上方的“搜索”以及各种条件进行导航时,三个区域的内容要发现相应的变动——比如默认时三个视图均显示所有学科的内容,当用户点击了“物理”之后,三个视图均只显示与物理相关的内容。(这种设计不只在教育平台中实用,在各种电影、旅行、美食、电商站点均可提供非常爽的用户体验:D)
像这样的设计通过 Views 要如何来实现?一旦解决方案被提出来了,大家就都会觉得真是十分的简单——将节点的字段作为过滤条件显示(暴露)出来,即可实现通过多条件/多形式进行过滤的功能,然后因为 Views 使用过滤条件时使用 GET 方式将参数追加到 URL 后,因此只要边栏的另外两个视图同样能够接收 URL 中的参数,就可以实现一处过滤,多处过滤的条件导航了。
这里并不打算再重新截图一步一步来实现上图的效果:D 有兴趣和有需要的朋友可以参照以上的思路在自己的项目中实现这样的多条件过滤,不用写代码就能用 Views 搞出如此这般强大的页面,实在是很爽的。
Taobaoke(淘宝客)模块使 Drupal 连接淘宝开放平台,通过淘宝网(http://www.taobao.com)提供的海量商品数据,可以迅速地创建基于 Drupal 的淘宝客商城。
本教程将介绍 Taobaoke 模块的安装及使用。
使用 taobaoke 模块需要用到淘宝开放平台(TOP)提供的 SDK,即 TopSDK,大家可通过以下链接进行下载:
淘宝开放平台淘宝客SDK下载:taobao-sdk-php-taobaoke.zip
说明:本SDK为淘宝官方2011年11月4日版本,也是 taobaoke 模块当前开发所使用的版本,推荐使用。
淘宝客模块目前还在开发中,但不影响使用,大家可以到我的沙盒用下载:
Taobaoke(淘宝客)模块项目主页:http://drupal.org/sandbox/lugir/1170452
详细教程编写中,稍安勿躁…… :)
传送之门 Alpha 2.0 版本已经上线,相对于上一版本增加了不少新特性,现在用户不仅可以收藏系统已有的页面,还可以与大家分享自己看到的优秀页面。
在这些功能的基础上,如果能够增加收听功能就更好了。这样一来用户就可以关注感兴趣的用户,当关注的用户分享了新的内容,便能够方便的在好友动态中看到。
根据现有的经验来看,要使用 Drupal 来实现这样的收听功能,应该是存在不少相关的第三方模块。比如可能存在 follow, activity 这样的模块。
在真正动手去搜索 follow, activity 这类关键词之前,首先还是将需要实现的需要罗列出来,有的放矢才不会在搜索模块时看得眼花缭乱。
需求整理好之后,接下来就开始基于这些需求开始查找可用的模块了。结合想到的关键词 —— follow, following, activity, 以及可能符合条件的两个模块 flag, heartbeat,下面就开始用 google 和 drupal.org 进行搜索了。
等找到合适的模块之后,我们再继续通过后续的文章来看如何为 Drupal 实现好友收听功能。:D
上一篇我们讲到《如何为Drupal实现好友关注/收听(follow)功能的需求分析》,然后便开始针对一些关键词和模块进行搜索、调研和试用,最终决定使用 Flag 及 Message 模块来实现所需的功能。
在确定使用 Flag 及 Message 模块之前,搜索了诸如 follow, activity 之类的关键词,同时也通过 Google 进行了一些搜索,还通过 Drupal 模块页面的相关项目了解了其它不少模块。下面列出好友收听/关注这类功能可能用到的一些模块,如果大家有类似的功能需要实现,可以进行一些了解。
以上模块都有其各自的一些功能和优势,但最终都没有选择,下面说明一下我们是如何基于《如何为Drupal实现好友关注/收听(follow)功能的需求分析》来进行模块筛选:
在模块选择这一阶段,最终选择了使用 Flag 和 Message 模块。选择这两个模块,主要基于以下条件考虑:
从分析上来看,只使用 Flag 和 Message 模块即可以实现好友关注及查看好友动太更新的功能。那后续的博文我们就需要实际进行一些操作和配置,看看如何使用 Flag 模块实现一键关注/收听,以及如何结合 Message 模块实现查看关注用户的动态更新。
Drupal 配置迁移是什么?很多 Drupaller 对这个话题感到无所适从,新人工作之初并不会意识到这个问题的存在,而意识到这个问题的朋友也不确定怎样正确地进行配置迁移。本文就围绕 Drupal 配置迁移的原因、方式/方法及相关模块较为系统地聊聊这个话题。
如果你被以下问题困扰,仔细阅读本文将会对你有所助益
大家都熟悉传统的Web开发,主要工作都是面对代码,不管是PHP、CSS、HTML或JS,几乎所有的工作都是在文件中完成。如果要更新或升级某些功能,做好备份后上传修改过的文件就能完成,So Easy!
对Drupal而言,配置迁移就不那么简单了,因为文件迁移只是 Drupal 配置迁移的一小部分,Drupal 中大部分的配置存在于数据库中。而因为线上环境的数据库时刻在变化,要把开发环境中一部分数据库的内容更新到线上而又不影响线上的内容,可不是一件容易的事。
Drupal将配置存在于数据库中是经常被Drupal老手们诟病的问题之一——最大的缺点是你不能简单地迁移数据库中的某些值或对其实行版本控制,当然这样设计的优点在于方便开发人员进行研发,以及方便使用者通过界面(而不需要修改代码)非常快速地对功能进行调配。(再一次,Drupal选择了灵活性而牺牲了其它东西)
在D8之前,Drupal没有统一的标准来规范大家应该如何存储各自己的配置数据,不同模块的配置格式和存储方式并不相同,因此也就无法通过某种特定的方式一次性迁移出所有配置数据。
(D8开始实施配置管理系统了,从此对配置的管理有了统一的规范和标准,可参见《Drupal 8 配置管理机制及新特性简介》)
而另外一点造成Drupal的配置迁移成为一个难点话题的原因在于,D8之前,Drupal的配置和内容混合存储在数据库中,很难将两者分离开,如果只是通过覆盖数据库的方式来进行操作,无法做到只改变配置而不触及内容,反之亦然。
因为设计上的原因,使得Drupal的配置迁移成了一个难点,针对于它的工作流程和解决方案也就成了一个独立的、不可回避的且颇有意思的话题。
目前有关Drupal配置迁移的处理方式已经非常成熟,D8之前的配置迁移可以参考本文,D8的配置迁移大家去学习其配置管理系统的知识并熟练运用即可。虽然D8之前没有官方统一的标准配置管理体系,但D8配置管理体系的很多理念与本文提及的各种配置迁移方式是相同的,因此学习本文也将会使之后了解D8的配置管理系统变得更为容易一些。
相信有很多朋友在做 Drupal 开发时会先在本地做一次,然后到测试环境或生产环境再做一次。当然这也不失为一种方式,对小站点的功能部署还能适用,但对于在线下进行了几周甚至几个月的工作量,再重复做一次的代价可是相当大的——前提还要是每个人都记得整段时间都按什么顺序做了什么配置。
如果大家希望更轻松、更准确、更高效、更简单地完成配置迁移的任务,不妨学会如何让配置迁移更为自行化。
以下是通过各种工具进行自动化配置迁移的一些主要优点:
之所以要谈配置迁移,是因为Web项目至少会有两个环境,即工程师的本地开发环境,和在线运行的生产环境。而通常情况下,标准的Web项目会涉及“开发-测试-线上”,即流行的 Dev-Stage-Prod 模型(也有称Dev-Stage-Live),复杂点的情况还会再加上一个QA环境。也正因为如此,才出现了配置迁移的需要。
在后文中,我们将以 Dev-Stage-Prod 环境模型为来了解 Drupal 的配置迁移方式及方向。因为这正好代表了我们平时的工作流程——工程师在各自的本地进行开发,然后部署到测试环境集中测试,反复修正最后再部署到线上。
了解了需要迁移的原因,我们再看看需要迁移的内容。正如前面所说,Drupal 中不同的配置有不同的迁移方式,使用对的工具和对的方法能够达到事半功倍的效果。
迁移项 |
存储位置 |
迁移方式 |
模块、主题 |
模块、主题文件中 |
直接上传文件 |
环境变量 |
数据库中 |
|
视图、编辑器、内容类型、字段、区块 |
数据库中 |
使用 Features 及 Features Extra 等模块打包到文件,然后上传 |
*术语、用户等配置依赖内容 |
数据库中 |
可使用 Features, UUID 及 UUID Features 等模块打包到文件,然后上传。 但建议先添加到线上环境,然后将数据库下载到本地进行开发会更简单,详见下方 |
…… |
…… |
…… |
不要感觉要记很多东西似的,这里帮你整理一下 —— Drupal 的配置无非就是存在于文件和数据库中,存在文件中的配置很好处理,直接上传就行。而对于存在于数据库中的配置呢?很简单 —— 先转化成文件,然后上传文件。
在举例说明不同配置迁移的最佳实践前,建议大家一定记住下图——代码(配置)由下往上,数据库(内容)由上往下——这是团队协作的基本铁律,以便确保文件和数据库都是由新往旧的方向部署,从源头减少冲突的发生。
(很多人在协作时会问这样的问题,说“我在线上修改了视图的配置,然后线下更新了视图的配置文件,这样要怎么更新呢?”这就是典型因为协作流程不规范而产生的人为冲突,一旦按照规范能够约束文件(配置)、数据库(内容)的更新方向,这类问题基本上便不会出现了。)
回到文章开头提到的几个问题,现在再来看看这些配置迁移流程建议:
现在看来,Drupal的配置迁移无非是两部分的内容,一部分已经存在于文件(如模块、主题)中的内容,直接上传文件进行更新即可;另一部分存在于数据库中的部分配置(或内容),即通过Features及其它相关模块先将配置导出到文件中,再按更新文件的操作进行即可。
别看关于 Drupal 配置迁移好像写了不少,主要便是掌握 Features 模块的用法和流程,稍加练习几次就会发现真是非常简单。
本代码规范翻译自 Drupal 官方网站的代码规范文档(http://drupal.org/coding-standards),方便国内的 Drupal 开发人员更好的学习和遵循代码规范。优秀的开发人员应该有遵循高标准以及编写高质量代码的意识。:)
控制结构包含 if, for, while, switch 等等,下面是一个简单的 if 语句结构示例:
控制语句的关键词与左边括号之间应该有一个空格,以此来与函数调用进行区分。
即使在大括号是可选的情况下,也应当总是使用大括号。这样可以加强代码的可读性以及减少因嵌套带来的逻辑错误。
switch 语句结构示例:
do-while 语句结构示例:
<?php
// Key is only valid if it matches the current user's ID, as otherwise other
// users could access any user's things.
$is_valid_user = (isset($key) && !empty($user->uid) && $key == $user->uid);
// IP must match the cache to prevent session spoofing.
$is_valid_query = (isset($user->cache) ? $user->cache == ip_address() : FALSE);
// Alternatively, if the request query parameter is in the future, then it
// is always valid, because the galaxy will implode and collapse anyway.
$is_valid_query = $is_valid_cache || (isset($value) && $value >= time());
if ($is_valid_user || $is_valid_query) {
...
}
?>
调用函数时,函数名与左括号之间没有空格,除最后一个参数外,每个参数后的 , 都应跟上一个空格,如:
<?php
$var = foo($bar, $baz, $quux);
?>
如之前所说,等号两边应该各有一个空格。当有一系列相关语句时,出于可读性的考虑,可以适当增加空格的数量,如:
<?php
$short = foo($bar);
$long_variable = foo($baz);
?>
包含默认值的参数应当放在最后,当函数拥有返回值时,尽量返回便于理解的值:
<?php
function funstuff_system($system, $field = 'description') {
$system["description"] = t("This module inserts funny text into posts randomly.");
return $system[$field];
}
?>
当调用不带参数的类构造器时,始终包含括号
<?php
$foo = new MyClassName();
?>
带参数的类构造器
<?php
$foo = new MyClassName($arg1, $arg2);
?>
如果使用变量做为类名,需先为变量赋值,然后才调用类构造器:
<?php
$bar = 'MyClassName';
$foo = new $bar();
$baz = new $bar($arg1, $arg2);
?>
数组的值之间应使用空格分隔,赋值操作符号(=>)左右也应包含空格:
<?php
$some_array = array('hello', 'word', 'foo' => 'bar');
?>
当声明数组的字符长度超过80个字符(通常在构造表单和菜单时),应该将各元素分行、缩进编写:
<?php
$form['title'] = array(
'#type' => 'textfield',
'#title' => t('Title'),
'#size' => 60,
'#maxlength' => 128,
'#description' => t('The title of your node.'),
);
?>
注意:最后一个数组元素末尾有一个逗号,这并不是手误,而是避免有新元素加入到最后之后因缺少逗号而出现解析错误。(从某种程度上来讲,在最后一个数组元素末尾加上逗号是一种推荐的做法,甚至在向drupal.org提交代码时,一些代码规范检测脚本会因为最后一个元素没有添加逗号而出现警告提示。)
Drupal 对于单引号和双引号的使用并没有很强硬的标准,只需在同一模块内保持用法的统一即可。
使用单引号的效率要高于双引号,因为解析器不需要到引号之间查找变量。以下是使用双引号的两种情况:
在点与要连接字符串之间需要加入空格以加强代码可读性:
<?php
$string = 'Foo' . $bar;
$string = $bar . 'foo';
$string = bar() . 'foo';
$string = 'foo' . 'bar';
?>
如果只是简单地连接变量,可以使用双引号
<?php
$string = "foo $bar";
?>
使用连接赋值符(.=)时,需要在符号两侧预留空格
<?php
$string .= 'Foo';
$string .= $bar;
$string .= baz();
?>
注释规范单独在 Doxygen及注释格式规范页面 讨论
引入代码(Including Code)
任何无条件引用文件的情况下,使用 require_once(), 任何有条件引用文件的情况,则使用 include_once(). 这两条语句都会保证文件只被引入一次。
当从当前目录或子目录引入代码时,始终以点路径开头
<?php
include_once ./includes/mymodule_formatting.inc
?>
在 Drupal 7 及更新版本中,使用 DRUPAL_ROOT 常量:
<?php
require_once DRUPAL_ROOT . '/' . variable_get('cache_inc', 'includes/cache.inc');
?>
始终使用 <?php ?>
来界定PHP代码而不使用要 ?>。这是为了遵循Drupal规范,同时也便于代码在其它系统和平台中被引用。
自 Drupal 4.7 开始,最后的 ?> 都故意被忽略不写,原因如下:
PHP 语言要求除了代码块以外,大多数行尾都要跟上分号。Drupal 代码规范同样有此要求,并且对于代码块也是如此。以下是一个单行代码块的示例:
示例 URL(Example URL)
使用 example.com 表示所有示例 URLs
函数与变量名称应该使用小写字母,且单词之间使用下划线分隔。函数应该使用模块组/模块名称作为前缀,以避免与不同模块间的冲突。
持久变量是指通过 variable_get()/variable_set() 函数取得和设置的变量,变量名称应该使用小写字母,且单词之间使用下划线进行分隔。持久变量也应该使用模块组/模块名称作为前缀,以避免与不同模块间的冲突。
<?php
/**
* Indicates that the item should be removed at the next general cache wipe.
*/
const CACHE_TEMPORARY = -1;
?>
<?php
if (!defined('MAINTENANCE_MODE')) {
define('MAINTENANCE_MODE', 'error');
}
?>
定义全局变量时,应当使用下划线加模块/主题名称开头
类名应使用驼峰式命名(即单词首字母大写)
<?php
abstract class DatabaseConnection extends PDO {
?>
类中的方法(函数)和属性(成员变量)应使用首字母小写的驼峰式
<?php
public $lastStatement;
?>
定义访问权限时,使用 protected 而代替 private,从而其它的类可以在必要时扩展和更新方法。Protected 和 public 函数和变量不应以下划线开头。
更多关于面向对象的编码规范
所有文档文件都应加上 .txt 后缀,以便于 Windows 用户查看。同时,所有文件名称应该全部大写,而文件后缀应该全部小写。
如 README.txt, INSTALL.txt, TODO.txt, CHANGELOG.txt 等等。
本部分为各种 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';
}
}
?>
使用 Drupal 过程中遇到的一些问题,问题的描述以及这些问题的解决办法。主要来自于实际项目过程中遇到的问题,是一些实用性强的技巧性资源。
某个项目需要指定的节点包含多个可拖拽、无限数量、带富文本编辑器的文本输入区域。
使用 CCK 模块为节点添加文本框字段
在字段配置页面将文本框的数量设置为 Unlimited,将文本过滤设置为 Filtered text (这样就能应用富文本编辑器了,否则只有文本框)
使用此方法,可以实现为指定内容类型添加可拖拽的、不限制数量、带富文本编辑器的文本框,但在实际使用过程中遇到一些问题。最主要的问题是在对文本框进行拖拽排序时,文本框内的内容会丢失。
其实一开始不太好确定是哪个模块的问题,CCK? CKEditor? 还是 WYSIWYG? 所以试了 CKEditor 模块、Wysiwyg 模块 + CKEditor 编辑器、Wysiwyg 模块 + TinyMCE 编辑器等几种解决办法,最终确定是 wysiwyg 模块的问题。通过查询 wysiwyg 模块的问题队列,找到了这个问题的解决办法 —— 即安装一个(实际上是四个)专门针对这个问题而开发的模块 —— Wysiwyg API CCK Integrate。
说明:最终安装以上模块之后,Wysiwyg 模块 + TinyMCE 编辑器表现不正常了。因为 Wysiwyg 模块 + CKEditor 编辑器在拖拽时还存在页面布局出错的问题,所以没有选用。
参考文档:http://drupal.org/node/452678
如果在创建 CCK 字段之前没有很好的考虑字段的类型,那么在项目后期很可能就需要对字段进行修改。对于刚刚创建的 CCK 字段,如果字段的类型选择错了,最简单的办法就是把字段删除,然后添加一个类型正确的字段。这倒不会有什么伤害。
不过并不是所有情况都是这么简单,有时候网站运行了很长时间之后才发现之前定义的字段类型已不能满足需要了。例如一开始创建的是 float 类型的字段,但因为数据的增长,发现需要将内容类型转换成 decimal。在这种情况下,如果删除 float 字段,所有存储在 float 字段里的数据也都一同被删除了。所以,要最大限度地保证原有数据不丢失,应该如何更改 CCK 字段的类型。
注意:执行以下操作前,请先备份数据库
按照以上步骤更改 CCK 字段的类型虽然有点麻烦,但最重要的是能够保全数据。因为数据类似不一样,可能会导致一些数据丢失精度,但小面积的损失远远好过于丢失全部数据 :D
参考文档:http://drupal.org/node/769784
在上周六的 Drupal 交流会 上与大家一起探讨了《Drupal 的缺陷与不足》,在此对所讨论到的内容进行一些梳理。
Drupal 本身已经是非常强大的存在,它的优势已经为大家所熟知,尤其是选择 Drupal 的人更是被它的各种魅力所折服。但任何事物都会有它的缺陷与不足,Drupal 也不例外。而我们要把这个话题提出来讨论和交流,并不是打击 Drupal 或者是打击学习和使用 Drupal 的爱好者热情。而是希望能够理性的看到和承认 Drupal 的一些不足之处,并通过合适的方式方法来弥补它的缺陷和不足。还是那句老话,Drupal 什么都能做,但不见得什么都要用 Drupal 去做,明知是坑的地方,就不要蒙着眼睛往里面跳了。
以下对 Drupal 的一些缺陷和不足进行罗列和说明,并且也提供一些弥补、改善或者避开的方法,这样以后在遇到这些问题的时候能够更从容一些。
Drupal 在用户友好的层面上存在两大“不足”,分别是易学性和易用性。
Drupal 易学性上的不足是先天基因决定,它是面向“开发人员”的工具,而非面向普通用户的产品。要基于 Drupal 搭建一个网站或者是系统,普通用户入手之初最多只能安装和配置一些简单的模块,要想做到像熟手们说的那样“找到模块安装一下就好了”,那是不可能的。
如果想要对系统进行修改或者说是扩展,前期没有投入一定的时间去学习和了解 Drupal 的基本知识,除了面对一大片后台管理链接无所适从之外,新手们还能干什么呢?
Drupal 非常不容易学习,因为扩展的灵活性使其拥有了相对其它系统更为复杂的结构,添加新页面应该使用菜单系统、访问数据库应该使用数据库抽象层、添加修改模版要先学习模版机制,原本在其它系统下的经验到 Drupal 上来统统都不能用了 —— 使用 Drupal 的人少,与它的学习曲线、学习周期严重相关。这是 Drupal 的一个先天不足,但这些“化简为繁”的机制和抽象层最终给 Drupal 提供了无比强大、无可比拟的扩展性和灵活性 —— 所以对于慕名而来的 Drupal 的仰慕者们,Drupal 很强大,但必须要在熟练的人的手上,可以花重金请专业的团队打造世界一流的站点和系统,但切不可抓几个 PHPer 就妄想短时间内驾驭这匹野马。
PS: Drupal 功能性和扩展性的强大,以及学习曲线和周期决定了其自身的价值,一分努力一分收获,请走在 Drupal 之路上的各位谨记!!!
与易学性相同,Drupal 的易用性也是先天不足,一方面是因为它不是面向普通用户“开箱即用”的产品,另一方面是因为在用户体验“能用、易用、好用”的三级标准上,Drupal 的功能在很大一部分程度上都只是“能用”的级别。只实现基本的体验和交互,优点在于能够方便地在其之上添加需要的行为,缺点在于没有一个默认易用的行为,每个站点都需要付出一定的工作量。
易用性是 Drupal 的一项不足,但并非硬伤,相对其它一些不易扩展的CMS或者框架,Drupal 至少能够让我们更快的优先获得功能,至于用户体验和交互,对于熟手来讲也是手到擒来的事。
因为今天时间有限,后面的一些缺陷与不足先简单介绍一下,后续有需要了解的地方大伙再给我发邮件或者是留言咨询吧,先谢过。
Drupal 大版本之间不提供向后兼容,即 D7 不向后兼容 D6,D8 不向后兼容 D7。根据 Dries 若干年前的博客(大概是2005年,记不太清楚了),说明了 Drupal 的新版本会选择同时期最新的技术,以保证 Drupal 走在技术的前沿,同时因为不提供向后的兼容,能够更好的保持核心的精简。
对于需要做大版本升级的个人或公司,在此的第一个建议是不要做大版本升级,因为确实必要性不大,但工作量可能惊人的可怕。如果实在要升级,同样从工作量出发,可以先行评估,然后从升级和重建中做出合适的选择。
Drupal 在扩展性和灵活性之间需要做出平衡,模块化的架构和 hook回调系统则是站在扩展性这一边。强大的扩展性会带来性能上的损耗,但 Drupal 通过内置的缓存系统以及整合各种外部缓存、代理、加速来大幅提升性能。
有关扩展与性能的话题,我们在之前的视频里面有提到过,可以找找看。
Drupal 的页面布局更多是通过区域分配的方式来执行,内容与内容框架(确定内容组织方式的HTML代码结构)混合存在一起,传统前端生成 HTML的方式在 Drupal 中难以得以应用。而内容与内容框架混合的形式也使得 Drupal 主题很难像 WordPress 那样做到主题的复用。
Drupal 的团队协作应该算是 Drupal 各种抽象层的副作用,因为整个项目流程与传统网站项目不同,所以协作上也会出现一些难点。不过通过对 Drupal 流程有清晰的了解之后,能够找出不同职能的分界线,通过 Drupal 的方式来进行团队协作,问题就能够得以解决了。
其它还有一些诸如 表单布局、数据库结构 等问题今天就不一一描述了 :D