Drupal 是一个框架:为什么每个人都需要理解这一点

作者:Diana Dupuis

每个计划和使用 Drupal 构建 Web 解决方案的人都会从理解“hook”(钩子)是什么中受益——以及为什么 Drupal 不是一个 CMS。

Drupal 采用者面临的最大挑战之一,无论是新的网站所有者还是初级开发人员,都是弄清楚使用 Drupal 哪些事情容易做,哪些事情难做。作为一名开发人员、解决方案架构师、技术策略师,甚至作为一位了解网站的朋友,我 60% 的讨论都围绕着三个问题:需要多长时间、需要多少成本,以及我的网站能否做 [插入酷炫的新事物]?

有时,这些问题很容易回答。许多与内容相关的任务可以通过简单地登录 Drupal,访问 /admin 页面并单击菜单链接,直到您到达必要的管理页面来完成。

但更常见的情况是,有些问题很难回答。有些任务可以通过添加贡献模块来完成,这些模块可以轻松“插入”到 Drupal 核心中,因为它“开箱即用”,并扩展网站的功能。贡献模块由 Drupal 社区创建和共享,可以添加到任何 Drupal 网站。

有些任务需要编写自定义代码,并且必须构建新的模块。自定义功能涉及多层潜在的功能。有些功能需要通过应用程序编程接口 (API) 与其他站点来回通信。较大的网站通常需要创建小型应用程序,在后台 Drupal 的通常工作流程之外完成任务。在许多情况下,存在多种解决方案,选择一种解决方案意味着放弃一些东西以获得其他东西。作为开发人员或利益相关者,找到满足业务目标并保持在范围内的最佳解决方案取决于合作讨论。

这就是沟通经常中断的地方。开发人员说一种语言,而网站所有者、项目和客户经理、利益相关者以及参与决策过程的其他人员说另一种语言。当人们第一次了解 Drupal 时,他们的入门通常侧重于节点是什么、区块、内容类型和视图是什么,以及如何创建 SEO 友好的 URL。这些概念很重要,但它们经常未能回答“这有多难做”这个基本问题,或者为更复杂功能的协作规划提供坚实的基础。每个参与者都需要理解,他们可以构建一个 Drupal 站点,该站点提供比 WordPress 站点更复杂的功能集,因为 Drupal 不是内容管理系统 (CMS);它是一个内容管理框架。

将 Drupal 概念化为一个框架不需要多年的编程经验;相反,它只需要理解“hook”(钩子)是什么,并找出您需要的 hook 是否存在,并且已经能够完成您想要完成的事情。

为了理解 hook,有必要理解 Web 应用程序交付的动态网页与静态网页的不同之处。大多数精通技术的人都认为这种知识是理所当然的,尤其是 Linux 爱好者和那些第一台台式电脑在 C: 提示符下有一个闪烁光标的人。但是很多人不知道网站是如何工作的。(他们为什么要了解?)以下是我用外行术语解释差异的方式。

在过去,静态页面是单个文本文档,其中包含您在页面上看到的所有内容,除了图像,都在一个文本文件中。该文件包含 HTML 标记,描述了正在显示的内容类型——例如,<p> 表示段落,<h1> 是大标题。浏览器(下载需要十个小时)转换了这种标记,并在文件名指示的 Web 地址上呈现了具有可读结构的页面。该文档将被上传到服务器并保存在网站的主文件夹中。然后可以使用浏览器在 yoursitename.com/page.html 查看文件名 page.html。

如果您想更改网页的内容,您可以编辑该文件。如果您想更改出现在网站所有页面上的标题中的内容,您必须编辑每个页面。无论是将内容链接在一起还是显示类似的侧边栏,内容都是在每个页面上手动单独布局的。

如今,大多数网站都是动态的。称为 Web 应用程序的小程序被上传并存储在服务器上。程序运行时,不是交付静态页面来查看,而是当浏览器到达页面时运行程序,将逻辑应用于页面创建过程。此逻辑指示每次请求页面时(也称为“页面加载时”)如何构建页面。例如:程序获取标题,获取主菜单,获取页面的唯一内容,获取页脚,并将整个页面交付给浏览器。因此,现在可以有一个可编辑的标题、一个页脚和一个在所有网页之间共享的菜单。

