是时候给Drupal换个样子了吗?

发布于:2020-12-24 16:05:27

10

72

0

公告 cms drupal php stackoverflow

Drupal 9刚刚发布,开源CMS已接近20年。 对于许多开发人员而言,“ CMS”让人想起2000年代后期的幽灵-十年间,Internet Explorer仍占据浏览器市场份额的65%,尚未提出HTML5规范,Git只是在VCS领域确立了统治地位,而jQuery 是JavaScript库的原作者。 但是,如果这是想到Drupal时脑海中的影像,那么该换个角度了。

房间里的elePHPant

在撰写本文时,我意识到Drupal的臭名昭著的区别是在Stack Overflow的2020年开发人员调查中获得了第二个最令人恐惧的Web框架,而PHP是其编写的基础语言,在该排名中排名第六 可怕的语言列表。

当然,这并不是任何开放源代码社区都会为之骄傲的徽章-那么Drupal 9值得一看的是什么呢?

我们可以仅仅因为Drupal被广泛使用而忽略了这一点,但是我们拥有更好的数据。 对Drupal以及其他开放源代码和专有CMS的情绪调查发现,Drupal的最大负面情绪来自初次使用的用户,但随着平台上用户的专业知识,这种情绪变得越来越积极。 这说明只有专家级别的用户会对使用Drupal的清晰度有积极的印象,并且通常会推荐给其他人。

 

Drupal社区在受调查的开发人员和最终用户中确定了一些推动这一观点的关键领域:易用性和总拥有成本(尤其是困难的主要版本升级)。改善初学者体验(针对开发人员,贡献者和最终用户)。

让我们看一下Drupal项目如何解决这些初学者和中级用户的问题,然后看一下使学习曲线对专家级用户有价值的基本功能。

即使这种探索并不能说服您在下一个Web开发项目中使用Drupal,但管理成熟的开源项目的经验对于任何开源社区的贡献者来说都应该是有价值的。

让我们开始吧。

轻松升级

在多年的开发和新的主要版本中,关于管理大型软件项目存在两种思想流派:

一、项目可以选择将向后兼容性作为优先重点。以WordPress为例,“力争永不向后兼容”,目标是“用户无需担心就可以轻松更新”。

1.优点:对后向兼容性的高度关注对初学者非常友好。对于管理更大规模部署的更高级的用户或工程团队,这种精神可以使保持最新状态的任务不再那么艰巨。

2.缺点:在这种极端情况下保持向后兼容性会导致大量代码库崩溃,导致执行相同功能的API数组混乱,并阻止采用新的最佳实践或技术。

二、项目可以选择专注于最新的体系结构创新和最佳实践,以牺牲主要版本之间的完全不兼容为代价。

1.优点:该项目可以采用最新的技术标准和创新,并根据从先前版本的多年经验中学到的所有经验来重写技术。可以删除旧版代码,并为新功能保留贡献者时间,而将重点放在兼容性上。

 2.缺点:主要版本之间的任何升级实际上都是完整的平台重组。从一个版本转移到另一个版本的数据必须迁移,而不是就地更新。用户群必须在主要版本之间重新学习平台。

从最初的版本到版本7,Drupal遵循后一种开发理念,牺牲了向后兼容性和易于更新的特性,以重塑架构以与最新标准和创新保持同步。

从Drupal 8开始,该项目对开发哲学进行了根本性的转变,以桥接这两种哲学:采用语义版本控制(SemVer)和严格的弃用策略。 SemVer仍然被许多开发人员广泛误解,因此值得重申一下它的含义:

一、SemVer版本架构为:MAJOR.MINOR.PATCH,其中三个版本组件中的每个组件(自然)具有语义:

       1.任何不兼容的API更改都必须增加MAJOR版本。

       2.以向后兼容的方式添加新功能需要增加MINOR版本。

       3.向后兼容的错误修复程序并不会从根本上改变功能,因此会增加PATCH版本。

二、通过采用SemVer与精心设计的弃用策略相结合,Drupal试图将这两种理念之间的差异进行划分

       1.优点:Drupal现在可以维护一个明确的向后兼容性窗口,以实现更可预测的升级,同时可以持续采用新技术和最佳实践。

       2.缺点:软件开发人员不是完美的逻辑学家,有时在构成向后兼容的突破性变化方面存在主观性或模糊性。人为错误有时可能意味着向后兼容承诺在补丁程序或次要发行版中被出卖。

改善初学者体验

改善初学者的体验是一项比较主观的工作,由于要考虑许多角色,因此更加复杂。

一、开发人员:以Drupal为框架。

二、Site Builders:在管理界面的无代码上下文中组装和配置模块以及自定义结构组件(如内容类型)。

