Bento

如何使用 Bento 创建 WordPress Gutenberg 区块

在本指南中,我们将解释为什么 Bento 组件非常适合创建 Gutenberg 区块,以及它的工作原理。

Gutenberg 是基于 React 的区块编辑器,为 WordPress 提供支持。除了 Gutenberg 中原生提供的核心区块外,开发人员还可以创建自定义区块以在编辑器中使用。通常,使用 Gutenberg 时,你必须实现两次相同的功能,首先在 React 中创建区块的编辑组件,然后为前端重新实现相同的外观和感觉,但不用 React。这会导致大量重复工作和额外的维护负担,甚至可能导致两个版本之间存在一些差异。

这就是 Bento 发挥作用的地方。

Bento 提供经过充分测试的、跨浏览器兼容且可访问的 Web 组件(又称自定义元素),可在任何网站上使用。它们性能极佳,有助于提供出色的页面体验。Bento 组件不仅可用作自定义元素,还可用作具有相同功能和 API 的 React 和 Preact 组件。这使得它们成为在 Gutenberg 中使用的理想选择。

在本指南中,你将学习如何创建一个由 Bento 提供支持的 Gutenberg 区块,该区块使用 Bento 走马灯组件。你也可以跳过此部分,直接跳转到包含最终代码的 GitHub 存储库

构建 Bento Gutenberg 区块

对于本指南,我们将使用 @wordpress/create-block,这是创建 WordPress 插件注册自定义块的官方支持方式。它会生成 PHP、JS、CSS 代码,以及启动项目所需的一切。你可以将它视为 Gutenberg 块的 create-react-app

让我们通过创建一个名为 awesome-carousel 的新插件来开始。为此,请在 wp-content/plugins 文件夹中运行以下命令

$ npx @wordpress/create-block awesome-carousel
$ cd awesome-carousel
$ npm start

之后,你可以转到 WordPress 管理员并立即激活新创建的 awesome-carousel 插件!

结果是一个简单的块,它已经可以插入到块编辑器中

Block Editor

创建编辑组件

接下来,让我们从 npm 安装 @bentoproject/base-carousel 包。与所有 Bento 组件一样,这个基本轮播组件可从 npm 获得,并包含 Web 组件、任何必需的 CSS 文件,以及 Preact 和 React 版本。

我们现在只对 React 版本和 CSS 感兴趣,因此在块目录中运行以下命令

$ npm install --save @bentoproject/base-carousel

之后,可以在 src/edit.js 中导入组件,其中包含块的编辑组件。

import {BentoBaseCarousel} from '@bentoproject/base-carousel/react';
import '@bentoproject/base-carousel/styles.css';

注意:看到 styles.css 导入了吗?感谢 @wordpress/create-block,此 CSS 文件将自动为我们加载到编辑器中。

接下来,让我们渲染 BentoBaseCarousel React 组件并与之交互。出于本指南的目的,我们将显示一组预定义的图像,并渲染自定义按钮以转到轮播中的下一张/上一张幻灯片。

渲染基本轮播组件与任何其他 React 组件的工作方式相同。它支持的 所有属性 都可以作为道具传递。

让我们相应地更新我们的编辑组件

export default function Edit() {
return (
<div {...useBlockProps()}>
<div className="awesome-carousel-wrapper">
<BentoBaseCarousel autoAdvance={false} loop={false} snap={true}>
<img
src="https://source.unsplash.com/random/1200x800?1"
width={1200}
height={800}
alt=""
/>

<img
src="https://source.unsplash.com/random/1200x800?2"
width={1200}
height={800}
alt=""
/>

<img
src="https://source.unsplash.com/random/1200x800?3"
width={1200}
height={800}
alt=""
/>

<img
src="https://source.unsplash.com/random/1200x800?4"
width={1200}
height={800}
alt=""
/>

</BentoBaseCarousel>
</div>
</div>
);
}

我们还将在 src/style.scss 文件中添加以下 CSS 来设置轮播的尺寸。它将自动应用于网站的前端以及编辑器中,非常方便!

.wp-block-create-block-awesome-carousel .awesome-carousel-wrapper,
.wp-block-create-block-awesome-carousel .awesome-carousel-wrapper > *
{
aspect-ratio: 1200/800;
}

注意:仅在 CSS 选择器中使用类名。bento-base-carousel 标签名仅在前端组件中用作自定义元素的一部分(见下文),而在 React 编辑器上下文中将使用 div 代替。

结果是在块编辑器中完全可用的轮播,不受其他组件或插件的样式干扰

Carousel inside Gutenberg

当然,理想情况下,用户可以编辑图像并将其存储为属性。您可以在 块编辑器手册 中了解更多相关信息。

添加交互性

Bento 组件通过其 API 具有很强的交互性。可以通过传递引用来访问 BentoBaseCarousel 组件 API

import {createRef} from '@wordpress/element';

// …

function Edit() {
const ref = createRef();
return <BentoBaseCarousel ref={ref}>{/* … */}</BentoBaseCarousel>;
}

然后,我们可以渲染两个自定义按钮来处理上一个/下一个导航

import { Button } from '@wordpress/components';

// …

const goToNextSlide = () => ref.current.next();
const goToPreviousSlide = () => ref.current.prev();

// …
<Button isSecondary onClick={goToPreviousSlide}>{'Previous'}</Button>
<Button isSecondary onClick={goToNextSlide}>{'Next'}</Button>

就是这样!结果如下所示

Carousel with controls

处理好编辑组件后,让我们将重点转移到块的 save 函数,该函数负责生成前端输出。这是我们将使用 <bento-base-carousel> Web 组件的地方。

创建前端组件

对于前端,我们将实现与在编辑组件中构建的类似体验:一个带有两个自定义按钮的简单轮播,以便与之交互。

save 函数本身非常简单,仅负责打印 Web 组件标记。它在 src/save.js 中定义。

export default function save() {
// …

return (
<div {...useBlockProps.save()}>
<div className="awesome-carousel-wrapper">
<bento-base-carousel auto-advance="false" loop="false" snap="true">
<img
src="https://source.unsplash.com/random/1200x800?1"
width={1200}
height={800}
alt=""
/>

<img
src="https://source.unsplash.com/random/1200x800?2"
width={1200}
height={800}
alt=""
/>

<img
src="https://source.unsplash.com/random/1200x800?3"
width={1200}
height={800}
alt=""
/>

<img
src="https://source.unsplash.com/random/1200x800?4"
width={1200}
height={800}
alt=""
/>

</bento-base-carousel>
</div>
<div className="awesome-carousel-buttons">
<button className="awesome-carousel-prev">{'Previous'}</button>
<button className="awesome-carousel-next">{'Next'}</button>
</div>
</div>
);
}

为了定义和设置 Web 组件的样式,我们还需要从 CDN 加载 Bento JavaScript 和 CSS。为此,我们需要切换到 PHP 来注册这些资源。让我们将以下代码添加到 awesome-carousel.php

/**
* Registers the scripts and styles for Bento components.
*
* @return void
*/

function create_block_awesome_carousel_register_assets() {
wp_register_script( 'bento-runtime', 'https://cdn.ampproject.org/bento.js', array(), false, true );
wp_register_script( 'bento-base-carousel', 'https://cdn.ampproject.org/v0/bento-base-carousel-1.0.js', array( 'bento-runtime' ), false, true );
wp_register_style( 'bento-base-carousel', 'https://cdn.ampproject.org/v0/bento-base-carousel-1.0.css', array() );

wp_register_script( 'awesome-carousel-view', plugin_dir_url( __FILE__ ) . 'build/view.js', array( 'bento-base-carousel' ) );
}

add_action( 'init', 'create_block_awesome_carousel_register_assets' );

如您所见,这也注册了一个自定义 awesome-carousel-view 脚本,我们可以在其中放置任何仅限前端的交互性。

值得注意的是,这只是在 WordPress 中注册 JS 和 CSS,但不会排队(加载)它。我们只希望在块实际呈现在前端时执行此操作,以避免加载不必要的脚本。可以使用块的渲染回调来实现此目的,我们可以通过在 awesome-carousel.php 中更新 create_block_awesome_carousel_block_init 来配置该回调,如下所示

/**
* Registers the block using the metadata loaded from the `block.json` file.
* Behind the scenes, it registers also all assets so they can be enqueued
* through the block editor in the corresponding context.
*
* @see https://developer.wordpress.org/block-editor/tutorials/block-tutorial/writing-your-first-block-type/
*/

function create_block_awesome_carousel_block_init() {
register_block_type(
__DIR__,
array(
'render_callback' => 'create_block_awesome_carousel_render_block',
)
);
}

add_action( 'init', 'create_block_awesome_carousel_block_init' );

/**
* Render callback for the carousel block.
*
* @param array $attributes Block attributes.
* @param string $content Block content.
*
* @return string Block content.
*/

function create_block_awesome_carousel_render_block( $attributes, $content ) {
if ( ! is_admin() ) {
wp_enqueue_script( 'awesome-carousel-view' );
wp_enqueue_style( 'bento-base-carousel' );
}

return $content;
}

注意:当添加对专用 viewScript 的支持时,这将在未来变得更容易,从而无需自定义渲染回调。

现在,唯一剩下的任务是在前端也让那些上一个/下一个按钮工作。

添加交互性

bento-base-carousel 组件 API 的访问方式与 React 版本类似,它让我们能够为这些按钮添加交互性。

要使用它,我们首先需要等待自定义元素被定义

await customElements.whenDefined('bento-base-carousel');

然后,我们可以这样访问 API

const carousel = document.querySelector('bento-base-carousel');
const api = await carousel.getApi();

然后,我们可以使用它来监听自定义按钮上的点击,以自行控制轮播。最终代码如下,可以放入新的 src/view.js 文件中

(async () => {
await window.customElements.whenDefined('bento-base-carousel');

const carousels = document.querySelectorAll(
'.wp-block-create-block-awesome-carousel'
);

for (const carousel of carousels) {
const bentoComponent = carousel.querySelector('bento-base-carousel');
const api = await bentoComponent.getApi();

carousel
.querySelector('.awesome-carousel-prev')
.addEventListener('click', () => {
api.prev();
});
carousel
.querySelector('.awesome-carousel-next')
.addEventListener('click', () => {
api.next();
});
}
})();

现在,为了让我们的设置识别这个新的 src/view.js 文件,我们需要稍微更新一下 package.json 配置文件,特别是 scripts 部分

{
"scripts": {
"build": "wp-scripts build src/index.js src/view.js",
"start": "wp-scripts start src/index.js src/view.js",
"packages-update": "wp-scripts packages-update"
}
}

之后,我们可以再次运行 npm run start 来构建我们的脚本。

就是这样!结果如下所示

Finished carousel

摘要

在本指南中,我们现在已经使用 Bento Carousel 组件成功创建了一个 Gutenberg 块。该块在编辑器中使用组件的 React 版本,在前端使用自定义元素,并添加了自定义按钮以展示 Bento 组件的 API 实际运行情况。

如果您想看到所有部分的组合,您可以在 GitHub 上找到完整的代码

提示:还有一个第二个 更高级版本,它展示了如何在 AMP 优先的 WordPress 网站上使用 Bento 驱动的 Gutenberg 块,以及如何自托管 Bento JS/CSS,而不是使用 CDN。

更多详情