文本是《WordPress Gutenberg Block API(共6篇)》专题的第 3 篇。阅读本文前,建议先阅读前面的文章:
新的WordPress编辑器(代号为Gutenberg)将于5.0版本发布。现在是在它进入WordPress核心之前掌握它的最佳时机。 在本系列中,我将向您展示如何使用Block API并创建您自己的内容块,您可以使用它们来构建您的帖子和页面。
在上一篇文章中,我们了解了如何使用create-guten-block
工具包创建一个插件,其中包含一个可供我们使用的样本块。我们可以根据需要轻松扩展它,但是知道如何从头开始创建块以充分理解Gutenberg块开发的所有方面是个好主意。
在这篇文章中,我们将在 my-custom-block 插件中创建第二个块,以显示PlaceIMG Web服务中的随机图像。您还可以通过从下拉选择控件中选择图像类别来自定义块。
但首先我们将学习块脚本和样式如何排队引入,然后再转到最重要的registerBlockType()
函数,这对于在Gutenberg中创建块是至关重要的。
排队块脚本和样式
要添加块所需的JavaScript和CSS,我们可以使用Gutenberg提供的两个新的WordPress钩子:
enqueue_block_editor_assets
enqueue_block_assets
这些仅在Gutenberg插件处于活动状态时可用,并且它们以类似于标准WordPress挂钩的方式工作以排队脚本。但是,它们专门用于与Gutenberg块一起使用。
enqueue_block_editor_assets
钩子只在管理编辑界面增加了脚本和样式。这使得它非常适合排队引入JavaScript来注册块和引入CSS来在块设置进行用户界面元素设置。
但是,对于块输出,您希望块在编辑器中的渲染方式与在大多数情况下在前端的渲染相同。 使用enqueue_block_assets
可以轻松实现,因为样式会自动添加到编辑器和前端。如果需要,您还可以使用此钩子加载JavaScript。
但您可能想知道如何仅在前端排队脚本和样式。没有WordPress钩子允许你直接执行此操作,但是你可以通过在enqueue_block_assets
钩子回调函数中添加条件语句来解决这个问题。
add_action( 'enqueue_block_assets', 'load_front_end scripts' );
function load_front_end scripts() {
if( !is_admin() {
// enqueue front end only scripts and styles here
}
}
要使用这两个新钩子来排队脚本和样式,您可以像平常使用wp_enqueue_style()
和wp_enqueue_scripts()
函数一样操作。
但是,您需要确保使用正确的脚本依赖项。要在编辑器上排队脚本,可以使用以下依赖项:
- 脚本:
array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-components' )
- 样式:
array( 'wp-edit-blocks' )
在为编辑器和前端排队样式时,您可以使用此依赖项:
array( 'wp-blocks' )
这里值得一提的是,我们的 my-custom-block 插件排队的实际文件是JavaScript和CSS 的编译版本,而不是包含JSX和Sass源代码的文件。
手动排队文件时,这是要记住的事情。如果您尝试将包含React,ES6 +或Sass的原始源代码排入队列,那么您将遇到许多错误。
这就是为什么使用工具包很有用的原因,例如create-guten-block
它会自动处理和排队脚本!
注册Gutenberg区块
要创建一个新块,我们需要通过调用registerBlockType()
并传入块名称和配置对象来向Gutenberg注册它。此对象具有许多需要正确解释的属性。
首先,让我们来看看块名称。这是第一个参数,是一个由两部分组成的字符串,命名空间和块名称本身,由正斜杠字符分隔。
例如:
registerBlockType(
'block-namespace/block-name',
{
// configuration object
}
);
如果您在插件中注册了几个块,那么您可以使用相同的命名空间来组织所有块。 但是,命名空间必须是插件的唯一名称,这有助于防止命名冲突。如果已经通过另一个插件注册了具有相同名称的块,则会发生这种情况。
第二个registerBlockType()
参数是设置对象,需要指定许多属性:
title
(字符串):在编辑器中显示为可搜索的块标签description
(可选字符串):描述块的用途icon
(可选的Dashicon或JSX元素):与块关联的图标- category (字符串):在“ 添加块” 对话框中块出现的位置
keywords
(可选数组):块搜索中最多使用三个关键词attributes
(可选对象):处理动态块数据edit
(函数):一个返回要在编辑器中呈现的标记的函数save
(函数):一个返回要在前端渲染的标记的函数useOnce
(可选布尔值):限制块被多次添加supports
(可选对象):定义块支持的功能
假设我们使用JSX进行块开发,这是registerBlockType()
一个非常简单的块的示例调用:
registerBlockType(
'my-unique-namespace/ultimate-block',
{
title: __( 'The Best Block Ever', 'domain' ),
icon: 'wordpress',
category: 'common',
keywords: [ __( 'sample', 'domain' ), __( 'Gutenberg', 'domain' ), __( 'block', 'domain' ) ],
edit: () => <h2>Welcome to the Gutenberg Editor!</h2>,
save: () => <h2>How am I looking on the front end?</h2>
}
);
注意,我们并没有包括对一个条目的 description
,attributes
,useOnce
,和supports
属性?可以安全地省略任何可选字段(与块无关)。 例如,由于此块不涉及任何动态数据,因此我们无需担心指定任何属性。
现在让我们逐一详细介绍registerBlockType()
配置对象属性。
标题和说明
在编辑器中插入或搜索块时,标题将显示在可用块列表中。
它也会显示在块检查器窗口中,以及块描述(如果已定义)。如果块检查器当前不可见,那么您可以使用Gutenberg编辑器右上角的齿轮图标来切换可见性。
理想情况下,标题和描述字段都应包含在i18n函数中,以允许翻译成其他语言。
类别
目前有五种块类别:
common
formatting
layout
widgets
embed
这些确定了在“ 添加块” 窗口中列出块的类别部分。
“块” 选项卡包含“公共块”,“ 格式”,“ 布局元素 ”和“ 小工具” 类别,而“ 嵌入” 类别具有自己的选项卡。
目前Gutenberg已修复了类别,但未来可能会有所变化。这将是有用的,例如,如果您在单个插件中开发多个块,并且您希望它们全部列在一个公共类别下,以便用户可以更容易地找到它们。
图标
默认情况下,您的块被分配了盾牌Dashicon,但您可以通过在icon
字段中指定自定义Dashicon来覆盖它。
每个Dashicon都带有前缀,dashicons-
后跟一个唯一的字符串。例如,齿轮图标具有名称dashicons-admin-generic
。 要将其用作块图标,只需删除要识别的dashicons-
前缀,例如 icon: 'admin-generic'
。
但是,您不仅限于使用Dashicons作为图标属性。该函数还接受JSX元素,这意味着您可以使用任何图像或SVG元素作为块图标。
只需确保图标大小与其他块图标保持一致,默认情况下为20 x 20像素。
关键词
最多可选择三个可翻译关键词,以便在用户搜索块时使您的区块脱颖而出。最好选择与块功能密切相关的关键词,以获得最佳效果。
keywords: [
__( 'search', 'domain' ),
__( 'for', 'domain' ),
__( 'me', 'domain' ),
]
您甚至可以将公司和/或插件名称声明为关键词,这样,如果您有多个块,则用户可以开始键入您的公司名称,所有块都将显示在搜索结果中。
虽然添加关键字完全是可选的,但它是让用户更容易找到您的块的好方法。
属性
属性有助于管理块中的动态数据。此属性是可选的,因为对于输出静态内容的非常简单的块,您不需要它。
但是,如果您的块处理可能更改的数据(例如可编辑文本区域的内容)或您需要存储块设置,那么使用属性是可行的方法。
属性通过将动态块数据保存在数据库或post meta中的帖子内容中来工作。在本教程中,我们将仅使用存储数据的属性以及帖子内容。
要检索存储在帖子内容中的属性数据,我们需要指定它在标记中的位置。我们可以通过指定指向属性数据的CSS选择器来完成此操作。
例如,如果我们的块包含锚标记,我们可以使用其title
字段作为我们的属性,如下所示:
attributes: {
linktitle: {
source: 'attribute',
selector: 'a',
attribute: 'title'
}
}
这里,属性名称是linktitle
,它是一个任意字符串,可以是你喜欢的任何东西。
例如,我们可以使用<a title="some title">
属性来存储通过块设置中的文本框输入的链接标题 。这样做突然使标题字段动态化,并允许您在编辑器中更改其值。
保存帖子后,属性值将插入到链接 title
字段中。同样,加载编辑器时,title
将从内容中检索标记的值并将其插入到linktitle
属性中。
您可以使用更多方法source
来确定如何通过属性存储或检索块内容。例如,您可以使用'text'
源从段落元素中提取内部文本。
attributes: {
paragraph: {
source: 'text',
selector: 'p'
}
}
您还可以使用children
源将元素的所有子节点提取到数组中并将其存储在属性中。
attributes: {
editablecontent: {
source: 'children',
selector: '.parent'
}
}
这将选择具有类的元素.parent
并将所有子节点存储在editablecontent
属性中。
如果未指定源,则在保存到数据库时,属性值将作为发布标记的一部分保存在HTML注释中。在帖子在前端呈现之前,这些注释被删除。
当我们在本教程后面开始实现随机图像块时,我们将看到这种类型属性的具体示例。
属性可能需要一点点来习惯,所以如果你没有完全理解它们,请不要担心。我建议您查看 Gutenberg手册的属性部分,了解更多详细信息和示例。
编辑
该edit
函数控制块在编辑器界面中的显示方式。动态数据将作为props
(包括已定义的任何自定义属性)传递到每个块。
通常的做法是添加 className={ props.className }
到主块元素以输出特定于块的CSS类。WordPress不会在编辑器中为您添加此内容,因此如果您想要包含它,则必须手动为每个块添加它。
使用props.className
是标准做法,因为它提供了一种为每个块定制CSS样式的方法。 生成的CSS类的格式是.wp-block-{namespace}-{name}
。如您所见,这基于块命名空间/名称,使其成为唯一块标识符的理想选择。
编辑功能要求您通过该render()
方法返回有效标记,然后使用该方法在编辑器中渲染块。
保存
与edit
函数类似,save
显示块在前端的可视化效果。它还通过props接收动态块数据(如果已定义)。
一个主要区别是props.className
内部不可使用save
,但这不是问题,因为它是由Gutenberg自动插入的。
支持
该supports
属性接受布尔值的对象,以确定您的块是否支持某些核心功能。
您可以设置的可用对象属性如下。
anchor
(默认为false):允许您直接链接到特定块customClassName
(true):在块的检查器中添加一个字段来定义用于该块的自定义className
className
(true):根据块名称向块根元素添加一个className
html
(true):允许直接编辑块标记
useOnce
属性
这是一个有用的属性,允许您限制块多次添加到页面。核心的 更多 块就是一个例子,如果已存在则无法添加到页面。
如您所见,一旦添加了更多块,块图标将变灰并且无法选择。该useOnce
属性默认设置为false
。
让我们变得有创意!
现在是时候使用我们迄今为止所获得的知识来实现一个块的可靠实例,它比简单地输出静态内容更有趣。
我们将构建一个块,将通过外部请求获得的随机图像输出到PlaceIMG 网站,该网站返回一个随机图像。此外,您还可以选择通过选择下拉控件返回的图像类别。
为方便起见,我们将新块添加到同一个 my-custom-block 插件中,而不是创建一个全新的插件。默认块的代码位于/src/block 文件夹内,因此在/src中添加另一个名为random-image的文件夹,并添加三个新文件:
- index.js:注册我们的新块
- editor.scss:用于编辑器样式
- style.scss:编辑器和前端的样式
或者,如果您不想手动输入所有内容,您可以复制/src/block文件夹并重命名它。但是,请确保,在新的块文件夹内重命名block.js到index.js。
我们使用index.js 作为主块文件名,因为这允许我们简化blocks.js中的import语句。我们可以只指定块文件夹的路径,而不必包含块的路径和完整文件名,import
将自动查找index.js 文件。
打开/src/blocks.js 并在文件顶部添加对我们新块的引用,直接在现有import语句下面。
import './random-image';
在/src/random-image/index.js中,添加以下代码以启动我们的新块。
// Import CSS.
import './style.scss';
import './editor.scss';
const { __ } = wp.i18n;
const { registerBlockType, query } = wp.blocks;
registerBlockType( 'cgb/block-random-image', {
title: __( 'Random Image' ),
icon: 'format-image',
category: 'common',
keywords: [
__( 'random' ),
__( 'image' )
],
edit: function( props ) {
return (
<div className={ props.className }>
<h3>Random image block (editor)</h3>
</div>
);
},
save: function( props ) {
return (
<div>
<h3>Random image block (front end)</h3>
</div>
);
}
} );
这将设置我们块的框架,并且非常类似于create-guten-block
工具包生成的样板块代码。
我们通过导入编辑器和前端样式表开始,然后我们将从中选取一些常用的功能wp.i18n
和 wp.blocks
为本地变量。
registerBlockType()
里面,值已进入了title
,icon
,category
,和keywords
属性,而edit
和save
功能目前只输出静态内容。
将随机图像块添加到新页面以查看到目前为止生成的输出。
确保您仍在观看文件以进行更改,以便将任何块源代码(JSX,ES6 +,Sass等)转换为有效的JavaScript和CSS。如果您当前没有在文件中查看更改,请在my-custom-block 插件根文件夹中打开命令行窗口并输入npm start
。
您可能想知道为什么我们不必添加任何PHP代码来排队其他块脚本。my-custom-block
块的块脚本是通过init.php
排队,但是我们不需要专门为我们的新块排队脚本,因为create-guten-block
已为我们操作了。
只要我们将主块文件导入src/blocks.js(如上所述),我们就不需要做任何额外的工作了。所有JSX,ES6 +和Sass代码将自动编译为以下文件:
- dist/blocks.style.build.css:编辑器和前端的样式
- dist/blocks.build.js: 仅用于编辑器的JavaScript
- dist/blocks.editor.build.css: 仅用于编辑器的样式
这些文件包含所有块的JavaScript和CSS,因此只需要将一组文件排入队列,无论创建的块数是多少!
我们现在准备为我们的块添加一些交互性,我们可以通过首先添加一个属性来存储图像类别来实现。
attributes: {
category: {
type: 'string',
default: 'nature'
}
}
这将创建一个名为category
的属性,该属性存储一个默认值为'nature'
的字符串。 我们没有在标记中指定存储和检索属性值的位置,因此将使用特殊的HTML注释。如果省略属性源,这是默认行为。
我们需要一些改变图像类别的方法,可以通过选择下拉控件来完成。将edit
函数更新为以下内容:
edit: function( props ) {
const { attributes: { category }, setAttributes } = props;
function setCategory( event ) {
const selected = event.target.querySelector( 'option:checked' );
setAttributes( { category: selected.value } );
event.preventDefault();
}
return (
<div className={ props.className }>
Current category is: {category}
<form onSubmit={ setCategory }>
<select value={ category } onChange={ setCategory }>
<option value="animals">Animals</option>
<option value="arch">Architecture</option>
<option value="nature">Nature</option>
<option value="people">People</option>
<option value="tech">Tech</option>
</select>
</form>
</div>
);
}
这是它的样子:
这与之前的静态edit
函数完全不同,所以让我们来看看这些变化。
首先,我们添加了一个选择下拉控件,其中有几个选项与PlaceIMG 站点上可用的图像类别相匹配。
当下拉值更改时,将调用setCategory
函数,该函数将查找当前选定的类别,然后依次调用 setAttributes
函数。 这是Gutenberg的核心功能,可以正确更新属性值。建议您仅使用此功能更新属性。
现在,每当选择新类别时,属性值都会更新并传递回edit
函数,该函数会更新输出消息。
我们必须完成最后一步才能显示随机图像。我们需要创建一个简单的组件,该组件将接收当前类别并输出带有从PlaceIMG站点获得的随机图像的<img>
标签。
我们需要对PlaceIMG提出的请求是以下形式: https://placeimg.com/[width]/[height]/[category]
我们现在将保持宽度和高度不变,因此我们只需要将当前类别添加到请求URL的末尾。例如,如果该类别是'nature'
,则完整请求网址为:https://placeimg.com/320/220/nature。
添加RandomImage
组件到registerBlockType()
上面:
function RandomImage( { category } ) {
const src = 'https://placeimg.com/320/220/' + category;
return <img src={ src } alt={ category } />;
}
要使用它,只需将其添加到编辑函数中并删除静态输出消息。同时我们在这里,也为保存函数做同样的事情。
完整的index.js文件现在应如下所示:
// Import CSS.
import './style.scss';
import './editor.scss';
const { __ } = wp.i18n;
const { registerBlockType, query } = wp.blocks;
function RandomImage( { category } ) {
const src = 'https://placeimg.com/320/220/' + category;
return <img src={ src } alt={ category } />;
}
registerBlockType( 'cgb/block-random-image', {
title: __( 'Random Image' ),
icon: 'format-image',
category: 'common',
keywords: [
__( 'random' ),
__( 'image' )
],
attributes: {
category: {
type: 'string',
default: 'nature'
}
},
edit: function( props ) {
const { attributes: { category }, setAttributes } = props;
function setCategory( event ) {
const selected = event.target.querySelector( 'option:checked' );
setAttributes( { category: selected.value } );
event.preventDefault();
}
return (
<div className={ props.className }>
<RandomImage category={ category } />
<form onSubmit={ setCategory }>
<select value={ category } onChange={ setCategory }>
<option value="animals">Animals</option>
<option value="arch">Architecture</option>
<option value="nature">Nature</option>
<option value="people">People</option>
<option value="tech">Tech</option>
</select>
</form>
</div>
);
},
save: function( props ) {
const { attributes: { category } } = props;
return (
<div>
<RandomImage category={ category } />
</div>
);
}
} );
最后(暂时),将以下样式添加到editor.scss以在图像周围添加彩色边框。
.wp-block-cgb-block-random-image {
select {
padding: 2px;
margin: 7px 0 5px 2px;
border-radius: 3px;
}
}
你还需要style.css中的一些样式 。
.wp-block-cgb-block-random-image {
background: #f3e88e;
color: #fff;
border: 2px solid #ead9a6;
border-radius: 10px;
padding: 5px;
width: -webkit-fit-content;
width: -moz-fit-content;
width: fit-content;
img {
border-radius: inherit;
border: 1px dotted #caac69;
display: grid;
}
}
只要在编辑器或前端刷新页面,就会显示一个新的随机图像。
如果您看到一遍又一遍地显示相同的图像,则可以进行强制刷新 以防止从浏览器缓存中提供图像。
小结
在本教程中,我们已经介绍了很多内容。如果你已经完成了所有的工作,那就给自己一个当之无愧的点赞吧! Gutenberg 区块开发可以带来很多乐趣,但在第一次曝光时掌握每个概念绝对具有挑战性。
在此过程中,我们学习了如何将块脚本和样式排入队列并深入介绍了registerBlockType()
函数。
我们通过将理论付诸实践并从头开始创建自定义块来使用PlaceIMG Web服务显示特定类别的随机图像。
在本系列教程的下一部分也是最后一部分中,我们将通过块检查器中的设置面板为随机图像块添加更多功能。
如果您一直关注本教程并且只是想在不输入所有内容的情况下试验代码,那么您将能够在下一个教程中下载最终的my-custom-block插件。
原文:WordPress Gutenberg Block API: Creating Custom Blocks ,发布于 2018年5月23日,由 倡萌@WordPress大学 翻译,未经许可,禁止转载和挪用译文!
您已阅读完《WordPress Gutenberg Block API(共6篇)》专题的第 3 篇。请继续阅读该专题下面的文章: