Drupal 中文教程

  Drupal 是全球最流行的CMS,被广泛应用于网站建设和系统开发。目前国内也有越来越多的爱好者看上了 Drupal,然而因为 Drupal 学习曲线陡峭,且没有很好的Drupal 中文教程,使得很多 Drupal 爱好者苦恼不已。

  本站本着学习交流的目的,编写此 Drupal 中文教程,抛砖引玉,以吸取更多更好的 Drupal 资源,供大家参考、交流、学习。

  内容不断更新中……

Drupal 8 中文教程

本教程面向所有 Drupal 8 用户,由原创文章与论坛的交流帖合并整理而成,希望对 Drupal 8 使用者有所助益。不定期更新,欢迎约稿、欢迎催更……

 

Drupal 8 网站建设

Drupal 解决方案

Drupal 8 模块开发

Drupal 8 主题制作与开发

延伸阅读

Drupal 中的基本概念和相关术语

  本节将介绍 Drupal 中的一些常用词语/术语,了解这些概念对你探索 Drupal 将会有莫大的帮助。

模块(Module)

  模块是用于扩展 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 的权限管理功能十分精细和灵活,能够为特定的角色分配不同的权限组合。

节点(Node)

  节点是 Drupal 中的一个通用术语,表示网站中的各种内容(content)。通俗来讲,节点就是网站中的各种文章页面,以下这些在 Drupal 中都称为“节点”:

  • 手册中的页面
  • 论坛中的主题
  • 博客文章
  • 新闻文章

  每个节点都有与之对应的内容类型(Content Type)、节点ID(nid)、标题、正文、作者、发布日期等字段。也可以通过启用核心的 Taxonomy 模块来为节点增加分类/标签字段、使用第三方的 Location 模块为节点增加地点字段,以及使用功能十分强大的 CCK 模块为内容增加各种其它字段。

评论(Comment)

  评论是 Drupal 站点中的另一种内容,需要启用核心的 comment 模块才可以使用。评论是用户提交到某个节点下的一小段内容,例如,对博客的回复/留言都是评论,论坛主题的回帖也是评论。

术语表(Taxonomy)

  Drupal 通过核心的 Taxonomy 模块为内容提供了一个分类系统。它允许管理用户定义词汇表(Vocabularies),并向词汇表中添加术语(Terms)。每个词汇表可以关联到一个或多个内容类型,如此一来,就可以通过不同的词汇实现对网站内容的分类。

数据库(Database)

  Drupal 的信息存储在数据库中,不同类型的信息有各自的数据库表,例如节点的基本信息都存储在 node 表中,此外评论、用户、角色、权限、术语表及其它信息都有各自对应的数据库表。

路径(Path)

  当你通过 URL 访问 Drupal 站点时,URL中位于站点根目录后的部分被称为路径。当你在访问一个 Drupal 路径时,Drupal 将判断将哪种信息返回给浏览器。Drupal 允许启用的模块定义各自的路径,并对这些路径的请求进行响应。当有人访问这些路径的时候,Drupal 就会通过指定的模块将页面内容返回显示给用户。

  例如,当你访问 http://lugir.com/node/447 这个URL,路径就是 node/447。对这个路径进行响应的模块是核心的 node 模块,当你访问这个路径时,node 模块将处理这个请求,并将内容返回给你。

  当 Drupal 站点没有启用“简洁链接”,路径是URL中位于 '?q=' 之后的部分。当站点启用了简洁链接后,路径则是URL中位于站点根目录后的部分。

主题(Theme)

  Drupal 通过主题(Theme)来控制网站的显示,其它包括网站的外观、色彩、布局和效果。一个 Drupal 主题通常包含一个或多个PHP文件,它们用于控制页面不同部分的 HTML 输出。主题中通常也会包含 CSS、JS 和 图片,它们用于定义网页的布局、字体、颜色和其它风格。

区域(Region)和区块(Block)

  Drupal 的页面可以分为不同的区域(Regions),也可以说,Drupal 的页面由不同的区域组成。Drupal 主题中包含的常见区域有页头(header)、页脚(footer)、侧边栏(sidebar)、主内容(content),不同的主题定义的区域并不相同,例如 zen 主题中还有左边栏(first sidebar)、右边栏(second sidebar)、内容上方区域(content top)和 内容正文区域(content bottom)。

  区块(Blocks)是一些用于放置到区域(region)中的内容块,因此被称为区块。

菜单(Menu)

  Drupal 默认包含三个菜单——主菜单、次菜单和导航。在大多数主题中,只要向主菜单和次菜单中添加了菜单项,它们便会自动出现在网站的页头或页脚部分,如果没有显示,则可能需要对主题进行一些配置。导航菜单包含了管理菜单中的所有菜单项,方便用户通过导航进行一些操作。用户也可以创建自己的菜单。

Drupal 中文安装教程

  Drupal 中文安装教程以图文结合的方式,一步步讲解如何安装Drupal,只需要按照教程,就可以简单的安装Drupal。

  目前 Drupal 有 5,6,7,8 四大版本(分别简称 D5,D6,D7,D8),以下是这几大版本的状态:

  • D5 已经过时,不推荐使用;
  • D6 是目前用得最多、最稳定、支持模块最多的 Drupal 版本,推荐使用;
  • D7 刚刚完成开发,稳定版释出不久,可用的第三方模块不多,建议暂不使用,但从D6转移到D7是日后的趋势;
  • D8 尚处于开发阶段,不推荐使用

如何安装 Drupal 6?Drupal 6 中文安装教程

Drupal 6 中文安装教程

准备工作

  1. 下载:到 Drupal 项目页面下载 drupal 程序包,项目地址: http://drupal.org/project/drupal
  2. 解压:将下载下来 drupal 程序包进行解压缩,得到名为 drupal-版本号 的目录,为目录改名,如改成 drupal6
  3. 下载语言包文件:到 http://localize.drupal.org/translate/languages/zh-hans 页面下载对应版本的语言包(.po文件)
  4. 安装语言包文件:将 .po 文件放置到 drupal6/profiles/default/translations 目录下(如没有 translations 目录请自行创建)
  5. 上传:将 drupal6 目录下的内容放置/上传到网站根目录
  6. 创建配置文件:进入 sites/default 目录,将 default.settings.php 复制一份,命名为 settings.php
  7. 创建用户文件目录:在 sites/default 目录下新建一个目录,名为 files
  8. 设置权限:如果是Linux平台,请将 files 目录的权限设置为 777,settings.php 设置为web服务器用户可写,如果不清楚,也可先设置为777

安装 Drupal 6

  1. 安装页面:执行完准备工作之后,便可通过浏览器访问drupal网站地址即可看到安装界面,如果执行了准备工作中的第3,4步,则可以对语言进行选择,选择安装中文语言包,如 drupal-6.22.zh-hans,点击按钮进行下一步;
  2. 如果没有完成准备工作中的第4,5,6步,则会出现错误提示,执行完准备工作中的第4,5,6步,错误消息就会消失
  3. 数据库配置:填写数据库的配置配置信息,包括数据库名、数据库用户名 和 数据库用户密码,填好之后点击下一步,开始安装Drupal
  4. 安装Drupal:这一步中系统执行Drupal的安装工作,然后进入Drupal站点配置页面
  5. 修正配置文件权限:如果是Linux平台,执行完此步操作之后,请将 sites/default/settings.php 文件权限改为只读(444)
  6. 站点设置:在站点设置页面,填写网站名称、网站邮箱、超级管理员帐号、超级管理员邮箱、超级管理员密码、默认时区和简洁链接,配置完成之后,点击"Save and Continue"即完成了 Drupal 的安装。
  7. 完成Drupal的安装,进入完成信息提示页面,点击最后面的 your new site 链接即可访问你的Drupal站点 :D

 

怎么导入Drupal中文语言包?怎么将Drupal界面翻译成中文

  如果安装 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

 

 

Drupal 7 中文安装教程

准备工作

  1. 下载 Drupal 7:到 Drupal 项目页面下载 drupal 程序包,项目地址: http://drupal.org/project/drupal
  2. 解压 Drupal 7:将下载下来 drupal 程序包进行解压缩,得到名为 drupal-版本号 的目录,为目录改名,如改成 drupal7
  3. 下载语言包文件:到 http://localize.drupal.org/translate/languages/zh-hans 页面下载对应版本的语言包(.po文件)
  4. 安装语言包文件:将 .po 文件放置到 drupal7/profiles/standard/translations 目录下
  5. 上传:将 drupal7 目录下的所有内容放置/上传到网站根目录
  6. 创建配置文件:进入 sites/default 目录,将 default.settings.php 复制一份,命名为 settings.php
  7. 创建用户文件目录:在 sites/default 目录下新建一个目录,名为 files
  8. 设置权限:如果是Linux平台,请将 files 目录的权限设置为 777,settings.php 设置为web服务器用户可写,如果不清楚,也可先设置为777

Drupal 7 中文安装教程

  1. 安装页面:执行完准备工作之后,便可通过浏览器访问drupal网站地址即可看到安装界面,默认选中“Standard”,点击 Save and continue 执行下一步
  2. 选择语言:如果执行了准备工作中的第3,4步,则此页面会出现语言选择项,选中 Chinese,Simplified(简体中文),点击 Save and continue 执行下一步
  3. Drupal 7 需要 php dom 扩展,如果没有安装 dom 扩展则会出现错误,为PHP安装dom扩展后,重启web服务器即可;如果没有完成准备工作中的第4,5,6步,也会出现错误提示,执行完准备工作中的第4,5,6步,错误消息就会消失
  4. 数据库配置:填写数据库的配置配置信息,包括数据库名、数据库用户名 和 数据库用户密码,填好之后点击下一步,开始安装Drupal
  5. 安装Drupal:这一步中系统执行Drupal的安装工作,然后进入Drupal站点配置页面
  6. 导入翻译:这一步也由系统自动执行
  7. 修正配置文件权限:如果是Linux平台,执行完此步操作之后,请将 sites/default/settings.php 文件权限改为只读(444)
  8. 站点设置:在站点设置页面,填写网站名称、网站邮箱、超级管理员帐号、超级管理员邮箱、超级管理员密码、默认时区和简洁链接,配置完成之后,点击"Save and Continue"即完成了 Drupal 的安装。
  9. 完成Drupal的安装,进入完成信息提示页面,点击"访问你的新网站"链接即可访问你的Drupal站点 :D

使用 Drupal 安装配置文件(Installation Profiles)

  安装配置文件(Installation Profiles)为 Drupal 网站实现一站式安装。通过使用安装配置文件,可以轻松地安装具备某些特性和功能的网站(如企业网站、电影网站、SNS社区),而无需手动一个个地启用和配置模块。

  安装配置文件中可能包含 Drupal 核心文件、第三方模块、第三方主题,以及一些预定义的配置。

  要使用 Drupal 安装配置文件(Installation Profiles),可以先到Drupal 安装配置文件页面进行下载。下载下来的安装配置文件分为两种,一种是与Drupal 核心一起打包的安装配置文件,一种是单独的Profile(配置文件)包。如果下载下来的安装配置文件名为 project-版本号-core.tar.gz,则是包含了 Drupal 核心的安装配置文件。

  使用整合了 Drupal 核心的安装配置文件,直接解压缩,按照普通的 Drupal 安装教程 执行安装即可,只是注意在第一个安装界面选择需要使用的安装配置文件

  如果下载的是单独的Profile包,则按以下步骤进行安装

  1. 可以到 Drupal 安装配置文件 页面下载需要的安装配置文件,下载得到 project-版本号.tar.gz, 如 foo-6.x-2.x.tar.gz
  2. 解压 .tar.gz 或 .zip 文件,得到以安装配置文件项目命令的目录,如 foo
  3. 将解压得到的 profile(安装配置文件)目录(如 foo)移动到 Drupal 安装目录下的 profiles 目录下,得到 profiles/foo
  4. 查看配置文件目录下的安装文档,通常是 README 或 INSTALL 文档
  5. 按照安装文档中的要求,下载需要的第三方模块和主题,通常下载到 sites/all/modules 和 sites/all/themes 下
  6. 访问 install.php 文件,在安装界面选择要使用的配置文件,开始安装 Drupal 

 

 