三、最终用户:内容编辑者,通常是开发人员为其构建体验的组成部分。

我们将保留最终用户体验,以检查Drupal的功能,因为这种体验的质量在很大程度上取决于开发团队和创建该体验的网站建设者的特定实施方式。 Drupal并非开箱即用,因此针对不同用例和环境的配置看起来可能有很大不同。但是,我们将重点介绍一些结构性功能,这些功能使Drupal开发人员有能力构建这些体验。

让我们来看看Drupal通过2020年内容管理系统应提供的功能为开发人员和网站建设者提供的功能。

今天的内容管理与十年前不同

 

如今,内容管理的问题空间与十年前大不相同。十年前,大多数实现仍集中在基础知识上:提供一个既可以充当编辑内容存储又可以充当显示层的整体框架-通常采用一种结合在一起的方法来使用第三方模块和主题。

既定的CMS项目已广泛分享了对CMS应具有的早期了解,近年来,Wix.com,Squarespace等廉价专有服务已将其商品化。

现代内容管理系统必须提供更强大的功能:

一、一个结构化的数据引擎,提供丰富的元数据,并使内容可用作可重用的组件。

二、结构化数据构成使现代CMS变得强大的所有其他功能的基础。当数据本身被构造为原子成分时,可以将其发布到不同的端点或显示中,无论是博客的直接RSS提要还是GraphQL查询的结构化响应。

三、健壮的API,通过API提供的功能与管理UI中提供的功能之间具有完全的功能奇偶校验。

以编程方式公开CMS的功能是实现超越传统网页的数字体验的基础:这些API可以实现无头或分离的体验,其中CMS管理数据,但用于显示数据的一个或多个端点是单独构建的前端应用程序。

编辑和工作流工具,以及强大的角色和权限管理,以支持将填充平台的内容编辑器。

为什么不简单地构建自己的MEA / RN堆栈,并负责直接构建数据库中的数据并在React或Vue.js之类的框架中构建完整的应用程序呢?

如果您的用例定义明确,不太可能更改,并且管理内容的人员很少,那么这可能是一个很好的解决方案。但是,一旦您需要定义更复杂的编辑工作流程并使用角色和权限来执行它们,使用像Drupal这样的CMS可以节省大量的开发时间。

在任何规模较大的用例中,以可复制和/或版本控制的方式管理依赖关系(即第三方库)和网站配置(即定义的角色和权限)都是至关重要的。

可以在“首次内容丰富的绘画”(或更新的指标,例如“最大内容丰富的绘画”)之前的很短时间内与以应用程序为中心的体验竞争的性能。

开放网络的生存威胁之一是,封闭的基于应用程序的体验会提供比我们以往在网络上更出色的性能和响应速度的用户体验。但这是可以克服的挑战。

Drupal代表现代CMS的地方

定义了现代CMS的要求之后,让我们看一下Drupal如何处理每种内容。Drupal的核心优势一直是其作为结构化数据引擎的力量。

很简单,实体是Drupal中内容的基本单位。 实体包括以下内容:节点(Drupal的通用内容项),注释,用户,块,分类术语等。

字段表示存储在实体内的数据。 任何单个字段都可以保存一种数据:纯文本,格式化文本,图像,其他文件,日期等。

开发人员还可以定义自己的实体。 此示例显示了一个名为Event的新实体的定义,该实体可用于存储有关Drupal聚会的结构化数据,以及ID和Universally Unique Identifier的一些基本字段的定义。

 

<?php

 

namespace DrupaleventEntity;

 

use DrupalCoreEntityContentEntityBase;

use DrupalCoreFieldBaseFieldDefinition;

use DrupalCoreEntityEntityTypeInterface;

use DrupalCoreEntityContentEntityInterface;

 

/**

 * Defines the event entity.

 *

 * @ingroup event

 *

 * @ContentEntityType(

 *   id = "event",

 *   label = @Translation("event"),

 *   base_table = "event",

 *   entity_keys = {

 *     "id" = "id",

 *     "uuid" = "uuid",

 *   },

 * )

 */

 

class Event extends ContentEntityBase implements ContentEntityInterface {

 

  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {

 

    // Standard field, used as unique if primary index.

    $fields['id'] = BaseFieldDefinition::create('integer')

      ->setLabel(t('ID'))

      ->setDescription(t('The ID of the Event entity.'))

      ->setReadOnly(TRUE);

 

    // Standard field, unique outside of the scope of the current project.

    $fields['uuid'] = BaseFieldDefinition::create('uuid')

      ->setLabel(t('UUID'))

      ->setDescription(t('The UUID of the Event entity.'))

      ->setReadOnly(TRUE);

 

    return $fields;

  }

}

?>

 

因为实体和字段在架构上是Drupal的核心,所以它们干净地继承了Drupal提供的所有功能-在Drupal的API中自动可用,可修改和可转换,受中央角色和权限系统的访问控制,并且至关重要的是, Drupal的结构化查询构建器视图。

什么是视图?

从概念上讲,视图是Drupal的核心组件,它使您可以从数据库中获取内容并将其结构化为提要或显示。

这与仅编写SQL查询有何区别? 除了简单地查询结构化数据外,View还继承了Drupal的所有其他功能,使您可以定义多个显示,使查询参数与上下文相关,以及使用Drupal的核心角色和权限系统来实施访问控制。

虽然可以通过Drupal管理界面中的Views UI来管理所有这些功能,但是对于更细粒度的控件,可以在代码中定义Views。

视图功能的一个例子

假设我们的Drupal实例存储了体育统计数据。 也许我们已经建立了一种典型的网站体验,用户可以浏览这些统计信息,但是我们的实例还向安装在体育馆中的数字信息亭提供内容。 该信息亭不能在Drupal上运行,而是使用RESTful Web服务查询我们的Drupal网站以获取有关使用该信息亭点击的体育迷队伍的统计信息。

我们可以在我们的Drupal站点中定义运动队实体的视图,该视图收集所有包含服务亭可能要求的团队统计信息的字段。

然后,我们可以使用信息亭将调用的REST导出路径配置Views输出,并选择是否将输出序列化为XML或JSON。

请注意,除了信息亭可以使用哪种输出格式外,我们对信息亭的构建方式一无所知。

当跨通道和端点显示结构化内容时,Drupal中的视图可以节省大量开发时间。

健壮的内容展示API

Drupal 9是使用API优先开发方法构建的。这意味着Drupal的所有应用程序功能都可以作为API使用,并且可以通过Drupal的RESTful Web服务和JSON:API来使用Drupal中存储的所有结构化数据。可通过贡献的模块获得对其他API扩展(例如GraphQL)的支持。至关重要的是,这些API尊重所有其他Drupal核心功能,例如修订,权限管理等。

我们在上面讨论了Views,它是Drupal的核心组件,可启用CMS的“一次编写,随处发布”功能。传统上,它是用来在Drupal自己的表示层中创建结构化数据的灵活显示,但我们在上面的示例中已经表明,它还可以创建API端点,以允许在解耦的前端应用程序中使用和显示内容。

以这种方式使用Drupal的情况越来越普遍。消耗来自解耦的Drupal安装中的数据的前端应用程序通常是在Node.js,React,Vue.js,Gatsby和类似框架中构建的。

是将Drupal用作独立的,“耦合的”应用程序,还是使用多种分离的选项,这取决于项目的编辑和开发需求。

编辑和工作流程工具

内容管理系统的作用仅在于其使内容编辑者能够执行其工作的能力,并且以Drupal为基础的开发团队通常被赋予对编辑功能的特定要求,编辑人员应能够在不涉及开发人员的情况下使用这些功能。在Drupal 9中,有一些用于定义编辑工作流程的结构性工具。

工作区使您可以为编辑工作流定义内容暂存环境,预览多个内容更改,然后可以将其同时部署到公共环境。

在单个内容类型中,您可以为内容定义状态,这些内容可以具有自己的属性,控制有权查看或编辑内容的人员,更改默认修订版等。

过渡定义了用户可以放置内容的可允许状态更改,并且角色和权限还可以进一步限制这些更改。

可以通过Drupal的配置管理系统来导入/导出工作区和工作流程配置,并对其版本进行控制,下面将对其进行描述,从而大大简化了在一系列安装中管理这些编辑工作流的任务。

例如,如果开发人员的任务是为整个编辑套件中的多个编辑团队的编辑工作流程添加新的内容批准步骤,每个编辑团队都在各自的代码库实例上,则可以在单个环境中创建配置,然后导出,然后导入到所有其他环境中。

依赖性和配置管理

Composer是PHP生态系统的依赖管理工具,与JavaScript生态系统的npm或Yarn相当。 Drupal 8首先引入了对基于Composer的依赖性管理的支持,但是对于Drupal 9,它成为管理Drupal安装的首选方法。 Drupal.org的发布打包系统可确保无论是在命令行上启动Drupal项目还是通过下载.tar.gz,该项目都可以使用Composer。

使用Composer启动Drupal项目非常简单。一旦有了满足系统要求的开发环境(通常是标准LAMP堆栈),就可以使用推荐的Composer模板安装Drupal:


 

$ composer create-project drupal/recommended-project my_site_name_dir

遵循适当的版本约束语法,可以使用composer require命令将其他Drupal模块或主题添加到您的安装中。

例如,如果您想要添加令牌模块(提供用于将动态生成的值插入内容的扩展选项)以及GraphQL模块(因为您的内容正被另一个前端应用程序使用),则可以添加这些模块使用以下命令到您的项目:


 

$ composer require 'drupal/token'
       $ composer require 'drupal/graphql'

使用其他依赖性管理工具的开发人员应该熟悉这种常规工作流程。

配置管理

Drupal对所有站点配置使用标准格式,无论是Drupal核心组件的配置还是已安装的模块。 这意味着Drupal配置可以作为YAML导出和导入,这允许分阶段进行配置更改,在站点之间部署配置以及轻松的版本控制。

在配置管理UI中,您可以查看活动(数据库中)配置以及当前可用的暂存(YAML中)配置。 可以导出活动配置以覆盖当前的暂存配置,或者可以将活动配置还原为暂存YAML中的设置。

如上所述,Drupal的任何自定义扩展都可以定义自己的配置。 配置YAML的模式非常简单:

 

 

# /modules/example/config/schema/example.schema.yml

example.settings:

  type: config_object

  label: 'Example config'

  mapping:

    message:

      type: text

      label: 'Message'

 

作为开发人员,这种导出和导入配置以及通过版本控制进行管理的功能使站点配置更易于控制,可审核,并且更易于从登台环境部署到生产环境。

性能和可扩展性

要与壁挂式移动应用程序近乎即时的响应能力竞争,就意味着要高度重视现代性能和渲染技术。

Drupal包括一个不需要配置的动态页面缓存,它使用页面上每个呈现项目的声明性缓存上下文来确定是否可以缓存该项目。 这意味着,无论用户是匿名的还是经过身份验证的,甚至具有动态,个性化内容的页面都可以部分或全部进行缓存。

这样做的关键是检测哪些页面内容可以缓存,哪些不应该缓存。 检测页面的高动态元素(即,较差的缓存候选对象)以便以后可以呈现的过程称为自动占位符。

默认情况下,Drupal将在渲染器配置中对符合以下条件的元素执行自动占位:

 

renderer.config:

    auto_placeholder_conditions:

      max-age: 0

      contexts: ['session', 'user']

      tags: []

 

这些条件可以针对您的特定用例进行扩展。 举例来说,如果您想消除对与用户或当前会话无关的动态内容的缓存(也许是实时活动的可视化),则可以定义一个新的缓存上下文,将其称为“ dataviz”。 给定上下文的内容将通过自动占位符而不是缓存进行处理。


 

-       contexts: ['session', 'user']
  +      contexts: ['session', 'user', 'dataviz']

同样,您可能想做相反的事情:为Drupal默认情况下通常不会缓存的内容定义一个缓存上下文。 例如,如果您的内容与用户实体相关,但是在很大程度上是不可变的,则可以为它提供一个新的缓存上下文,以对该内容实施缓存,而不必缓存可能根据用户上下文而动态变化的所有其他内容 。

Drupal还包括BigPipe核心模块,BigPipe核心模块是当今最先进的页面渲染优化技术,最早由Facebook提出并实施。 此技术建立在上述缓存上下文和自动占位符的基础上,以允许页面以早期刷新的方式呈现(在整个页面就绪之前将初始内容发送到浏览器),然后在占位符内容中进行流式传输。

与最大的内容丰富的涂料相比,这是一个巨大的改进时间。 尽管可以扩展BigPipe功能,但默认情况下它无需启用其他配置即可启用它。

丰富和触及

CMS生态系统中技术复杂程度的提高同时增加了数字体验的丰富性,也增加了构建和维护这些系统的复杂性。 这改变了Drupal的目标。

在Drupal社区中,我们说Drupal是雄心勃勃的数字体验。 这不仅是衡量大小的方法,甚至不是主要衡量标准的方法,而是衡量网络体验整合上面我们探讨的这些现代内容管理概念所需的程度的方法。

经Drupal创始人Dries Buytaert许可使用的图形。

像Drupal这样的强大CMS的目的不再是在构建博客,投资组合网站或小册子软件时,而且希望在进行这种探索之后,当您想到CMS生态系统时,这不再是我要想到的。 相反,如果我们在这里探索的现代功能与您的用例产生了共鸣,那么现在该让Drupal 9焕然一新了。

快速开始

如果您具有LAMP开发环境,则可以使用Composer和PHP快速探索一个快速入门的Drupal环境:


 

$ composer create-project drupal/recommended-project try9
$ php try9/web/core/scripts/drupal quick-start demo_umami

要了解有关Drupal的更多信息,请浏览Drupal项目的文档,考虑在线或在您所在地区加入Drupal社区,或在DrupalCon上查看我们。