Drupal 11:使用 SDC 组件库预览单目录组件
单目录组件(SDC)由一组文件构成,它们共同在 Drupal 网站上创建一个小的组件。SDC 可以相互嵌套,也就是说,我们能够创建一组一致的元素,并将它们组合运用到网站中。
SDC 的强大之处在于它的自包含性。要是你需要构建一个在小部件中显示数据的复杂组件,将其构建为 SDC 就意味着每次包含它时,都会显示相同的小部件。
我们可以在不先将 SDC 添加到模板的情况下,把它添加到你的 Drupal 网站。在构建 SDC 时,你可以利用 SDC 组件库模块来预览它们,等准备好后再将其集成到网站里。
本文或多或少是对文章 使用 Storybook 预览单目录组件 的重新创作,不过重点围绕 SDC 组件库模块。所以,会存在一些重复内容,但每篇文章都是独立的,你无需在页面之间来回跳转。
在本文中,我们将介绍如何使用 SDC 设置一个主题,接着使用 SDC 组件库模块预览该组件。
一、创建单目录组件
要在 SDC 组件库中预览 SDC,我们首先得创建一个 SDC,在本文的后续部分将以此为例。假设你有一个自定义主题,可在其中构建 SDC。
这里我们不会深入探讨 SDC,因为这可能是一个很大的主题,所以我们只创建所需的元素。如果你需要更多信息,官方的 Drupal SDC 文档 实际上非常有用。还有一本 Drupal 10 主题开发书籍,其中有关于在 Drupal 中构建和使用 SDC 的全面指南。
在这个例子中,我将创建一个简单的作者组件,用于显示文章作者的姓名、简介和头像。以下是该组件正常运行所需的文件。
author.component.yml 文件将作者 URL 定义为一个属性,并设置了几个插槽来传递姓名、简介和头像信息。
name: Author
description: "Display author information"
props:
type: object
properties:
author_url:
type: string
title: Author URL
examples:
- /author/philipnorton42
slots:
name:
title: "Name"
bio:
title: "Bio"
avatar:
title: "Avatar"
关于 props 和 slots 的区别有很多相关内容,但在这个例子中,props 仅用于作者的 URL,而 slots 用于其他所有内容。我们需要将头像和简介作为插槽传递,因为这些内容可能包含 HTML 甚至是可渲染的项目。
在主 author.twig 文件中,我们创建了一些简单的标记,并添加了 author.component.yml 文件中定义的属性。这里的块很重要,但只有在为 SDC 组件库模块设置故事时它们才会发挥作用,我们将在文章后面介绍。
<aside class="author">
<div>
{% block avatar %}
{{ avatar }}
{% endblock %}
</div>
<div class="author_bio">
<p>
<a href="{{ author_url }}" rel="bookmark">
<span>{{ name }}</span>
</a>
</p>
{% block bio %}
{{ bio }}
{% endblock %}
</div>
</aside>
作者组件的 CSS 文件存储在 author.css 中,相对简单。它只是创建了一个带有阴影的区域和一个包含左右两部分的弹性容器。
aside.author {
clear: both;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 10%), 0 4px 6px -2px rgba(0, 0, 0, 10%);
padding: 1rem;
margin-bottom: 2rem;
margin-top: 2rem;
display: flex;
}
aside.author:first-child {
width: 20%;
text-align: center;
}
aside.author:first-child img {
max-width: 100%;
height: auto;
}
aside.author:last-child {
width: 80%;
}
div.author_bio {
margin-left: 1rem;
}
div.author_bio p {
margin-top: 0;
}
这三个文件都位于一个名为 author 的目录中,该目录位于一个名为 my_theme 的主题中。
二、安装 SDC 组件模块
使用 Composer 以常规方式安装该模块。
composer require drupal/sdc_component_library
在撰写本文时,该模块只有 Beta 版本,这意味着在安装之前,你可能需要放宽 composer.json 文件中的要求。可以通过将 minimum-stability 设置为 “beta” 来实现。
"minimum-stability": "beta",
模块激活后,你可以访问 /components 路径来查看组件库。目前该页面没有菜单选项,所以你需要手动访问该路径。你还需要为任何需要访问此页面的角色添加 access sdc component library 权限。
此页面将扫描你当前活动的主题以查找组件,然后将这些组件显示在该界面中。你需要配置每个组件才能在该界面中显示,因此库会为所有组件显示错误消息。
如果你正在积极开发组件,打开 Twig 调试模式也是个好主意。
drush state:set twig_debug 1
drush state:set twig_cache_disable 1
drush state:set disable_rendered_output_cache_bins 1
现在,我们需要为每个要预览的组件创建一个 <组件名称>.story.twig 文件。模块需要这个文件来显示包含一些数据的组件。故事文件的结构非常简单,它包含了你将组件添加到网站所需的设置。
对于只需要几个 props 值的简单组件,你可以使用 embed 标签来包含组件并注入你的值。
{% embed 'my_theme:componentName' with {a_property: 'A value'} %}
{% endembed %}
对于具有 slots 的更复杂组件,你可以使用 set 标签设置插槽的值,然后使用 include 标签将组件注入到你的故事中。使用这种机制意味着我们可以在故事中向组件注入标记数据,而无需在组件模板中使用原始过滤器。
{% set some_slot %}
<p>Some prop that contains markup.</p>
{% endset %}
{{ include('my_theme:componentName', {
some_slot
}) }}
对于上面的作者示例,由于组件名称是 author,我们将创建一个名为 author.story.twig 的文件。然后,因为我们需要将 HTML 传递给模板,所以需要使用 embed Twig 标签。这就是 Twig block 标签发挥作用的地方。为了将故事中的值传递给组件,我们需要覆盖组件中的块,并将参数以原始形式注入到模板中。这使我们可以在故事中使用 HTML,而无需在模板本身中添加原始输出,这可能不安全。
{% set bio %}
<p>Phil is the founder and administrator of <a href="https://www.hashbangcode.com">#! code</a> and is an IT professional working in the North West of the UK.</p>
{% endset %}
{% set avatar %}
<img loading="lazy" src="https://picsum.photos/id/237/480/480" width="480" height="480" alt="Test image" class="image-style-large">
{% endset %}
{% include 'my_theme:author' with {
author_url: '/author/philipnorton42',
name: 'Phil Norton',
bio: bio,
avatar: avatar
} only %}
有了这个文件后,我们可以返回 /components 页面,查看组件的实际效果。
SDC 组件库模块将包含组件中的任何额外样式或 JavaScript 文件,因此你的组件应该与添加到主题中时的表现完全一致。
请注意,组件库是使用当前活动的主题渲染的,因此所有常规的 Drupal 样式也会注入到页面中。
三、添加多个故事
现在我们已经为组件创建了一个故事,我们可以在此基础上进行扩展,在单个故事文件中创建多个故事。在创建组件时,这样做很重要,因为不同的属性和标记可能会导致组件以不同的方式运行。为了正确测试组件,必须添加包含不同数据的组件示例。
通过在同一个故事 Twig 文件中添加多个故事,使用 SDC 组件库模块可以实现这一点。
{# 第一个故事 #}
{% set bio %}
<p>Phil is the founder and administrator of <a href="https://www.hashbangcode.com">#! code</a> and is an IT professional working in the North West of the UK.</p>
{% endset %}
{% set avatar %}
<img loading="lazy" src="https://picsum.photos/id/237/480/480" width="480" height="480" alt="Phil Nortons profile image" class="image-style-large">
{% endset %}
{% include 'my_theme:author' with {
author_url: '/author/philipnorton42',
name: 'Phil Norton',
bio: bio,
avatar: avatar
} only %}
{# 第二个故事 #}
{% set bio %}
<p>Testing is a non-entity used for testing purposes.<br><br><br>Please<br>take<br>care<br>of<br>this<br>non-entity.</p>
{% endset %}
{% set avatar %}{% endset %}
{% include 'my_theme:author' with {
author_url: '/author/testing',
name: 'Testing Testerson',
bio: bio,
avatar: avatar
} only %}
将此内容添加到 author.story.twig 文件中并重新加载页面,将产生以下输出。
这里有一个警告,组件是在同一个模板中依次渲染的,因此你 可能 会看到组件之间相互影响的问题。如果发生这种情况,说明你的组件隔离性不够,你应该努力纠正这一点。然而,这也可以显示出在页面上仅显示一次组件时通常不会遇到的可访问性问题,因此这样做有一些好处。
四、结论
现在我们已经在 Storybook 中预览了作者组件并检查其正常工作,我们可以将其添加到我们的主题中。我一开始创建的作者组件现在在主题中以以下方式使用(在作者最小视图模式模板中)。
{{ include('hashbangcode_theme:author', {
author_url: url,
name: label,
bio: content.field_author_short_bio,
avatar: content.field_author_avatar
}) }}
如果你打算使用单目录组件进行构建,那么你应该使用 SDC 组件库模块或 Storybook,正如我在 上一篇文章 中所讨论的那样。
能够在 Drupal 主题中快速预览组件是一个非常强大的工具。此外,与 Storybook 不同,使用该模块无需为组件进行任何设置或其他配置。你只需要该模块、查看 SDC 组件库页面的权限以及每个组件的相关故事文件。无需摆弄 CORS 设置或分割部署以防止这些规则影响你的生产站点。
通过激活该模块,你可以直接在网站内预览组件。只需确保正确设置权限,以免允许匿名查看该页面。允许匿名访问该页面不是一个严重的安全问题,但可能会在搜索结果中造成问题(如果被索引),或者泄露不应公开的网站信息,例如即将推出的页面的组件。
内置的可访问性扫描器是一个非常不错的功能,肯定有助于解决组件中的任何简单可访问性问题。当在同一个 <组件名称>.story.twig 文件中添加多个组件时它可能会有点混乱,但我认为它在这种设置中发现的问题在实时网站上仍然会出现。
我之前提到过,该模块会在每个活动主题中查找组件,这可能会导致其他主题中的组件显示在你当前活动的主题中。如果你有包含组件的活动主题,但不希望它们显示,这可能会有点烦人。在发现过程中,没有钩子或其他触发器可以拦截。
这是一个非常好的模块,如果你不想使用 Storybook,它应该成为你 Drupal 开发工作流程的一部分。然而,我认为 Storybook 相对于该模块有几个优势,包括能够通过界面实时操作组件。通过界面更改内容意味着你可以使用不同的设置测试组件,这是使用 Storybook 的一个关键特性。