Drupal 如何安装主题

  1. 下载主题。从 http://drupal.org/project/themes 可以查找和下载主题,注意所下载的主题版本与Drupal版本相兼容。带 dev 标识的主题说明它还处于开发阶段,功能和稳定性还不够成熟,请谨慎使用。推荐下载标记为 recommended(推荐)版本的主题;
  2. 解压模块压缩包。从 drupal.org 下载来的主题是压缩包形式,以 .tar.gz 或 .zip 结尾。使用 WinRAR, 7-Zip 或者任何适合的解压缩工具或命令进行解压缩。解压缩之后可得到一个以主题名称命令的目录(文件夹);
  3. 上传主题目录(文件夹)。使用 FTP 或者其它工具将主题目录上传到你的 Drupal 中。请注意,安装目录下有一个 themes 目录,但此目录用于放置 Drupal 自带的核心主题,请不要将第三方主题放置于其中。所有第三方模块建议放置于 sites/all/themes 下,如没有此 themes 目录,请自行创建;
  4. 阅读说明文件。如果模块中包含了说明文件,通常如 INSTALL.txt 或 README.txt,了解安装主题的一些特殊配置需求。有时这些文件没有 .txt 后缀,双击无法直接打开,可使用任意文字编辑器来打开;
  5. 启用主题
    Drupal 6: 访问 管理 > 站点构建 > 主题(admin/build/themes),勾选要启用的主题中的勾选框;
    Drupal 6 启用主题
    PS:如果想要把主题设置为对所有用户启用的默认主题,请选中主题中的默认单选框;
    Drupal 7: 访问 外观(admin/appearance),点击主题下方的“启用”或“启用并设置”
    Drupal 7 启用主题
  6. 点击“保存”按钮保存主题配置

  如果使用模块时遇到问题,可以到模块项目页面(http://drupal.org/project/主题名称)搜索issues,或者到论坛或QQ群去寻求他人帮助。

  说明:建议将使用的主题保持为最新的稳定版本,以保证大多数已经的问题都已被修复。可以通过在 drupal.org 上创建帐户,跟踪你所使用的模块,以获得主题的最新动态。

Drupal 7 在线添加/安装主题新特性介绍

  D7 安装主题较D6有一些改进,除了通过下载主题,手动放置/上传到主题目录下进行安装之外,D7还提供了2种在线安装新主题的新功能,一种是通过URL进行在线安装,一种是通过Drupal上传主题包进行安装。

  需要注意的是,通过 URL 安装主题需要事先为 Drupal 配置好 FTP 信息,因为我没有配置 FTP 环境,这里只是简单介绍一下在线安装主题的流程。

  访问 外观 > 安装新主题(admin/appearance/install)页面,就可以看到 D7 在线安装主题的界面了

Drupal 7 在线安装主题

  将主题包的 URL 粘贴到“从URL安装”的地址框中,或者选择本地文件上传主题包,点击“安装”来执行主题的安装操作。

 

使用 zen 主题制作 Drupal 主题的推荐步骤

  zen 主题是 Drupal 主题开发中用得最多的基主题(Base Theme)之一,通过使用 zen,创建 zen 的子主题做为网站的主题,可以节省大量主题开发工作,让主题开发人员将主要注意力集中的主题的结构和布局上,而较少关注一些函数的实现。

  本文介绍如何为 zen 主题创建子主题,此教程主要参考 zen 主题的 README 说明文档:

  1. 下载 zen 主题:http://drupal.org/project/zen
  2. 解压:将 zen 主题解压到 sites/all/themes 目录下,得到 sites/all/themes/zen
  3. 复制:将 zen 目录下的 STARTERKIT 复制出来,得到 sites/all/themes/STARTERKIT,将 STARTERKIT 重命名为你的主题名称,例如 lugir,则得到 sites/all/themes/mytheme 
    注意:目录名称只能是小写字母、数字和小划线。
    将 STARTERKIT 从 zen 目录中复制出来,是为了方便升级 zen 主题
  4. 重命名info文件:进入你的主题目录(mytheme),将 STARTERKIT.info.txt 文档去掉 .txt 后缀,并重命名为主题名称,如 mytheme.info
    例如:将 mytheme/STARTERKIT.info.txt 改名为 mytheme/mytheme.info
  5. 编辑info文件:编辑 mytheme.info 文档,修改 name 和 description 的内容,如 name = "mytheme", description = "A Zen sub-theme"
  6. 替换函数名称:编辑子主题中的 template.php 和 theme-settings.php 文档,将所有 STARTERKIT 替换成你的主题名称,如全部替换成 mytheme
  7. 启用主题:登录到 Drupal 站点,访问 管理 > 站点构建 > 主题(admin/build/theme),找到并启用你的新主题即可,如果有需要也可以设为默认。

其它操作

  • 修改模块文件:zen 主题的 templates 目录下放置了一些 .tpl.php 模块文件,如果要对这些模块进行修改,应先将其复制到子主题下的 templates 目录下,然后再进行修改

 

Drupal 如何安装模块(Drupal 6)

简介

  安装第三方Drupal模块十分简单,只需从 http://drupal.org/project/modules 下载第三方模块的压缩包,然后将压缩包解压放到 sites/all/modules 目录下,阅读模块说明文件(通常是模块目录下的 README 文档),如果说明文档里面没有要求做其它操作,直接在模块管理页面(管理 > 站点构建 > 模块)选择并启用模块即可。

详细说明

  1. 下载模块。可以到 http://drupal.org/project/modules 查找模块,下载的 Drupal 模块必需与所使用的 Drupal 版本相兼容。dev 版本的模块说明当前正处于开发阶段,模块可能不够稳定,应该谨慎选用。推荐下载 recommended(推荐)状态的模块;
  2. 解压模块压缩包。从 drupal.org 下载来的模块是压缩包形式,以 .tar.gz 或 .zip 结尾。使用 WinRAR, 7-Zip 或者任何适合的解压缩工具或命令进行解压缩。解压缩之后可得到一个以模块名称命令的目录(文件夹);
  3. 上传模块目录(文件夹)。使用 FTP 或者其它工具将模块目录上传到你的 Drupal 中。请注意,安装目录下有一个 modules 目录,但此目录用于放置 Drupal 核心模块,请不要将第三方模块放置于其中。所有第三方模块建议放置于 sites/all/modules 下,如没有此 modules 目录,请自行创建;
  4. 阅读说明文件。如果模块中包含了说明文件,通常如 INSTALL.txt 或 README.txt,了解安装模块的一些特殊配置需求。有时这些文件没有 .txt 后缀,双击无法直接打开,可使用任意文字编辑器来打开;
  5. 启用模块。打开 管理>站点构建>模块,找到新上传的模块,勾选前面的启用模块选框,然后点击“保存”即可。注意:如果是更新一个已经安装的模块,模块已经启用,但需要以超级管理员身份访问 http://你的域名.com/update.php 页面,根据提示对模块进行数据库更新。
  6. 配置权限。一些模块需要对用户设置正确的权限才可便于使用。通常在 管理>用户管理>权限 页面进行用户权限管理,在此页面查看模块是否需要配置权限,如果有,请将权限分配给你希望的角色;
  7. 调整配置。大部分模块会有配置页面,这些配置页面一般位于 管理>站点构建 或 管理>站点配置

  如果使用模块时遇到问题,可以到模块项目页面(http://drupal.org/project/模块名)搜索issues,或者到论坛或QQ群去寻求他人帮助。

  说明:建议将使用的模块保持为最新的稳定版本,以保证大多数已经的问题都已被修复。可以通过在 drupal.org 上创建帐户,跟踪你所使用的模块,以获得模块的最新动态。

Drupal 升级指南:从 Drupal 6 升级到 Drupal 7

  本手册参考 Drupal 7 发行包里面的 UPGRADE.txt 文档及 Drupal 在线文档,详解 Drupal 6 到 Drupal 7 的升级过程。

 

Drupal 6 到 Drupal 7 升级规划

  在进行网站升级之前,还有一大堆事情需要先做。在升级前了解已有网站如何建设是非常重要的。在真正升级站点之前在开发环境先进行测试是最好不过的了。

现有模块和主题

找出网站上安装的模块(包括那些已安装,但之后被禁用的模块)

找出网站上安装和使用的主题

将这些模块和主题列成一张清单,这样有利于升级时进行核对,这份清单还为升级过程中禁用和重新启用模块带来方便。

 

禁用和卸载未使用的模块

当对网站中的模块进行完调查之后,能够知道哪些模块实际上并未使用。出于安全性和性能的考虑,我们总是推荐将未使用的模块卸载并移除。

 

第三方模块升级

在升级前调查关于模块的情况:

  1. 这个模块是否有 D7 版本?通过访问模块项目页面,就可以轻松的获知这一信息。
  2. 这个模块是否被整合到 D7 核心?不少实用的模块都被整合到 D7 的核心,详情可参考《整合到 Drupal 7 核心的 Drupal 6 模块
  3. 这个模块是否可以升级到 D7 版本?(有些模块有多具版本,如 6.x-1.x 和 6.x-2.x,但其中只有一个版本能够升级到 Drupal 7)
  4. 这个模块的 D7 版本是否增加了一些新的依赖性?有时新版本的模块需要依赖其它的一些模块(例如 D7 版本的 Views 模块依赖于 ctools 模块,而 D6 版本并无此依赖性),因此确保升级时加上依赖的模块。

 

主题升级

如果网站使用了第三方的主题,就需要研究主题是否能升级到 Drupal 7

  1. 这个主题是否有 D7 版本?
  2. 网站的主题是否基于一些基主题(如 Zen 或 960)?这样的主题应该如何进行升级?

如果网站的主题是自定义开发,或者修改自第三方的主题,则需要考虑到主题升级将会花上一些时间,可参考《Converting 6.x themes to 7.x

 

内核及第三方模块的修改

使用 Drupal 的原则之一就是“绝对不要修改内核”,然而有时确实更改了内核的一些文件和模块。对于这些修改,进行操作的人应该承担起进行标注和升级的责任。对于第三方模块的修改也是如此。

 

创建升级规划文档

基于之前对于网站中模块和主题的调查创建网站升级规划文档,文档应包含《从 Drupal 6 升级到 Drupal 7 步骤详解》中的所有步骤。因为升级过程中有许多事情很可能会被遗漏,创建一份核对清单,便于自己查看升级完成的项目和跟踪进度,而且能够节省很多时间。将升级过程中遇到的问题做一些记录,这对以后再进行升级操作是非常宝贵的资源。

以下内容可以考虑加入到文档中:

  • 不能进行升级的模块的其它选择
  • 哪些模块在升级数据库,需要先完成自身的升级
  • 对升级有特殊要求的模块的相关说明
  • 模块升级的顺序
  • 升级是否成功的测试计划

 

参考文档:Make an Upgrade Plan

从 Drupal 6 升级到 Drupal 7 步骤详解

  对 Drupal 版本进行升级之前,建议先检查第三方代码与自定义代码与新版本的兼容性,在完成这些检查并了解新旧版本的可升级部分之后,便可通过以下步骤开始升级了。

  1. 检查第三方及自制模块、主题与 Drupal 7 的兼容性[1],(如果你是开发人员,还应该了解如何对你的代码进行升级[2][3])
  2. 确保你目前使用的是最新版本的 Drupal 6.x(当前为 Drupal 6.20),如果当前不是使用最新版本的 Drupal 6,请先升级到 Drupal 6.20。可以参考 Drupal 6.20 发行包里面的 UPGRADE.txt 文档,或者是我以前译写的针对 6.x 版本间升级的《Drupal 的升级步骤
  3. 使用 UID 1 用户登录到站点
  4. 打开 Administer > Site configuration > Site mainenance,将“站点维护”更改为“离线”并保存配置
  5. 打开 Administer > Site building > Themes,启用"Garland"并将其设置为默认主题
  6. 打开 Administer > Site building > Modules,禁用所有第三方及自制模块。因为模块之前存在依赖关系,所以可能需要重复多次才能禁用所有的第三方和自制模块。如果你确定其中部分模块以后不会在 Drupal 7 中被使用,那么可以在禁用之后将其“卸载”;
  7. 通过命令行或FTP删除以下文件:
    sites/default/default.settings.php
  8. 除了 sites 文件夹和其它由你添加的文件,删除 Drupal 安装目录内其它的所有文件和文件夹。如果你对 .htaccess 或 robots.txt 进行的更改,则应该在稍后重新更改新版本的 .htaccess 和 robots.txt 文档,以保证满足你的需求;
  9. 如果在第6步中卸载了某些模块,你应该将此模块文件从 sites/all/modules 或 sites/*/modules 中移除。但不要删除其它模块,即使它们与 Drupal 7 还不兼容,我们将稍后再处理
  10. 从 http://drupal.org 下载最新版的 Drupal 7.x 发行包,将它解包到你的网站根目录
  11. 重新修改在 Drupal 6 中修改过的核心文件,如 .htaccess 和 robots.txt
  12. 将 settings.php 的权限改为可写,从而保证它能够被升级到 Drupal 7 格式。settings.php 文件通常位于 sites/default/settings.php
  13. 通过浏览器访问 http://www.example.com/update.php 执行更新脚本 update.php(注意将其中的 example.com 改为你的站点域名)。如果无法访问 update.php,请执行以下操作:
    - 使用文本编辑器打开 settings.php
    - 找到以下内容:
      $update_free_access = FALSE; (将 FALSE 改为 TRUE)
    注意:千万记得更新完成之后将这个选择改回 FALSE;
  14. 执行完以上更新脚本便完成了 Drupal 核心的更新,备份一下更新后的数据库;
  15. 参考《升级第三方模块及主题》[4]重置和更新非核心的 Drupal 模块及主题;
  16. 访问 Administration > Reports > Status,确保所有内容都工作正常;
  17. 确保 settings.php 文档中的 $update_free_access = FALSE;
  18. 访问 Administration > Configuration > Development > Maintenance mode,取消“将站点设为维护模式(Put site into maintenance mode)”,并保存配置;

  执行完以上步骤,便完成了 Drupal 6 到 Drupal 7 的升级操作,有关 Drupal 7 的管理功能介绍,可参考 http://drupal.org/getting-started/7/admin

  到目前为止,以上步骤只完成了 Drupal 核心文件从 6.x 到 7.x 的升级,对于个别模块的升级,请单独参考模块对应的 7.x 版本中的 UPGRADE.txt 文件,并根据模块作者的说明进行升级。

参考资料:

  • [1] 已经拥有 Drupal 7 版本的模块列表 - http://drupal.org/node/895314
  • [2] 开发人员-升级模块 - http://drupal.org/update/modules
  • [3] 开发人员-升级主题 - http://drupal.org/update/theme
  • [4] 升级第三方模块及主题 - http://drupal.org/node/948216

Drupal 6 升级到 Drupal 7 注意事项及技巧

  本文档记录 Drupal 6 升级到 Drupal 7 的一些注意事项和处理技巧,从而避免在升级过程中遇到一些常见问题。

注意事项:

  • 禁用所有主题,并将 Garland 设为默认主题
  • 禁用所有第三方模块和自定义模块

如果没有执行以上操作,常常会出现找到不指定函数而导致网站无法打开的情况,因此在执行升级前,请确保禁用了所有的主题和模块。

如果升级之后网站不能打开,查看 Web 服务器日志,一般能够定位到出问题的原因。

技巧:在升级之后发现有模块和主题没有禁用,可以通过修改 Drupal 数据库中 system 表中 status 列的值来设置主题或模块的状态(并不推荐这个办法,但这样做确实能解决一些问题。大家最好还是在进行升级前确认禁用了所有第三方和自定义的模块和主题)

 

如果网站数据较多,升级过程会变得十分漫长,可能会长达几个小时,因此在进行数据库更新之前,可以:

  • 清空数据库中所有 cache 开头的数据库表
  • 清空数据库中所有 search 开头的数据库表

说明:cache 开头的数据库表都是缓存数据,search 开头的数据库表保存是的搜索相关的索引数据,尤其是 search_index 表中的数据量巨大(几百万、千万、上亿)。这些表中的数据都是可以自动再生成的内容,因此清空这些表对于减少数据库体积十分有效果。

注意:有关清空所有 search 开头数据库表的作法并不知道有没有什么副作用,有顾虑的朋友请进行一些研究。(cache 开头的表可以安全清空)。

 

技巧:对于中大型网站,建议使用 drush 来执行数据库更新操作(drush updatedb),因为对于数据库的升级可能长达几个小时,通过访问 update.php 来执行升级操作可能出现PHP脚本执行超时和AJAX的错误。

 

如果您在升级过程中遇到其它一些常见问题,欢迎分享您的经验或者提问 :)

备份 Drupal 数据库与文件

  执行 Drupal 升级进行之前,请务必先备份好所有的文件和数据库。因为,如果升级过程中出现任何问题,除了使用备份,没有其它更好的办法让你的站点恢复原状。并且,如果在升级过过程中遇到任何错误,都不应该再执行任何更进一步的操作。

备份数据库:

  备份 Drupal 数据库,可根据用户的实际情况使用命令行或者 PhpMyAdmin 进行备份。因为 PHP 脚本有最大执行时间限制,因此在使用PhpMyAdmin备份较大的数据库文件时可能会因超时而导致备份失败。MySQLDumper 和 Bigdump 是两个可选的数据库备份工具。

备份文件

  升级 Drupal 前需要备份的文件包核心文件与非核心文件,核心文件即为 Drupal 发行包中包含的文件,非核心文件通常是指第三方模块、第三方主题或其它用户生成的文件,默认情况下,这些非核心文件都位于Drupal安装目录的 sites 目录下。

  所以升级之前,应该备份 Drupal 数据库与 Drupal 安装目录下的所有文件,以确保升级出错后可以使用这些备份来还原站点。

 

参考文档:

  • Make Backups - http://drupal.org/upgrade/backing-up-the-db
  • Backing up a site - http://drupal.org/node/22281

整合到 Drupal 7 核心的 Drupal 6 模块

  本文档提供了一份模块清单,这些模块有 Drupal 6 版本,在升级到 Drupal 7 之后,这些模块的功能已经部分或已完全被整合到 D7 的核心了。

  以个列表还在不断更新,因此并非最终版本,最新版本的原文可以查看《Drupal 6 contributed modules that are in Drupal 7 core

可卸载的模块

以下这些模块的功能已经包含在 Drupal 7 的核心中,它们的升级不涉及数据迁移。当网站从 D6 升级到 D7 时,可以将这些模块从模块目录下移除。升级完成后,可能需要对这些模块进行重新配置以便恢复 D6 时的功能。(对于包含复杂配置的模块,我们也希望模块维护人员提供自动化升级能力)

 

其它可卸载的模块(视所使用的功能而已)

以下模块的部分功能被集成到 D7 核心,但其自身仍然具备一些额外的功能,如果你没有用到这些额外的功能,则可以卸载这些模块。

  • Token
    - 此模块依然是 D7 版本,用于提供一些token的用户界面(UI)功能,如 field 和 profile tokens.
  • Better Formats
    - 核心以外的 D7 版本的此模块具备以下功能:基于用户角色显示: 输入格式提示, 输入格式提示链接及 format selection for [entity]

 

包含数据迁移的模块

以下这些模块在站点升级时需要被保留,首先需要完成《从 Drupal 6 升级到 Drupal 7 步骤详解》中的所有步骤,然后安装一些处理数据迁移的辅助模块。

  • Content Construction Kit (CCK)
    - 除了整合到 D7 核心之外,CCK 中的一些功能被做为独立的模块发布出来,其中包含了数据迁移的功能,如 Node 和 User references 的功能包含到 References 模块中. Content permissions, fieldgroups 及 content copy 也被做为独立模块发布。
  • Content Taxonomy
    - 需要迁移数据,模块的项目页面提到将提供数据迁移功能。
  • Date Timezone
    - 这是 Date 的子模块之一.
  • Field Taxonomy
    - 需要迁移数据,目前项目页面没有提到自动化数据迁移功能的消息
  • Filefield/Imagefield
    - 这两个模块的数据迁移的初步方案是借助 CCK 的 Content Migrate 模块
  • Image
    - 相关的图片节点(Image Nodes)需要使用 Field Converter 模块迁移到 FieldAPI. 部分功能(如:导入)依然存在于独立的模块中。
  • Taxonomy Delegate
    - 需要迁移数据,目前项目页面没有提到自动化数据迁移功能的消息
  • Taxonomy Intro
    - 需要迁移数据,目前项目页面没有提到自动化数据迁移功能的消息
  • Term fields
    - 需要迁移数据,目前项目页面没有提到自动化数据迁移功能的消息

 

参考文档:Drupal 6 contributed modules that are in Drupal 7 core

Drupal 使用教程

  本文档整理了一些与使用 Drupal 相关的教程,如 Drupal 的配置、如何使用 Drupal 实现某些功能、如何使用和配置 Drupal 模块、Drupal 使用小技巧等。

使用术语表为内容添加分类(D6)

  使用 Drupal 核心模块的 Taxonomy 模块,将创建的词汇表(Vocabulary)与指定的内容类型想关联,很容易就可以实现对内容进行分类。一旦对内容进行分类之后,就可以执行一些基于分类的操作,比如显示某一分类下的所有内容,基于分类显示内容列表区块等。

创建词汇表

访问 管理 > 内容管理 > 分类 > 添加词汇表(admin/content/taxonomy/add/vocabulary)页面

填写“术语表标识”

填写“术语表标识”【图】

选择将使用此术语表的内容类型。内容类型配置项会列出 Drupal 中所有的内容类型,我这里并没有添加其它内容类型,所以只有默认的新闻(Story)和页面(Page)

选择使用此术语表的内容类型【图】

设置术语表类型。

设置术语表类型

术语表类型配置的前两项会决定术语表在添加节点页面的显示方式。

  • 如果不勾选“标签”和“多重选择”,则会以下拉菜单的形式显示术语表中的词汇,如下图的“内容分类”所示;
  • 如果只勾选“多重选择”,则会以多选框的形式显示词汇,按住 ctrl 键进行多选;
  • 如果勾选“标签”,则会显示普通文本框,用户可通过文本框输入词汇,词汇之间用英文逗号进行分隔;“标签”分类大致如下图的“标签”所示;

设置术语表类型【图】

添加词汇

创建完词汇表之后,便可以在术语表管理页面(admin/content/taxonomy)看到刚才新建的“栏目分类”词汇表

词汇列列表【图】

点击词汇表后面的“添加术语”链接,进入添加术语页面,简单创建几个术语,然后对术语层级进行一下调整,得到如下的词汇结构:

栏目分类【图】

创建内容

  经过前面创建词汇表(将词汇表关联到内容类型Story),然后向词汇表中添加了词汇,之后,便可以在管理 > 内容管理 > 创建内容 > Story(node/add/story)页面,看到并使用新添加的“栏目分类”术语表了

创建内容【图】

 

使用术语表为内容添加分类(D7)

  在 Drupal 7 中,使用术语表为内容添加分类,与《Drupal 6使用术语表为内容添加分类》的步骤基本一样,稍有不同的一点在于,D7 没有在词汇表的配置页面将词汇表与内容类型进行关联,而是需要稍后将术语表做为内容类型的一个字段添加到内容编辑表单。

  本文将介绍如何在 Drupal 7 中,使用术语表为内容添加分类的做法。

创建术语表

访问 管理 > 结构 > 分类 > 添加词汇表(admin/structure/taxonomy/add)页面,填写词汇表的基本信息并点击保存

创建词汇表【图】

添加词汇

创建完词汇表之后,便可以在术语表管理页面(admin/structure/taxonomy)看到刚才新建的“栏目分类”词汇表

术语表列表【图】

点击词汇表后面的“添加术语”链接,进入添加术语页面,简单创建几个术语,然后对术语层级进行一下调整,得到如下的词汇结构:

词汇层级结构【图】

添加内容类型字段

  访问 管理 > 结构 > 内容类型(admin/structure/types)页面,可以看到系统中存在的内容类型的列表

Drupal 7 内容类型列表【图】

点击“基本页面”所在行的“管理字段”链接,进入“基本内容”内容类型的字段管理页面。在添加新字段处填写以下信息,然后点击“保存”:

  • 标签:栏目分类
  • 字段名称:field_category
  • 存储的数据类型:术语来源
  • 编辑此数据的表单元素:选择列表

Drupal 7 字段管理页面【图】

在字段设置页面,选择术语来源,然后点击“保存字段设置”

Drupal 7 术语来源字段设置【图】

选择“术语来源”之后,点击“保存字段设置”之后,会进入到字段详细配置页面,根据自己的需要对字段进行配置,因为这里只是做演示,直接点击页面最下方的“保存设置”即可

在返回的字段管理页面中,就可以看到“栏目分类”字段已经成功显示在内容类型的字段列表中了。拖动标签前面的十字架,将栏目分类移动到Title后面,结果如图示

Drupal 7 内容类型字段列表【图】

创建内容

访问 管理 > 信息面板 > 添加内容 > 基本页面(node/add/page)页面,已经可以在标题(Title)字段下方看到“栏目分类”字段了

Drupal 7 创建内容【图】

 

Drupal 幻灯片制作教程

  各种类型的网站都可以用到幻灯片,不论是用途网站首页的图片展示还是用于制作大气的图片轮换Banner。Drupal 中用得较多的幻灯片模块有 Views Slideshow 和 DDBlock 两种,本文将以 Views Slideshow 为例,详细介绍使用 Drupal 制作幻灯片的步骤:

  用到的模块:

  • Views Slideshow (6.x-2.x)
  • ImageField
  • Link
  • ImageCache

  确认安装并启用以上模块之后,便可以按照以下步骤来创建 Drupal 幻灯片了 :D

  提示:本文最后提供了一个打包好的幻灯片配置包,大家直接下载并启用就可以得到按照本文配置的基本幻灯片了 :D

 

Drupal 幻灯片制作流程:

 

1.创建幻灯片 (Slideshow) 内容类型

添加内容类型,访问管理 > 内容管理 > 内容类型 > 添加内容类型页面 (admin/content/types/add),按以下配置创建内容类型之后点击保存
名称: slideshow
类型: 幻灯片

添加幻灯片内容类型

新添加的 Slideshow 会出现在内容类型管理列表中,点击 Slideshow 对应的“管理字段" (manage fields) 链接,进入 Slideshow 编辑页面

进入管理字段页面

添加幻灯片图片字段:在管理字段页面,按以下配置添加图片 (ImageField) 字段后点击“保存字段设置”按钮

  • 标签:幻灯片图片
  • 字段名称:field_slideshow_image
  • 数据类型:文件
  • 表单元素:图片

添加幻灯片图片字段

配置幻灯片图片字段:在图片字段配置页面,配置以下信息及根据你的需要进行配置后点击“保存”

  • 路径设置-> 文件路径: slideshow (这会将所有上传的幻灯片图片保存到 slideshow 目录下)
  • 全局设置 -> 必须

添加幻灯片链接字段:在管理字段页面,按以下配置添加链接 (Link) 字段后点击“保存”

  • 标签:幻灯片链接
  • 字段名称:field_slideshow_link
  • 数据类型:链接
  • 表单元素:链接

添加幻灯片链接字段

配置幻灯片链接字段:在链接字段配置页面,根据需要配置后点击“保存字段配置”按钮

调整字段顺序:在管理字段页面,将幻灯片图片和幻灯片链接拖动到正文的前面,然后点击“保存”

调整幻灯片字段顺序

 

2. 添加幻灯片图片

访问创建内容 > 幻灯片 (node/add/slideshow) 页面,填写标题、上传图片、填写幻灯片链接标题和URL,正文可以留空,然后保存即可

重复此步骤创建大概5张不同的幻灯片图片

 

3. 创建 ImageCache 规则

访问管理 > 站点构建 > ImageCache > 添加 ImageCache 预设页面 (admin/build/imagecache/add),设置名称后点击保存
ImageCache 预设名称:Slideshow

添加幻灯片预设

在运作中,点击"添加 Scale And Crop "链接,在新窗口设置幻灯片大小后点击"创建动作"

  • 宽度:300
  • 高度:240

  注意:点击创建动作后,可以在页面下方看到缩放成 300 x 240 大小的图片,如果看不到图片预览,请查看模块管理页面,确保 ImageAPI GD2 和 ImageAPI ImageMagick 至少有一个是启用状态。

4. 创建 View

访问管理 > 站点构建 > 视图 > 添加 页面(admin/build/views/add),配置以下信息后点击“前进”

  • 视图名称:slideshow
  • 视图描述:幻灯片
  • 视频标签:幻灯片

添加幻灯片视图

添加区块:在 View 配置页面的最左边,从下拉框中选择“区块”, 点击“添加显示”

添加幻灯片区块

配置幻灯片区块:按照以下顺序和配置对幻灯片区块进行配置

  • 字段
    • 添加字段:内容:幻灯片链接(field_slideshow_link)幻灯片链接(field_slideshow_link)
      • 排除显示:勾选
      • 标签:无
      • 格式:URL, as plain text
    • 添加字段:内容: 幻灯片图片 (field_slideshow_image)幻灯片图片 (field_slideshow_image)
      • 将这个字段作为链接输出:勾选
        • 链接路径:[field_slideshow_link_url]
      • 标签:无
      • 格式:Slideshow image
  • 过滤
    • 添加过滤器:节点: 类型
      • 操作符:其中之一
      • 节点类型:幻灯片
    • 添加过滤器:节点:已发表
      • 已发表:是
  • 基本设置
    • 样式:幻灯片
      选择幻灯片之后,点击样式列后面的齿轮可以对幻灯片进行详细配置。可以用于创建带缩略图的幻灯片、添加幻灯片控件、幻灯片效果等等(可参见文章最后的幻灯片示例)
    • 要显示的条目数:5

幻灯片视图设置

5. 将幻灯片分配到指定区域

访问管理 > 站点构建 > 区块管理页面 (admin/build/block),找到 slideshow: 区块,将其分配到指定的区域后,点击保存。

6. 幻灯片美化

为幻灯片区块添加 CSS,做一些美化,使幻灯片看起来更漂亮。

 

  本文介绍了配合 Views Slideshow 创建幻灯片的基本用法,大家可以根据需要,自行添加一些字段以及更改 Views Slideshow 的配置更幻灯片变得更加丰富。使用 Views Slideshow 可以创建各种类型的幻灯片片,下面提供几个幻灯片示例以供大家参考交流。欢迎留言交流 :D

1. 只带页码的幻灯片

Views Slideshow 示例,只带页码的简单幻灯片

2. 包含页面和标题的幻灯片

Views Slideshow 示例:带页码和标题的幻灯片

3. 纵向带页码的幻灯片

Views Slideshow 示例:纵向带页码的幻灯片

4. 带标题、缩略图和控件的复杂幻灯片

Views Slideshow 示例:带标题、缩略图和控件的幻灯片

    虽然本文介绍了制作幻灯片的步骤,但每次在不同的网站上又重新配置一遍也比较辛苦,为了节省重复的配置工作,我制作了一个特性包,大家直接下载且启用就可以得到一个基于本教程的简单幻灯片了,详情请参考《Fox Slideshow - 基于 Views Slideshow 的幻灯片 Features 包下载

使注册用户在发表评论时可设置昵称

  Drupal 的评论功能,默认可以配置成允许匿名用户填写联系信息,使匿名用户可以使用任意昵称发表评论。而 Drupal 注册用户,在登录之后,默认只能使用用户名进行回复,无法像匿名用户那样使用任意昵称。

  本文通过创建一个简单的 Drupal 模块,为拥有 set comment name 权限的登录用户,能够在发布评论时手动设置昵称。

创建模块文件夹: sites/all/modules/comment_name

创建模块信息文件:在comment_name模块目录下创建模块信息文件, comment_name.info,并将以下内容写入到 comment_name.info 文件中

name = "Comment Name"
description = "Let authenticated user post comments as an anomyouse user with a name."
core = 6.x
package = Other
dependencies[] = comment

创建模块文件:在 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 != && (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 管理员在发布评论时就能够以匿名用户的身份,使用任意名称发表评论了。

如何为 Drupal 站点添加在线电子书阅读功能

  像 Google Book百度文库 那样的文档在线阅读功能非常实用,要想为 Drupal 站点实现这样的文档在线阅读功能,可以通过 SWF Tools 模块来实现。

A. 启用并配置 SWF Tools 和 FlexPaper

  1. 首先,到 SWF Tools 项目页面下载 swftools 模块:http://drupal.org/project/swftools
    注意:请下载 swftools-6.x-3.0-beta5 或以上版本,此前的版本未集成对 FlexPaper 的支持;
  2. 将模块解压到 sites/all/modules 目录下;
  3. 到 Flexpaper 官方网站下载,Flexpaper(Flash版本),地址:http://flexpaper.devaldi.com/download/
  4. 将下载下来的 flexpaper_x.x.x_flash.zip 解压到 sites/all/libraries/flexpaper 目录下;
  5. 访问 管理>站点构建>模块(admin/build/modules) 页面,启用 SWF Tools 和 FlexPaper 模块;
  6. 访问 管理 > 站点设置 > SWF Tools > File Handling(admin/settings/swftools/handling)页面,展开 File Handling 区块,将 Default player for a single swf movie 的值设置为 FlexPaper;
  7. 访问 管理 > 站点设置 > SWF Tools > FlexPaper(admin/settings/swftools/flexpaper)页面,对 FlexPaper 配置进行设置
  8. 访问 管理 > 站点设置 > 输入格式(admin/settings/filters),找到想要使用 SWF Tools 标签的 Filter,如 Filtered HTML,点击配置。在 Filtered HTML 配置页面,找到“过滤”区块,勾选中 SWF Tools Filter,保存;

 

B. 制作可通过 FlexPaper 在线浏览的电子书

  1. 访问 SWF Tools 官方网站的下载页面,下载 SWF Tools: http://swftools.org/download.html
    Linux 用户下载 .tar.gz 包, Windows 下载 .exe 安装程序
  2. 安装 SWF Tools
  3. 使用 SWF Tools 提供的 pdf2swf 功能,将要在线阅读 PDF 文档转换成 .swf 格式

 

C. 上传转换后的 .swf 格式电子书

  1. 创建新的内容,可以通过 CCK Field,附件或FTP上传等方式,将 .swf 文件上传到网站中
  2. 在创建内容页面,将输入格式更改为第A-8步中启用了 SWF Tools Filter 的输入格式,如 Filtered HTML
  3. 按照 swf tools filter 提示的格式在正文中写入以下代码,保存之后即可以看到以 FlexPaper 显示的在线电子书。

[swf file="http://lugir.com/sites/default/files/test.swf"]

以下是使用 SWF Tools 模块和 FlexPaper 实现的在线电子书的效果截图

FlexPaper 预览

PS: 安装好的 FlexPaper 无法显示放大缩小的工具条,我为SWF Tools的这个功能写了一些补丁文件,有需要可以到下面的地址下载和使用:

http://drupal.org/node/1159076

 

 

为 Drupal 添加评论数量最多的前N位用户排行榜

  如果想要为 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->namedrupal_get_path_alias("user/{$user->uid}")) . " (" $user->count ")</li>";
}

$ouput .= "</ul>";
echo 
$output;
?>

  以上代码默认显示10位用户,要更改显示的用户数量,更改 "LIMIT 10" 中的数值即可。

  另外,此代码将匿名用户(uid=0)和管理用户(uid=1)排除在统计之外,如有需要,可更改 WHERE 选择语句的条件。

使用 Boost 模块为网站提供高性能静态页面缓存机制

  本文介绍如何为 Drupal 站点准备和安装 Boost 模块,以及在成功配置 boost 模块后如何检验模块是否正常工作。

安装 Boost 模块

  • 下载模块:访问 boost 模块的项目地址,下载 boost 模块 http://drupal.org/project/boost,本文以 boost-6.x-1.18 为例
  • 解压模块:将下载来的 boost 模块包解压并放置于网站的 sites/all/modules 目录下,得到 sites/all/modules/boost 
  • 启用模块:访问 管理 > 站点构建 > 模块(admin/build/modules)页面,找到并启用 boost 模块
  • 配置模块:访问 管理 > 站点设置 > 性能 > Boost Settings(admin/settings/performance/boost)页面,设置缓存目录(建议使用默认值cache不变),及配置其它 boost 选项
  • 查看状态报告:访问 管理 > 报告 > 状态报告(admin/reports/status)页面,会看到一些错误信息,接下来的操作将会逐个地解决这些错误
  • 创建缓存目录:在 drupal 安装目录下创建 cache 目录,如果运行在 Linux 平台,还需要配置目录访问权限,使 web 服务器用户对 cache 目录有写权限
  • 备份 .htaccess 文件:将 drupal 安装目录下的 .htaccess 文件复制一份,命名为 .htaccess.bak,并用文本编辑器打开 .htaccess 文件
  • 编辑 .htaccess 文件:访问 管理 > 站点设置 > 性能 > Boost htaccess rules generation(admin/settings/performance/boost-rules)页面,复制文本框中的所有内容,将其粘贴到 .htaccess 文件中以下位置,保存 .htaccess 文件。

  # RewriteBase /
      ----------将复制出来的内容粘贴到这个位置----------
  # Rewrite URLs of the form 'x' to the form 'index.php?q=x'.

  • 编辑 robots.txt 文件:编辑 drupal 安装目录下的 robots.txt 文件,在最后面加入以下条目

# Boost
Disallow: /boost_stats.php
Disallow: /CHANGELOG.txt

  • 查看状态报告:刷新 管理 > 报告 > 状态报告(admin/reports/status)页面,所有错误信息都处理完毕
  • 启用 boost 缓存:访问 管理 > 站点设置 > 性能(admin/settings/performance)页面,根据需要配置 Drupal 站点的缓存机制

完成以上所有操作后,Boost 就可以正常运行了

测试并验证 Boost 的工作

  • 登出 Drupal 或者使用另一个浏览器匿名浏览启用了 boost 模块的站点,对一些页面进行浏览
  • 登录并访问 管理 > 站点设置 > 性能(admin/settings/performance)页面,查看有多少页面被 Boost 进行了缓存
  • 访问 管理 > 报告 > 状态报告(admin/reports/status)页面,看是否有任何错误信息
  • 要验证匿名用户查看的某个页面是静态缓存页面还是动态页面,只需查看网页源代码,如果在源代码的最后面有类似以下代码,则是 Boost 提供的缓存页面。

<!-- Page cached by Boost @ 2011-06-30 12:09:30, expires @ 2011-06-30 13:09:30 -->

注意:因为服务器配置的不同,Boost的默认配置可能不会生效,此时可尝试修改Boost配置中的 Server URL or Name 及 Document Root 两项以解决问题

使用 diff 命令创建 patch 文件

  使用 diff 命令可以为文件创建 patch 文件,通过执行以下代码即可

diff -Naur file_new file_old > file.patch

以上命令的意思是,对比 file_new 与 file_old 的不同,将两者的差异导入到 file.patch 文件中。以便于其它人可以使用这个 file.patch 为 file_old 文件打补丁

  关于如何应用 .patch(补丁)文件,可参考《使用 patch 命令为文件打补丁》http://lugir.com/node/419

安装 DDBlock

下载及安装

  1. 下载 JQuery_Update 模块
  2. 下载 DDBlock 模块
  3. 将 jquery_update 和 ddblock 模块解压到 sites/all/modules 目录
  4. 访问 管理 > 站点构建 > 模块(admin/build/modules)页面,启用 JQuery Update 和 Dynamic display block 模块,点击保存

 

可选,如果希望 JQuery Easing 效果,可以到下载 JQuery Easing 插件

  1. 到 http://plugins.jquery.com/project/Easing 页面下载 1.1.1 版本的 easing 插件
  2. 将 easing.1.1.1.js 文件复制到 sites/all/modules/ddblock 下

 

DDBlock 基本用法,使用 DDBlock 创建简单的图片幻灯片

  本文介绍 DDBlock 的基础用法,即使用指定目录下的图片,创建一个简单的图片幻灯片

添加、启用和配置 DDBlock

  1. 访问 管理 > 站点设置 > Dynamic display block(admin/settings/ddblock)页面;
  2. 找到 add dynamic display block 区域,在区块标题中填写要添加的区块标题,如“DDBlock 测试区块”,然后点击添加区块;
  3. 添加区块后可以页面的列表中看到新增的区块,以本教程为例,则是“DDBlock 测试区块”。点击“DDBlock 测试区块”后面的设置区块链接,进入区块设置页面;
  4. 将 Image Folder 设置为 ddblock,这里设置的路径为 Drupal 文件系统,即在 管理 > 站点设置 > 文件系统(admin/settings/file-system)中设置的文件系统路径,默认为 sites/default/files
  5. 根据需要修改其它配置,然后点击页面最下方的“保存区块”
  6. 在 sites/default/files 目录下创建 ddblock 目录;
  7. 向 sites/default/files/ddblock 目录上传入一些图片;
  8. 访问 管理 > 站点构建 > 区块(admin/build/blocks)页面,找到“DDBlock 测试区块”区块,将其分配到某个想要让它显示的区域(Region),点击“保存区块”即可。

 

说明:所创建的 DDBlock 会按照第4, 5步的配置,从指定的目录中取得图片并显示。

使用 Drupal 创建多语言站点

  Drupal 核心提供了 Locale 模块用于为 Drupal 站点提供本地化的功能,使用 Locale 模块创建本地化的站点非常实用,并且能够制作较为简单的多语言站点。不过,我们更推荐使用 i18n 模块,通过 Drupal 创建多语言站点。有关 i18n 模块及其它多语言站点相关的模块的使用,将会再本教程中陆续介绍。

  *说明:本文虽然是在D6时代撰写,但大部分内容对于现今版本的Drupal依然适用。

  本教程将介绍以下内容:

  

  接下来我们就开始使用 Drupal 创建包含中文和英文两种语言的多语言站点 :D

使用 Drupal 创建多语言站点

  1. 安装 Drupal 6
  2. 启用 Locale 模块并导入中文语言包
  3. 访问 管理 > 站点设置 > 语言(admin/settings/language)页面,点击“英文”语言后面的“编辑”链接(admin/settings/language/edit/en),在编辑语言页面,将“路径前缀”设置为 en(默认英语语言的路径前缀为空),点击“保存语言”;
  4. 访问 管理 > 站点设置 > 语言 > 配置(admin/settings/language/configure)页面,将“语言协定”配置为“仅使用路径前缀”,点击“保存设置”
  5. 访问 管理 > 站点构建 > 区块(admin/build/blocks)页面,将名为“语言转换”的区块分配到右边栏,点击“保存区块”
    注意:若没有正确配置第4步的操作,“语言转换”区块将不会显示
  6. 保存区块后,网站的右边栏会显示如下图示的链接,点击“简体中文”和“English”的链接,试试语言的切换
    Drupal 多语言站点,语言切换
    注意:如果在第2步中将默认语言设置为“简体中文”,但未在第3步中为英文语言设置路径前缀,则不能正确执行语言切换

  现在,我们已经创建了可以切换语言界面的 Drupal 站点,以下分别是站点的中文界面截图和英文界面截图

Drupal 多语言站点中文界面截图

Drupal 多语言站点中文界面截图

Drupal 多语言站点英文界面截图

Drupal 多语言站点英文界面截图

  相信大家也发现了,在切换语言时,尽管界面语言都进行了中英文的切换,但是像“网站标题”这样存储在数据库里面的配置项,却没能被翻译过来。Locale 能够做到界面内容的翻译已经很不错,至于网站变量的多语言化,以及术语表、内容、CCK、菜单、区块等元素的多语言化,就交给接下来要介绍的 i18n 模块来做吧。

站点变量(Variables)多语言化

  上一节我们已经使用 Drupal 核心的 Locale 模块为 Drupal 站点启用了多语言的功能,并且对 Drupal 界面进行了翻译。不过还遗留了一点点小问题,就是 Drupal 的站点标题没有翻译过来。

  Drupal 中的一些文本和配置存储在数据库的variables表中。比如“站点名称”和“站点口号”这样的配置文本,Drupal 核心的 Locale 模块不能实现这些配置变量的多语言化。因此创建一个更彻底的多语言站点,还需要用到 Internationalization(i18n)模块,i18n 模块提供了 Drupal 变量多语言化的功能。

  要实现对 Drupal 变量的多语言化操作,需要知道要翻译的变量的名称,这一步可以通过搜索 Drupal 数据库的 variables 表来实现。

  当你确定要对哪些变量进行多语言化操作时,你只需要按照以下格式,将变量添加到 settings.php 文件中即可。以下添加了 Drupal 站点的一些常见变量:

/**
 * Multilingual settings
 *
 * This is a collection of variables that can be set up for each language when i18n is enabled.
 * These are the basic ones for Drupal core, but you can add your own here.
 */

$conf['i18n_variables'] = array(

  // Site name, slogan, mission, etc..
  'site_name',
  'site_slogan',
  'site_mission',
  'site_footer',
  'anonymous',

  // Different front page for each language
  'site_frontpage',

  // Primary and secondary links
  'menu_primary_links_source',
  'menu_secondary_links_source',

  // Contact form information
  'contact_form_information',

  // For theme variables, read more below
  'theme_settings',
  'theme_garland_settings',

);

  当启用了 i18n 模块,并且向 settings.php 配置文件中添加了以上代码之后,可以在 管理 > 站点设置 > 语言 > Multilingual system > Variables(admin/settings/languages/i18n/variables)页面中,看到可以实现多语言化的变量名称及翻译状态。

Drupal 站点信息多语言化

  1. 访问 管理 > 站点设置 > 站点信息(admin/settings/site-information),可以看到一些表单项的后面加上了 This is a multilingual varibles 的提示,说明这些配置已经可以多语言化了
  2. 使用中文填写站点信息表单项,如:
    名称:Drupal 多语言化测试站点
    口号:使用 Drupal 创建多语言站点
    ...
    然后,点击“保存设置”。
  3. 切换到英语界面(如果你阅读了本教程的前面章节,并跟着教程进行的配置,那么,点击右边栏语言切换区块中的 English 链接即可切换到英文界面。如果你是路途看到这一篇文章,而不知如何切换,推荐你先看看前面的章节)
  4. 在英语界面中,使用英文填写 Site Information(站点信息)表单项,如:
    Name:Drupal Multilingual Test Sites
    Slogan:Using Drupal create a multilinugal website
    ...
    然后,点击“Save Configuration”。

  尝试在语言间进行一些切换,可以看到中文界面使用了中文的标题和口号,英文界面则使用英文的标题和口号

Drupal 多语言站点中文界面截图

Drupal 站点变量多语言化-中文

Drupal 多语言站点英文界面截图

Drupal 站点变量多语言化-英文

为内容创建不同语言的翻译版本

  Drupal 核心提供的 Content translation 模块,为创建多语言的 Drupal 站点提供了内容多语言化的支持,本教程将介绍如何为内容创建不同语言的翻译版本。 

为内容创建不同语言的翻译版本

 

启用内容翻译功能

  1. 访问 管理 > 站点构建 > 模块(admin/build/modules)页面,启用 Content translation 模块,点击“保存”;
  2. 确定想要启用多语言翻译功能的内容类型,如新闻(Story),访问 内容管理 > 内容类型 > Story(admin/content/node-type/story)页面;
  3. 展开“流程设定”选项,将“多语言支持”配置为“启用,与翻译一起”,点击“保存内容类型”;

 

创建内容及翻译版本

  1. 访问 内容 > 创建内容 > Story(admin/content/story/add)页面;
  2. 使用中文填写标题和内容,并将语言设置为“Chinese, Simplified(简体中文)”,点击“保存”;
  3. 在节点页面点击“翻译”链接
    这里可以看到一个网站启用的语言列表,以及内容的翻译情况
  4. 点击 English 那一行的“添加翻译”
  5. 在加载的翻译编辑页面,语言选项被限定为“English(英文)”,并使用英文编写翻译版本的标题和内容,然后点击“保存”;

 

  创建翻译之后,可以在节点页面的下方看到一个翻译链接,点击翻译链接即可看到内容的翻译版本。

菜单与主链接/次链接多语言化

  只使用 Drupal 核心所提供的功能,还不能菜单项的多语言化/翻译。不过使用 i18n 模块包中提供的 Menu translation 模块,可能很好的实现菜单、主链接/次链接的多语言化功能。

  i18n 模块包中的 Menu translation 模块,提供了以下特性:

  • 允许创建菜单时为菜单设置语言项(如中文、英文等等),设置了语言的菜单项只会在与当前使用语言一致时才会显示;
  • 可以为未设置语言项的菜单内容进行多语言化。实现可通过 Drupal 的翻译页面对菜单项进行翻译;

 

创建可翻译的多语言化菜单

 

  1. 启用模块:启用 i18n 模块的 Menu translation 模块;
  2. 访问 管理 > 站点构建 > 菜单 > 主链接(Primary links) > 增加菜单项(admin/build/menu-customize/primary-links/add)
  3. 创建可翻译菜单项:根据以下信息填写菜单创建表单后,点击“保存”
    路径:<front>
    菜单链接标题:首页
    语言:所有语言
    说明:将语言设置为所有语言的菜单项,会在所有语言界面下显示,可尝试在中英文界面之前进行切换,都能菜单项“首页”,不过在英文界面下也还是显示中文
  4. 搜索翻译项:访问 管理 > 站点构建 > 翻译 > 搜索(admin/build/translate/search),按照以下信息填写表单后,点击“搜索”
    字符串包括:首页
    将搜索限制在:菜单
  5. 从搜索结果中找到要翻译的菜单项目,点击后面的“编辑”链接
  6. 翻译菜单项:在翻译界面中,填写翻译内容,Home。然后点击保存翻译;
  7. 现在再在中英文之间进行切换,就可以看到,在中文界面下,主链接显示菜单项“首页”,在英文界面下,主链接显示菜单项“Home”

 

创建只在指定语言环境下显示的菜单

 

  1. 访问 管理 > 站点构建 > 菜单 > 主链接(Primary links) > 增加菜单项(admin/build/menu-customize/primary-links/add)
  2. 创建可翻译菜单项:根据以下信息填写菜单创建表单后,点击“保存”
    路径:node
    菜单链接标题:内容
    语言:Chinese Simplified (简体中文)
    说明:在这里为菜单语言项,该菜单只有在与当前语言环境一致时,才会显示出来。
  3. 重复第2步,使用以下信息创建一个英语菜单项路径:node
    菜单链接标题:Node
    语言:English (英语)
  4. 现在再在中英文之间进行切换,就可以看到,在中文界面下,会显示语言设置为 Chinese Simplified (简体中文)的菜单项“内容”,在英文界面下,则会显示语言设置为 English (英文)的菜单项“Node”

 

使用多语言化变量设置不同的主链接/次链接

 

  访问 管理 > 站点构建 > 菜单 > 设置(admin/build/menu/settings)页面,可以看到“主导航菜单来源”及“次级菜单来源”都被标识为“多语言化变量(This is a multilingual variable)”,这说明这两项值,在不同的语言环境下,可以设置不同的值,并被数据库分开保存。(更多关于多语言化变量请参考《站点变量(Variables)多语言化》)

  在中文语言下,为主链接/次链接选择恰当的中文链接,在英文语言下,为主链接/次链接选择恰当的英文链接,从而实现在不同语言下,使用不同语言的菜单项,以此来实现 Drupal 网站中菜单的多语言化。

创建支持多语言化的区块

  为 Drupal 创建多语言化支持的区块,需要 i18n 模块包中的 Block Translation 提供相应的支持。有两种方式可以实现区块的多语言化,一种是对区块(Blocks)中的字段进行翻译,另一种是为每一种语言创建一个对应的区块。本文将介绍这两种区块多语言化的方法。

准备工作:

  1. 下载 i18n 模块包,下载地址:http://drupal.org/project/i18n
  2. 模块管理页面:访问 管理 > 站点构建 > 模块(admin/build/modules)页面
  3. 启用模块:启用 Internationalization 模块、String Translation 模块 和 Block Translation 模块,并点击“保存设置”

 

创建基于字段翻译的多语言化区块

  1. 创建区块:访问 管理 > 站点构建 > 区块 > 添加区块(admin/build/blocks/add)
  2. 设置区块语言:在添加区块页面的 Multilingual settings 中,将语言设置为 Chinese Simplified(简体中文)
  3. 添加中文区块:在添加区块页面,填写以下中文信息,然后点击“保存区块”
    区块描述:多语言化测试区块(描述)
    区块标题:多语言化测试区块
    区块内容:这是一个用于测试区块多语言化的区块 :D
    注意:实际操作时,请根据你的需要为区块填写合适的描述、标题和内容等信息
  4. 分配区块:在区块管理页面(admin/build/blocks),找到刚创建的“多语言化测试区块(描述)”,将其分配到指定的区块,如左边栏,点击“保存区块”
  5. 搜索区块中的字段:访问 管理 > 站点构建 > 翻译 > 搜索(admin/build/translate/search),在页面的搜索框中搜索第3步中填写的信息,如"多语言化测试区块",将得到如下搜索结果
    区块多语言化-搜索字段
    说明:基于字段的翻译好像不能对区块描述进行翻译,不过对区块标题和内容的多语言化翻译都是支持的。如果希望区块描述也能够被多语言化,可以参考第二种区块多语言化的方法
  6. 翻译区块中的字段:点击“编辑”进入字段翻译页面,填写翻译内容后点击“保存翻译”
    区块多语言化-翻译字段
  7. 重复第5,6步,完成区块内容的翻译
  8. 查看效果:在默认中文语言界面下,创建的区块显示如下图:
    区块多语言化-中文
    切换到英文语言界面下,创建的区块显示如下图:
    区块多语言化-英文

 

为不同的语言创建对应的多语言区块

  1. 创建区块:访问 管理 > 站点构建 > 区块 > 添加区块(admin/build/blocks/add)
  2. 设置区块语言:在添加区块页面的 Multilingual settings 中,将语言设置为 All languages (Translatable)
  3. 添加区块:在添加区块页面,填写以下信息后,点击“保存区块”
    区块描述:多语言化测试区块(描述)
    区块标题:多语言化测试区块
    区块内容:这是一个用于测试区块多语言化的区块 :D
    注意:实际操作时,请根据你的需要为区块填写合适的描述、标题和内容等信息
  4. 添加其它语言区块(如英语):重复第2步,将语言设置为 English(英语),重复第3步,填写以下英文信息,然后点击“保存区块”
    区块描述:Multilingual Test Block(Brief)
    区块标题:Multilingual Test Block
    区块内容:This is a multilingual test block, :D
  5. 分配区块:在区块管理页面(admin/build/blocks),找到刚创建的“多语言化测试区块(描述)”和“Multilingual Test Block(Brief)”,将其分配到指定的区块,如左边栏,点击“保存区块”
  6. 查看效果:i18n 提供的 language section 机制会自动判断多语言项目(如区块)与当前语言的关系,只有与当前语言相同的内容才会显示出来。因此当网站界面语言为中文时,站点左边栏将会显示“多语言化测试区块”,当网站界面语言为英语时,则会显示 "Multilingual Test Block"

  

Drupal 数据库迁移技巧

  在迁移 Drupal 站点时,数据库迁移是非常重要的一步。一般来讲,数据库迁移包含从老服务器上导出数据库,及在新服务器上导入数据库。

  备份数据库非常简单,使用 phpMyAdmin 或者其它数据库管理工具都可以实现。但是在将数据导入到新的服务器时,常常会遇到一些错误而导致数据库迁移失败(如图)。通常情况下,都是因为缓存数据的原因。即 cache 表及以 cache_ 作为前缀的数据库表。

Migrate a drupal database

  Drupal 在启用缓存的情况下,会在 cache 及 cache_ 前缀的数据库表中写入许多缓存数据,但这些数据对于数据迁移并不是必须的,因为当站点转移到新服务器之后,这些缓存数据又可以重新生成。但是这两个表里面的数据结构,常会出现SQL语法错误而导致数据库导入失败。

  以下是处理这些问题的一些方法:

  1. 在执行数据库备份前,关闭并清除 Drupal 缓存
  2. 在导出数据库前,清空所有 cache 及 cache_ 为前缀的表中的数据
  3. 分两次导出数据:第一次导出除 cache 及 cache_ 为前缀以外的表;第二次导出 cache 及 cache_ 为前缀的数据表的结构(不含数据)

 

  总之,导出时保证 cache 及 cache_ 为前缀的表中无数据即可。

  然后将备份的数据导入到新的服务器中,即可完成 Drupal 数据库的迁移。

 

Drupal实现多条件过滤导航(一)

  大家在上网时经常能够看很多网站都有很酷很实用的多条件过滤,通过组合许多不同的过滤条件,帮助用户逐渐缩小内容的显示范围,逐渐找到最需要的内容。

  比如像优酷这样的电影过滤

优酷电影导航

  不过相信更多的Drupaller是在做商城类的项目时遇到这样的需求,即便如此,换汤不换药 :D 大家很困惑,甚至觉得有些压力山大,究竟用 Drupal 能不能为产品实现这样的多条件过滤呢?

太平洋电脑筛选

  ——当然可以了,除了给你生个孩子,还有什么是 Drupal 做不到的呢 ;)

  在开始介绍如何实现这样的功能前,我们先统一一下对需求的认识。并且在这里希望大家认识到随着网站信息量的增大,内容标识维度的增加,不只是电影网站、网上商城,多条件过滤可以应用的范围是非常广泛的,旅行、美食、创业、图书管理、同城交友哪里都可以它的身影,希望大家开动脑筋、发散思维 :D

  好了,下面我们一起来整理一下多条件过滤的一般需求,同时我们也提出一些高级的需求,一方面是挑战自我,另一方面也是因为现一个功能很简单,但要把一个功能在现实世界中用好用强,要考虑的东西还会多很多。

 

多条件过滤需求整理

 

基本需求

  • 能够将内容相关的各项条件以链接形式显示出来
  • 通过点击相应的链接对过滤结果产生直接的影响
  • 用户能够以不同的顺序点击多个条件,显示的结果为多个条件的交集

 

高级需求

  • 高级过滤方式:除了可以通过点击链接选择条件外,还能够为用户提供一些其它类型的过滤方式,如基于全文检索的搜索框、基于价格范围(最低价-最高价)的区间过滤、基于商品评分(1~5星)的过滤等等……
  • 全局过滤条件:除了网站主体区域外,网站通常还会在边栏也会有一些相关内容(如最新电影、推荐商品)的列表结果,当用户选择了指定的过滤条件后,除了网站主体区域的过滤结果产生变化外,过滤条件还应该应用到边栏或页面其它部分。

 

  如果能实现基本需求,已经很好了,如果能够把高级需求一并实现,那就真是太酷了。当然这一切对 Drupal 而言只是不能生孩子之外能够做的众多事情中的一件,下一篇我们就来分享实现这样的多条件过滤的思路和流程 ;)

 