那么页面的唯一内容呢?应用程序如何“获取”它?想象一个电子表格,其中每一行代表每个页面的唯一内容。动态网站以这种方式存储内容。它们使用数据库,数据库可以想象成电子表格的集合,称为表。每个表,像电子表格一样,都有列和行。每一行都有一个唯一的 ID。当显示页面时,与该页面关联的内容——例如,一篇关于容器园艺的文章——从数据库表中检索出来并输出到页面。

在 Drupal 的情况下,编程语言 PHP 提供逻辑,MySQL 提供数据库。通常,安装在服务器上以支持此过程的操作系统是 Linux,而 Apache 是处理页面请求并在构建完成后交付页面的软件。这个软件包称为 LAMP 堆栈。

如果没有像 about.html 这样的静态文件名,动态网站如何知道要显示内容表中的哪一行?Drupal,像其他 Web 应用程序一样,使用查询字符串将内容与页面地址匹配。查询字符串看起来像这样:?q=1234,它们附加在 URL 的末尾——例如,yoursitename.com/?q=1234。Drupal 使用修改后的(同样令人费解的)地址结构:yoursitename.com/node/1234。在这两种情况下,唯一的 ID,页面内容的行号,都在那里:1234。

显示语义 URL 的网页,如 yoursitename.com/growing-a-container-garden,已经包含了将唯一 ID 与单词配对的逻辑。但对于每个页面,仍然存在唯一的 ID,并与数据库表中的内容关联。

随着动态 Web 应用程序的出现,驱动它们所需的编程语言和数据库的持续发展,以及世界对越来越丰富的内容型网站的迫切需求,——内容管理系统 (CMS) 诞生了。Drupal 是一个 CMS,因为它是一个将内容保存到数据库并使用写入其核心或由程序员添加的逻辑将其显示到页面的应用程序。但 Drupal 不是(真正地)一个 CMS;它是一个框架,可以做“CMS 式”的事情。Drupal 为 Web 应用程序提供结构,远比 CMS 复杂,可以完成网站可以做的所有事情:扩展功能(使用贡献或自定义代码)、与其他 Web 应用程序通信、在后台运行用 PHP 和其他语言编写的应用程序、提供响应式页面或集成前端语言、通过利用服务器技术扩展以处理大量流量,并为其他尚未想到的创新提供基础。

这就是过程变得巧妙的地方。但是,在明确难易程度取决于 hook 之前,还需要采取一个概念步骤——引导启动。同样,这个概念对于以技术为中心的读者来说可能看起来是常识,但解释起来可能很拗口。以下是我的外行版本,这是一个过度简化,但更深入的理解不是理解 hook 的先决条件。

当浏览器访问网页时,Drupal 会问一系列问题。提问过程称为引导启动。问题 (Q) 触发操作 (A)。

  • Q: 你(一般)是谁,你想要什么? A: 初始化并存储一般信息。

  • Q: 我可以直接给你存储的副本吗? A: 提供缓存数据(存储在内存中的内容)。

  • Q: 我可以连接到数据库吗? A: 连接或崩溃。

  • Q: 我需要从那里获取任何东西才能工作吗? A: 获取它。

  • Q: 你(具体)是谁? A: 启动会话。

  • Q: 你的要求是什么? A: 创建服务器/浏览器页面标头(用于进一步关联的参数)。

  • Q: 你在哪里? A: 选择语言。

最后,Drupal 交付内容

  • Q: 哪个页面? A: 提供页面。

这是最佳位置,大多数(但不是全部)hook 魔术发生的地方。

Hook 是称为函数的微小功能块,其中包含 PHP 代码。这些代码块在被调用时运行。在引导启动过程中,尤其是在提出最终的“哪个页面?”问题时,会调用 hook。每当 Drupal 中发生事件时,例如删除页面,都会调用 hook。在这些 hook 内部,有代码可以更改功能,并且一旦调用 hook,它就会运行。几乎任何你想让 Drupal 做的事情都有一个 hook 在做。

Drupal 依靠命名约定在正确的时间调用 hook 以运行它们。在构建菜单时,Drupal 会查找名称中带有“_menu”的 hook。当页面被删除时,会调用名称为“_delete”的 hook。

Drupal 模块覆盖现有 hook 或添加新的 hook。例如,如果我想更改表单的显示方式,我将更改的代码放在名为 mymodulename_form_alter 的函数中。当表单的页面被构建时,Drupal 将查找任何“_form_alter”函数,以查看是否还有更多事情要做。我也可以在自定义代码中创建新的 hook,这些 hook 可以被其他 hook 调用,mymodulename_myhook。

Hook 不仅仅控制行为。主题,即专门指示网站外观和感觉的文件集合,也包括 hook。Drupal 网站的前端(演示而不是行为)不仅仅是绘制上去的;它也依赖于 hook,所有 hook 都在 Drupal 交付页面时被调用。

还记得我们最初的三个问题吗:这需要多长时间,那会花费多少钱,以及我的网站能否做 [插入酷炫的新事物]?答案,以及某件事是容易(快速、便宜且已经可能)还是困难(耗时、昂贵且创新),取决于 hook。“我希望我的网站做 X。这容易还是困难?”从易到难的尺度看起来像这样

  • Drupal 已经做了你想让它做的事情,因为必要的 hook,以及必要的代码,默认情况下运行。

  • Drupal 提供了一个管理界面,供你打开或更改它。

  • 一个模块或主题已经被编写出来,调用或添加你需要的 hook(以及其中必要的代码)。

  • 必须编写自定义代码(使用或创建 hook 并向其中添加代码)。这里所需的时间和精力差异很大,从快速编写的三行代码到数月的编程,创建多个可贡献的模块。

  • 必须创建自定义数据库表。在这个复杂程度上,代码仍然会依赖 hook,但开始在 Drupal 原生功能之外运行;因此,它(有时)比仅添加代码更复杂。

  • 必要的数据来自其他网站,或者您网站的新功能需要与其他网站通信(例如,信用卡处理)。完成此操作的时间和精力也差异很大,可能像添加一个模块(已经处理这种通信)一样容易,也可能像编写一个在调用适当的 hook 时运行的单独应用程序一样困难。您的网站将如何处理数据以及它给系统带来的负载也极大地影响了复杂性。

  • 您的任务无法在页面加载时运行,必须编写一个特殊的过程来完成它们。有时,这是一个快速的添加(使用 hook_cron 的简单 cron 作业),有时这很复杂。通常,当数据处理会减慢页面加载速度(或使网站崩溃)时,会使用这种方法,因此它会异步处理并保存(缓存),在页面加载并提出问题时提供缓存版本。

Drupal 是否已经包含运行必要代码的必要 hook,并且它是否提供了一个管理界面来设置您想要完成的事情?容易!您是否需要从其他地方获取大量数据,异步于页面加载进行处理和保存,并创建与现有数据交互的新数据库表?困难!

Drupal 核心和许多贡献模块主要设计用于管理内容,以驱动 CMS——这就是为什么从某种角度来看,说 Drupal 是一个 CMS 是正确的。开箱即用,用户可以创建任何可以想象到的内容类型——书评、食谱、学术论文提交、新闻稿、博客文章等等。Drupal 7 中的管理界面使得创建节点(具有标题和正文的基础内容类型)并将相关数据字段添加到其中,例如书评中的作者和出版商,成为一项无需代码的任务。创建包括封面图像、作者、出版商、出版日期以及指向 Powell's City of Books 的链接的书评非常快。为每个评论添加五星评级只需添加一个贡献模块并将其打开即可。

使评论看起来像设计有多难取决于设计与 Drupal 将内容呈现到页面的方式有多大差异。如果作者、出版商等将按照管理创建的顺序显示,并根据网站的通用样式指南进行样式设置,则创建外观和感觉涉及向主题的 CSS 文件添加一些 CSS。容易!但是,如果页面将以独特的顺序分发字段或包含自定义行为(例如也显示用户评级的其他书籍),则需要完成自定义工作。模块和主题中的 hook 使这项工作能够发生,允许页面加载过程被中断和编辑。

具有讽刺意味的是,Drupal 能够创建书评内容类型的事实也使其成为一个框架。用 Drupal 核心贡献者和 Drupal 协会顾问委员会成员 Larry Garfield 的话来说:

今天的 Drupal 是一个为各种不同需求构建内容管理系统的工具。对于希望构建 Drupal 网站的人来说,这是一个重要的区别。Drupal 不是一个 CMS。它是您用来构建自己的 CMS 的框架,以满足您的规范,以满足您的需求。它是一个内容管理框架。

深入研究 hook 的语法确实需要编程知识,并且根据我的经验,这应该是开发人员和产品所有者之间讨论结束的地方。我的开发人员同事和我讨论了实现 hook 的技术方面:使用哪个 hook,将它们放在哪里,何时调用它们,如何简化它们运行的代码,性能问题和缓存计划,使用贡献代码还是编写自己的代码的决定。一旦决定例如拉入 feed 并显示它们,关于“如何”的讨论就开始了。(Node.js 任何人?)沟通在实施“如何”时出现的问题,并与网站所有者进行协作决策是管理开发的精细艺术,也是对话重新开始的地方。当每个参与者都理解 Drupal 如何工作(框架!)并信任开发团队做出的难易程度评估时,这个过程每次都会变得更容易。

Hook 创建、定义和覆盖用于构建信息架构的 Drupal 工具——将内容与其他内容关联并创建可导航的结构。没有人希望网站吐出一个巨大的内容块。构建信息架构的主要工具是内容类型、菜单、区块、分类法和视图。

  • 节点、内容类型和字段为内容提供结构。字段(如作者或出版商)使内容创建变得容易,并为用户提供视觉连续性。

  • 菜单通过创建关联结构来实现导航。菜单创建内容地理,并揭示探索它的路径,而不会迷路。

  • 区块是可以与区域(如侧边栏或页脚)关联并在其中显示的 content 内容框。这些框可以用任何类型的内容填充:节点和内容类型、菜单、列表、带有标记的文本、输出(如 feed)或独特的代码创建的列表(如“最推荐”)。当然,也有 hook 来创建、控制、编辑和覆盖区块,尽管大多数区块都是以管理方式构建的。

  • 分类法是可以与内容关联的术语列表。大多数用户都熟悉标签的概念,例如将博客文章与“编码、骑自行车、烹饪或徒步旅行”等术语列表关联。在 Drupal 中,分类法可以为更复杂的用例提供基础,但关联内容是最常见的。

  • Views 模块是一个列表生成器,由一个贡献模块驱动。许多复杂的任务都可以由 Views 处理,但最基本的是,它是创建 Drupal 中内容列表的方式——例如,“最近三个月发布的所有书评”。Views 还可以使用关联显示内容,例如“按分类法术语‘苹果’和‘菠菜’标记的所有帖子,按字母顺序排序”。列表通常是使用 Views 管理界面创建的,但自定义代码可以覆盖输出(hook!),并且整个视图都可以在代码中创建。

Drupal 框架是一个厨房,是的,抽屉里已经有工具,食品储藏室里也有食材。但这些工具和食材并不能定义在那里可以制作的膳食。当将 Drupal 理解为一个框架时,网站所有者、利益相关者、项目经理、业务目标定义者和开发人员团队可以一起烹饪更好的膳食。将 Drupal 视为 CMS 通常意味着强迫它屈服于你的意志:“我想要像我母亲过去做的那样的西葫芦松饼;就做那个。”作为一个框架,Drupal 鼓励在努力范围内创建最好、最优雅的食谱:“这里有一些西葫芦,我们能用它做什么?”

Drupal 的灵活性可能会使回答我们的三个问题(需要多长时间、需要多少钱以及是否可以完成)更耗时。但最终,结果会更加令人满意。

加载 Disqus 评论