Drupal实现多条件过滤导航(二)—— Search API 方式

   在上一篇《 Drupal实现多条件过滤导航(上)》中我们已经了解到多条件过滤导航的基本需求和高级需求,下面就来看看通过Drupal如何得以实现。

  需求拿到手上,首先要想的即是有哪些第三方的模块可以供我们使用,如果还不知道哪些模块可供使用,使用 Google 或者 drupal.org 进行简单的搜索即可得到一些常用的解决方案。

  在开始搜索之前,有几个关键词可以帮助我们进行搜索——search(搜索)、filter(过滤)、faceted(分面搜索)、Solr(Apache Solr)。因为 filter 在 Drupal 里是“输入格式”的专有名词,进行这个搜索得到的结果往往并非是我们所需要的。另一方面我们希望通过尽可能简单的方式来实现这一功能,因此也不希望还要做到与 Apache Solr 进行整合。所以,最终我们通过 search 和 faceted 两个关键词展开搜索。

  ……

  经过一番搜索和尝试之后,大致得到以下一些模块可以帮助我们实现所需的功能,这些模块是:

  • Search API - 为Drupal提供可扩展的搜索框架,以便与各种搜索引擎联合工作
  • Facet API - 为Drupal提供易于创建和管理的分页搜索接口
  • Search API Database Search - 基于 Search API,为Drupal提供基于数据库索引的搜索后端
  • Search API Pages - 基于 Search API,为Drupal提供各种自定义搜索页面

 

  与此同时,搜索过程中还能找到一些非常实用的教程,如 Ivan Zugec 的 《How to setup Search API with Apache Solr》——尽管这篇文章里面是用 Solr 作为后端搜索引擎,如果我们希望简单地实现这一功能,使用前面提到的 Search API Database Search 来替换教程中要用到的 Search API Solr Search 模块即可。

  当按照教程完成分页搜索的配置后,即可得到类似以下截图的搜索页面,根据需要创建相应的 Faceted Block View,分配到指定的位置,然后使用CSS控制区块的样式布局(如将所有链接显示在同一行)即可

Drupal 分面搜索

Drupal 过滤搜索

  对于基本的过滤搜索,使用 Search API 来实现就能足够了,即使当数据量较大时,使用Solr作为后端搜索引擎,效率和性能也会相当出色。

  在使用 Search API 结合 Database Search 或 Solr Search 时,对于中文站点而言,更适合用于条件过滤或非搜索过滤上,因为不论是 Database Search 还是 Solr Search,在不添加分词工具的情况下它们不具备合适的中文分词能力,因此如果是需要的支持中文且需要结合搜索过滤的情况下,我们则应该考虑另一种解决方案。

  下一篇我们将接着介绍使用Drupal实现多条件过滤导航的另一种解决方案,不但配置简单,而且可以满足我们在需求篇中提到的两大高级功能——即除链接过滤之外的其它过滤方式(字符串搜索、价格区间、星级……)以及全局过滤条件(当页面有多个相关的内容块时,过滤条件同时作用于多个内容块)

Drupal实现多条件过滤导航(三)—— Views 方式

  在 D6 时代,Views 更多只是用于构造各种新闻列表、图文列表、图片集、幻灯片之类的列表或结果集。进入 D7 之后,因为 Views 被应用得更广泛,以及更多基于 Views 的第三方模块的出现,使用得 Views 的功能越发的强劲。而在 D8 中,Views 更是直接被加入了内核,可见 Views 的实用性非同一般。

  很多朋友从来只用 Views 做过简单的内容列表,不曾玩过太多基于 Views 的花样,今天我们也借着多条件过滤导航这样一个功能的需求,小窥一下 Views 不太一样的用法。

Drupal多条件过滤导航

  有前两篇的基础,这里就不再介绍需求和背景了,直接切入正题,理一理思路,看看如何使用 Views 来实现上图的多条件过滤导航。

  首先,上图应该是由三个 Views 组成,即左上的“热点真题”、左下的“精选真题”以下右侧的“最新真题”

  我们在此要实现的功能呢,即当用户使用右上方的“搜索”以及各种条件进行导航时,三个区域的内容要发现相应的变动——比如默认时三个视图均显示所有学科的内容,当用户点击了“物理”之后,三个视图均只显示与物理相关的内容。(这种设计不只在教育平台中实用,在各种电影、旅行、美食、电商站点均可提供非常爽的用户体验:D)

  像这样的设计通过 Views 要如何来实现?一旦解决方案被提出来了,大家就都会觉得真是十分的简单——将节点的字段作为过滤条件显示(暴露)出来,即可实现通过多条件/多形式进行过滤的功能,然后因为 Views 使用过滤条件时使用 GET 方式将参数追加到 URL 后,因此只要边栏的另外两个视图同样能够接收 URL 中的参数,就可以实现一处过滤,多处过滤的条件导航了。

  这里并不打算再重新截图一步一步来实现上图的效果:D 有兴趣和有需要的朋友可以参照以上的思路在自己的项目中实现这样的多条件过滤,不用写代码就能用 Views 搞出如此这般强大的页面,实在是很爽的。

Taobaoke - Drupal 淘宝客模块使用指南

  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

 

  详细教程编写中,稍安勿躁…… :)

 

 

如何为 Drupal 实现好友关注/收听(follow)功能?准备阶段

  传送之门 Alpha 2.0 版本已经上线,相对于上一版本增加了不少新特性,现在用户不仅可以收藏系统已有的页面,还可以与大家分享自己看到的优秀页面。

  在这些功能的基础上,如果能够增加收听功能就更好了。这样一来用户就可以关注感兴趣的用户,当关注的用户分享了新的内容,便能够方便的在好友动态中看到。

Drupal 好友收听

  根据现有的经验来看,要使用 Drupal 来实现这样的收听功能,应该是存在不少相关的第三方模块。比如可能存在 follow, activity 这样的模块。

  在真正动手去搜索 follow, activity 这类关键词之前,首先还是将需要实现的需要罗列出来,有的放矢才不会在搜索模块时看得眼花缭乱。

好友关注/收听(Follow)需求

  • 用户之间可以方便地收听、取消收听(如果能够做到一键执行将会是很好的用户体验)
    * 说到一键收听,不经想到 Flag 模块可以实现这样的需求。如果 Flag 能够方便地整合并实现后面几项需求,那不失为一个好方法。
  • 用户可以查看关注自己的用户列表以及自己关注的用户列表
    * 这一点Flag + Views很容易实现
  • 当用户执行了一些特定操作时,如分享网页,能够将这个消息推送给关注此用户的听众(这项需求还需要一定的扩展性,以便于自定义通知行为)
    * 之前在群里有朋友问到过类似的需求,记得当时有朋友推荐看看 heartbeat 模块

 

  需求整理好之后,接下来就开始基于这些需求开始查找可用的模块了。结合想到的关键词 —— follow, following, activity, 以及可能符合条件的两个模块 flag, heartbeat,下面就开始用 google 和 drupal.org 进行搜索了。

  等找到合适的模块之后,我们再继续通过后续的文章来看如何为 Drupal 实现好友收听功能。:D

如何为 Drupal 实现好友关注/收听(follow)功能?模块选择

  上一篇我们讲到《如何为Drupal实现好友关注/收听(follow)功能的需求分析》,然后便开始针对一些关键词和模块进行搜索、调研和试用,最终决定使用 Flag 及 Message 模块来实现所需的功能。

  在确定使用 Flag 及 Message 模块之前,搜索了诸如 follow, activity 之类的关键词,同时也通过 Google 进行了一些搜索,还通过 Drupal 模块页面的相关项目了解了其它不少模块。下面列出好友收听/关注这类功能可能用到的一些模块,如果大家有类似的功能需要实现,可以进行一些了解。

模块列表

  • Flag Follow - 基于 Flag 的关注模块,提供用户之间单向关注的功能,与 Heartbeat 整合,可直接使用
  • Flag Friend - 基于 Flag 的好友模块,提供用户之间双向的交友功能
  • User Relationships - 可以根据需要自定义各种用户关系,支持单向及双向用户关系
  • Heartbeat - 提供用户行为的记录和展示,展示效果很不错,而且与上述几个模块都可能整合。可惜项目主页说明模块将废弃,今后可能使用 Message 模块更多一些
  • Activity - 提供简单用户行为记录和展示

 

  以上模块都有其各自的一些功能和优势,但最终都没有选择,下面说明一下我们是如何基于《如何为Drupal实现好友关注/收听(follow)功能的需求分析》来进行模块筛选:

  • Flag Follow - 既提供了单向的关注功能,又与 Heartbeat 直接整合,启用差不多就能直接满足需求。但 Heartbeat 模块已声明将废弃,使用此模块后续升级和继续维护可能存在较大问题。加上使用 Flag 能够很容易实现用户的单向关注,如果模块本身与 Heartbeat 整合的优势不考虑进来,确实不是很必要使用这个模块。
  • Flag Friend - 这个模块主要用于提供双向的好友功能,与我们的需求不符合。
  • User Relationships - 此模块可用于定义各种用户关系,但过于庞大,相比用 Flag 来实现单向关注的功能要复杂一些。另外相比此模块与 Flag 模块数据表结构、以及与 Views 与其它模块的整合上来考虑,Flag 应该更胜一筹。
  • Heartbeat - 在 Heartbeat 与 Message 之间选择确实费了不少功夫,不打算使用 Heartbeat 的最主要原因即在于此模块将废弃,而他最大的吸引力在于内置的消息显示方式。后来从发展的眼光来考虑,还是决定使用 Message 模块。
  • Activity - 各方面都比较简单,项目介绍页面也没突出介绍其展示效果或功能或扩展性方面的优势,所以不深入调研

 

  在模块选择这一阶段,最终选择了使用 Flag 和 Message 模块。选择这两个模块,主要基于以下条件考虑:

  • 使用 Flag 定义一个简单的“关注/取消关注”标识,用户可以方便地一键关注和取消关注用户
  • Flag 可能与 Views 整合,方便地制作“我关注/收听的人”和“关注/收听我的人”这两项列表(经过后来试用,简单配置一下即可方便整合——无需代码)
  • Message模块能够记录和展示用户的行为,并且方便扩展用户自定义行为(发布内容、分享链接等等)
  • 如果能够通过 Views 过滤出“我关注/收听的人”的所有行为,即可以实现像微博那样看到自己关注的更新了——这里面稍微复杂一点,涉及 Message 与 Views 的整合以及 Views 与 Flag 关联并过滤的问题。之后我们只要验证这一点,整个功能就能够走得通了。

 

  从分析上来看,只使用 Flag 和 Message 模块即可以实现好友关注及查看好友动太更新的功能。那后续的博文我们就需要实际进行一些操作和配置,看看如何使用 Flag 模块实现一键关注/收听,以及如何结合 Message 模块实现查看关注用户的动态更新。

浅谈 Drupal 配置迁移

  Drupal 配置迁移是什么?很多 Drupaller 对这个话题感到无所适从,新人工作之初并不会意识到这个问题的存在,而意识到这个问题的朋友也不确定怎样正确地进行配置迁移。本文就围绕 Drupal 配置迁移的原因、方式/方法及相关模块较为系统地聊聊这个话题。

Drupal Migrate

  如果你被以下问题困扰,仔细阅读本文将会对你有所助益

  • 修改了一些站点配置(如站点名称、标语或任何存在于variables表中的变量值),怎么一次性部署到线上?怎么跟踪每次的修改记录?(大部分情况下你是不是直接在线上修改了:D)
  • 在开发环境中页面布局进行了调整,修改了区块的配置(如位置、显示条件)和内容,怎么样才能快速地部署到线上(是不是手动一个一个去调整,把做过的事情重新再做一遍——这样很无趣,也很费时,还容易遗漏和出错,尤其是当这些配置之前是由其它人配置的,想要再准确地复现将会非常困难)
  • 在开发环境中添加了几个新的字段、内容类型、输入格式、Wysiwyg配置或者视图,不想在线上再手动操作,点鼠标点到手发麻,又应该怎么办?
  • 开发过程中需要大量实际数据,不能直接在线上操作,如何把实际数据从线上迁移到开发环境中?
  • ……

 

为什么 Drupal 要做配置迁移?

  大家都熟悉传统的Web开发,主要工作都是面对代码,不管是PHP、CSS、HTML或JS,几乎所有的工作都是在文件中完成。如果要更新或升级某些功能,做好备份后上传修改过的文件就能完成,So Easy!

  对Drupal而言,配置迁移就不那么简单了,因为文件迁移只是 Drupal 配置迁移的一小部分,Drupal 中大部分的配置存在于数据库中。而因为线上环境的数据库时刻在变化,要把开发环境中一部分数据库的内容更新到线上而又不影响线上的内容,可不是一件容易的事。

Drupal configuration in database

  Drupal将配置存在于数据库中是经常被Drupal老手们诟病的问题之一——最大的缺点是你不能简单地迁移数据库中的某些值或对其实行版本控制,当然这样设计的优点在于方便开发人员进行研发,以及方便使用者通过界面(而不需要修改代码)非常快速地对功能进行调配。(再一次,Drupal选择了灵活性而牺牲了其它东西)

  在D8之前,Drupal没有统一的标准来规范大家应该如何存储各自己的配置数据,不同模块的配置格式和存储方式并不相同,因此也就无法通过某种特定的方式一次性迁移出所有配置数据。

  (D8开始实施配置管理系统了,从此对配置的管理有了统一的规范和标准,可参见《Drupal 8 配置管理机制及新特性简介》)

  而另外一点造成Drupal的配置迁移成为一个难点话题的原因在于,D8之前,Drupal的配置和内容混合存储在数据库中,很难将两者分离开,如果只是通过覆盖数据库的方式来进行操作,无法做到只改变配置而不触及内容,反之亦然。

  因为设计上的原因,使得Drupal的配置迁移成了一个难点,针对于它的工作流程和解决方案也就成了一个独立的、不可回避的且颇有意思的话题。

  目前有关Drupal配置迁移的处理方式已经非常成熟,D8之前的配置迁移可以参考本文,D8的配置迁移大家去学习其配置管理系统的知识并熟练运用即可。虽然D8之前没有官方统一的标准配置管理体系,但D8配置管理体系的很多理念与本文提及的各种配置迁移方式是相同的,因此学习本文也将会使之后了解D8的配置管理系统变得更为容易一些。

 

加强 Drupal 配置迁移自动化的优点

  相信有很多朋友在做 Drupal 开发时会先在本地做一次,然后到测试环境或生产环境再做一次。当然这也不失为一种方式,对小站点的功能部署还能适用,但对于在线下进行了几周甚至几个月的工作量,再重复做一次的代价可是相当大的——前提还要是每个人都记得整段时间都按什么顺序做了什么配置。

  如果大家希望更轻松、更准确、更高效、更简单地完成配置迁移的任务,不妨学会如何让配置迁移更为自行化。

  以下是通过各种工具进行自动化配置迁移的一些主要优点:

  • 减轻工作量——大量配置的部署真的可以点鼠标点到手发麻,将大量点击操作简化为上传文件会轻松很多;
  • 降低错误率——人往往是出错的主要原因,让代码来记忆第一步操作可以大大降低出错机率;
  • 版本控制——能够记录每一次配置的变更状况与时间,同时也更容易将配置恢复到某个时间点的备份;
  • 快速部署——站点经不起长时间离线,将数周及数月的更新在数分钟基本数秒钟之内完成会有很爽的成就感;
  • ……

 

Drupal 常见的配置迁移情况

  之所以要谈配置迁移,是因为Web项目至少会有两个环境,即工程师的本地开发环境,和在线运行的生产环境。而通常情况下,标准的Web项目会涉及“开发-测试-线上”,即流行的 Dev-Stage-Prod 模型(也有称Dev-Stage-Live),复杂点的情况还会再加上一个QA环境。也正因为如此,才出现了配置迁移的需要。

Dev Stage Prod Environments

  在后文中,我们将以 Dev-Stage-Prod 环境模型为来了解 Drupal 的配置迁移方式及方向。因为这正好代表了我们平时的工作流程——工程师在各自的本地进行开发,然后部署到测试环境集中测试,反复修正最后再部署到线上。

 

Drupal 需要迁移哪些内容以及如何迁移

  了解了需要迁移的原因,我们再看看需要迁移的内容。正如前面所说,Drupal 中不同的配置有不同的迁移方式,使用对的工具和对的方法能够达到事半功倍的效果。

迁移项

存储位置

迁移方式

模块、主题

模块、主题文件中

直接上传文件

环境变量

数据库中

结合 Features 结合 Strongarm 模块打包到文件,然后上传

视图、编辑器、内容类型、字段、区块

数据库中

使用 Features Features Extra 等模块打包到文件,然后上传

*术语、用户等配置依赖内容

数据库中

可使用 Features, UUID 及 UUID Features 等模块打包到文件,然后上传。

但建议先添加到线上环境,然后将数据库下载到本地进行开发会更简单,详见下方

……

……

……

  不要感觉要记很多东西似的,这里帮你整理一下 —— Drupal 的配置无非就是存在于文件和数据库中,存在文件中的配置很好处理,直接上传就行。而对于存在于数据库中的配置呢?很简单 —— 先转化成文件,然后上传文件。

  在举例说明不同配置迁移的最佳实践前,建议大家一定记住下图——代码(配置)由下往上,数据库(内容)由上往下——这是团队协作的基本铁律,以便确保文件和数据库都是由新往旧的方向部署,从源头减少冲突的发生

代码及内容更新方向

  (很多人在协作时会问这样的问题,说“我在线上修改了视图的配置,然后线下更新了视图的配置文件,这样要怎么更新呢?”这就是典型因为协作流程不规范而产生的人为冲突,一旦按照规范能够约束文件(配置)、数据库(内容)的更新方向,这类问题基本上便不会出现了。

  回到文章开头提到的几个问题,现在再来看看这些配置迁移流程建议:

  • 站点配置或其它变量迁移 – 使用 Features 模块,结合 Strongarm 模块将要跟踪的变量打包到文件中,然后按 Dev->Stage->Prod 的方向进行更新部署
  • 区块配置迁移 – 使用 Features 模块,结合 Features Extra 模块,将区块的配置及内容打包到文件中,然后按 Dev->Stage->Prod 的方向进行更新部署
  • 内容类型、字段、视图、输入格式、编辑器配置等 – 使用 Features 模块(必要时结合Strongarm)将配置打包到文件中,然后按 Dev->Stage->Prod 的方向进行更新部署
  • 内容数据的更新 – 使用 Backup and Migrate 模块或其它方式导出线上环境的数据库,并按 Prod->Stage->Dev 的方向进行内容更新

 

Drupal 配置迁移小结

  现在看来,Drupal的配置迁移无非是两部分的内容,一部分已经存在于文件(如模块、主题)中的内容,直接上传文件进行更新即可;另一部分存在于数据库中的部分配置(或内容),即通过Features及其它相关模块先将配置导出到文件中,再按更新文件的操作进行即可。

  别看关于 Drupal 配置迁移好像写了不少,主要便是掌握 Features 模块的用法和流程,稍加练习几次就会发现真是非常简单。

Drupal 代码规范

  本代码规范翻译自 Drupal 官方网站的代码规范文档(http://drupal.org/coding-standards),方便国内的 Drupal 开发人员更好的学习和遵循代码规范。优秀的开发人员应该有遵循高标准以及编写高质量代码的意识。:)

 

索引

缩进与空白字符(Indenting and Whitespace)

  • 使用 2 个空格而不使用 tab 键进行代码缩进(notepad++, Eclipse 等编辑器均支持此项配置);
  • 行尾不应该有空白字符
  • 应使用 \n (Unix换行符),而不是 \r\n (Windows 换行符)
  • 所有文件均应以一个空行结尾

运算符(Operators)

  • 所有二元运算符(二个值之间的运算符),如 +, -, =, !=, ==, > 等等,在运算符两端均需留有一个空格,如应该使用 $foo = $bar 而不是 $foo=$bar。
  • 所有一元运算符(只操作一个值班的运算符),例如 ++,在值与运算符之间则不应加入空格

转型(Casting)

  • 在 (type) 与要转型的变量之间应加入一个空格,如 (int) $mynumber.

控制结构(Control Structures)

控制结构包含 if, for, while, switch 等等,下面是一个简单的 if 语句结构示例:

if (condition1 || condition2) {
  action1;
}
elseif (condition3 && condition4) {
  action2;
}
else {
  defaultaction;
}

控制语句的关键词与左边括号之间应该有一个空格,以此来与函数调用进行区分。

即使在大括号是可选的情况下,也应当总是使用大括号。这样可以加强代码的可读性以及减少因嵌套带来的逻辑错误。

switch 语句结构示例:

switch (condition) {
  case 1:
    action1;
    break;

  case 2:
    action2;
    break;

  default:
    defaultaction;
}

do-while 语句结构示例:

do {
  actions;
} while ($condition);

行长度与封装(Line length and wrapping)

  • 通常情况下,每行代码的长度不应超过80个字符
  • 以下情况,行长度可超过80个字符:当行内包含过长的函数名称、函数/类定义、变量声明等
  • 为方便阅读和理解,控制结构的行长度可超过80个字符
    if ($something['with']['something']['else']['in']['here'] == mymodule_check_something($whatever['else'])) {
      ...
    }
    if (isset($something['what']['ever']) && $something['what']['ever'] > $infinite && user_access('galaxy')) {
      ...
    }
    // Non-obvious conditions of low complexity are also acceptable, but should
    // always be documented, explaining WHY a particular check is done.
    if (preg_match('@(/|\\)(\.\.|~)@', $target) && strpos($target_dir, $repository) !== 0) {
      return FALSE;
    }
  • 控制条件(condition)不应该写作多行
  • 控制条件应该适当拆分以便于阅读和理解,编写代码时要避免以下情形:
    if ((isset($key) && !empty($user->uid) && $key == $user->uid) || (isset($user->cache) ? $user->cache : '') == ip_address() || isset($value) && $value >= time())) {
      ...
    }


    将控制条件进行拆分,不仅便于阅读,同时也方便添加注释让人知道为何进行这样的条件判断
    <?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) {
        ...
      }
    ?>

函数调用(Function Calls)

调用函数时,函数名与左括号之间没有空格,除最后一个参数外,每个参数后的 , 都应跟上一个空格,如:

<?php
$var 
foo($bar$baz$quux);
?>

如之前所说,等号两边应该各有一个空格。当有一系列相关语句时,出于可读性的考虑,可以适当增加空格的数量,如:

<?php
$short         
foo($bar);
$long_variable foo($baz);
?>

函数声明(Function Declarations)

包含默认值的参数应当放在最后,当函数拥有返回值时,尽量返回便于理解的值:

<?php
function funstuff_system($system$field 'description') {
  
$system["description"] = t("This module inserts funny text into posts randomly.");
  return 
$system[$field];
}
?>

类构造器调用(Class Constructor Calls)

当调用不带参数的类构造器时,始终包含括号

<?php
$foo 
= new MyClassName();
?>

带参数的类构造器

<?php
$foo 
= new MyClassName($arg1$arg2);
?>

如果使用变量做为类名,需先为变量赋值,然后才调用类构造器:

<?php
$bar 
'MyClassName';
$foo = new $bar();
$baz = new $bar($arg1$arg2);
?>

数组(Array)

数组的值之间应使用空格分隔,赋值操作符号(=>)左右也应包含空格:

<?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提交代码时,一些代码规范检测脚本会因为最后一个元素没有添加逗号而出现警告提示。)

引号(Quotes)

Drupal 对于单引号和双引号的使用并没有很强硬的标准,只需在同一模块内保持用法的统一即可。

使用单引号的效率要高于双引号,因为解析器不需要到引号之间查找变量。以下是使用双引号的两种情况:

  • 引号中间带有变量,如
    "<h2>$header</h2>"
  • 引号中间带有单引号,使用双引号可避免对单引号的转义
    "He's a good person."

    当然也可以使用单引号,但 .pot 解析器不能很好的处理这种情况,而且看起来怪怪的

    'He\'s a good person.'

字符串连接(String Concatenations)

在点与要连接字符串之间需要加入空格以加强代码可读性:

<?php
$string 
'Foo' $bar;
$string $bar 'foo';
$string bar() . 'foo';
$string 'foo' 'bar';
?>

如果只是简单地连接变量,可以使用双引号

<?php
$string 
"foo $bar";
?>

使用连接赋值符(.=)时,需要在符号两侧预留空格

<?php
$string 
.= 'Foo';
$string .= $bar;
$string .= baz();
?>

注释(Comment)

注释规范单独在 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 Code Tags)

始终使用 <?php ?> 来界定PHP代码而不使用要 ?>。这是为了遵循Drupal规范,同时也便于代码在其它系统和平台中被引用。

自 Drupal 4.7 开始,最后的 ?> 都故意被忽略不写,原因如下:

  • 移除它可以避免在文件末尾出现空白字符,这些空白字符可能导致“文件头已发送(header already sent)”错误,XHTML/XML验证错误,及其它问题
  • PHP 官方说明结尾的PHP界定符是可选项
  • PHP.net 自身也移除了文件末尾的界定符(如 prepend.inc

分号(Semicolons)

PHP 语言要求除了代码块以外,大多数行尾都要跟上分号。Drupal 代码规范同样有此要求,并且对于代码块也是如此。以下是一个单行代码块的示例:

<?php print $tax; ?> -- YES
<?php print $tax ?> -- NO

示例 URL(Example URL)

使用 example.com 表示所有示例 URLs

命名规范(Naming Conventions)

函数与变量(Functions and Variables)

函数与变量名称应该使用小写字母,且单词之间使用下划线分隔。函数应该使用模块组/模块名称作为前缀,以避免与不同模块间的冲突。

持久变量(Persistent Variables)

持久变量是指通过 variable_get()/variable_set() 函数取得和设置的变量,变量名称应该使用小写字母,且单词之间使用下划线进行分隔。持久变量也应该使用模块组/模块名称作为前缀,以避免与不同模块间的冲突。

常量(Constants)

  • 常量始终要求使用全大写字母,且单词之间使用下划线进行分隔。(包括PHP内置常量 TRUE, FALSE, NULL)
  • 模块中定义的常量需始终使用大写的模块名称作为前缀。
  • 在 Drupal 8 及之后,应使用 const 关键词代替 define() 函数来定义常量,因为效率更高
    <?php
    /**
    * Indicates that the item should be removed at the next general cache wipe.
    */
    const CACHE_TEMPORARY = -1;
    ?>

    注意 const 不能用于PHP表达式,因此在条件判断和非字面值(non-literal value ???)时,还是应当使用 define() 函数
    <?php
    if (!defined('MAINTENANCE_MODE')) {
      
    define('MAINTENANCE_MODE''error');
    }
    ?>

全局变量(Global Variables)

定义全局变量时,应当使用下划线加模块/主题名称开头

类(Class)

类名应使用驼峰式命名(即单词首字母大写)

<?php
abstract class DatabaseConnection extends PDO {
?>

类中的方法(函数)和属性(成员变量)应使用首字母小写的驼峰式

<?php
public $lastStatement;
?>

定义访问权限时,使用 protected 而代替 private,从而其它的类可以在必要时扩展和更新方法。Protected 和 public 函数和变量不应以下划线开头。

更多关于面向对象的编码规范

文件名(Filename)

所有文档文件都应加上 .txt 后缀,以便于 Windows 用户查看。同时,所有文件名称应该全部大写,而文件后缀应该全部小写。

如 README.txt, INSTALL.txt, TODO.txt, CHANGELOG.txt 等等。

辅助模块及工具

  • Coder 模块:可以遵循部分以上代码规范,对代码进行审查及修改建议
  • Drupal Code Sniffer:代码规范检测工具
  • PAReview.sh:还处理沙盒中的代码规范检测脚本,几乎严格遵守以上所有代码规范并给出修改建议。

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

  }
  
}
?>

Drupal 问题与解决办法

  使用 Drupal 过程中遇到的一些问题,问题的描述以及这些问题的解决办法。主要来自于实际项目过程中遇到的问题,是一些实用性强的技巧性资源。

 

 

CCK 富文本框字段拖拽 Bug 的解决办法

  某个项目需要指定的节点包含多个可拖拽、无限数量、带富文本编辑器的文本输入区域。

 

实现方式

使用 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 字段之前没有很好的考虑字段的类型,那么在项目后期很可能就需要对字段进行修改。对于刚刚创建的 CCK 字段,如果字段的类型选择错了,最简单的办法就是把字段删除,然后添加一个类型正确的字段。这倒不会有什么伤害。

  不过并不是所有情况都是这么简单,有时候网站运行了很长时间之后才发现之前定义的字段类型已不能满足需要了。例如一开始创建的是 float 类型的字段,但因为数据的增长,发现需要将内容类型转换成 decimal。在这种情况下,如果删除 float 字段,所有存储在 float 字段里的数据也都一同被删除了。所以,要最大限度地保证原有数据不丢失,应该如何更改 CCK 字段的类型。

 

更改 CCK 字段类型的方法

注意:执行以下操作前,请先备份数据库

  1. 为内容类型新增加一个类型正确的字段,名为 field_<tmp>(这只是一个临时的字段,名称并不是很重要),并按照正确的配置对字段进行配置;
  2. 执行 SQL 语句将 field_<origin> 字段中的所有数据复制到 field_<tmp> 字段中;
    UPDATE content_type_<your content type> SET field_<new fieldname>_value = field_<old fieldname>_value
    注意:请在执行以上语句时,使用对应的内容类型名称和字段名称代替其中尖括号(<>)中的名称
  3. 删除原来的 CCK 字段 field_<origin>;
  4. 再建立一个类型正确的字段,使用删除的 CCK 字段的名称 field_<origin>,并按照正确的配置对字段进行配置;
  5. 执行类似第2步中的 SQL 语句,不过这些一次要将数据从 field_<tmp> 复制到 field_<origin> 中
  6. 删除临时字段 field_<tmp>;
  7. 完成。

 

  按照以上步骤更改 CCK 字段的类型虽然有点麻烦,但最重要的是能够保全数据。因为数据类似不一样,可能会导致一些数据丢失精度,但小面积的损失远远好过于丢失全部数据 :D

 

参考文档:http://drupal.org/node/769784

Drupal 的缺陷与不足

  在上周六的 Drupal 交流会 上与大家一起探讨了《Drupal 的缺陷与不足》,在此对所讨论到的内容进行一些梳理。

Disadvantages of 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