wordpress Gutenberg Block api:创建自定义块,欢迎回到我们关于使用 WordPress Gutenberg Block api创建自定义块的系列。本教程是关于扩展我们在上一篇文章中创建的随机图像块。我们已经添加了一个下拉控件来选择图像类别。我们将继续通过添加更多块选项来允许进一步自定义。
具体来说,我们将看到如何在编辑器的各个部分添加块设置。没错,您不仅限于直接在块本身上添加块控件!
最终的 my-custom-block 插件代码可供下载。只需单击右侧边栏中的链接,然后将 zip 文件下载到您的计算机,然后像安装任何其他 WordPress 插件一样安装它。您还可以在我们的 GitHub 存储库中找到源代码。
Gutenberg 的开发正在以相当快的速度进行,自上一个教程发布以来,已经有了一个重要的新版本。本教程中使用的 Gutenberg 版本已更新至 3.0.1,部分编辑器 UI 可能与本系列之前教程中显示的屏幕截图略有不同。
让我们扩展!
我们在上一个教程中添加的下拉控件位于编辑器内,就在随机图像的标记下方。这很方便,但我们也有其他选择。
我们还可以将块控件添加到弹出工具栏(在选择块时出现)和块检查器面板。
在上面的屏幕截图中,我们可以看到段落块 [1] 的工具栏控件,以及面板检查器 [3] 中的相关控件。位置 [2] 显示了我们的随机图像块的下拉控件。
您可能已经在考虑为自己的块设置选择哪个位置,但您不必只选择其中一个位置。它们并不相互排斥。例如,对于段落块(如上所示),您可以看到设置在块检查器面板和工具栏之间拆分。
此外,在编辑器的不同位置有两个影响相同设置的单独控件是完全可以的。您可能不想经常这样做,但知道如何实现它很有用,所以我们稍后会看到如何做到这一点。
直接阻止设置
让我们从向块添加功能的最简单方法开始,该方法直接位于块的edit
函数内部。我们已经使用这种方法来添加我们的随机图像下拉控件,因为它只需要很少的额外工作。
我们不会过多地向块本身添加新控件,但我们可以调整下拉控件的行为,使其更加直观。为了让它尽可能靠近前端渲染,我们可以阻止下拉菜单出现,除非该块被选中。
让我们现在进行此更改。如果您从上次开始学习本教程,请 在您喜欢的编辑器中打开/my-custom-block/src/random-image/index.js 。这是我们随机图像块的主要javascript文件。
传递给所有块的道具之一是isSelected
,它保存块的可见性状态。我们可以使用它来有条件地显示类别下拉控件。
isSelected
首先,从对象中拉出props
并将其添加到edit
函数内部的常量列表中。这很有用,因此我们可以通过缩短名称(即isSelected
,而不是props.isSelected
)来引用它。
const { attributes: { category }, setAttributes, isSelected } = props;
接下来,我们可以使用此属性来确定是否应显示下拉控件:
{ isSelected && ( <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> ) }
这是正确的测试的简写方式,因为我们不能在jsx代码中isSelected
使用完整的 JavaScriptif
语句。
确保您仍在监视文件的更改,以便将任何块源代码(JSX、ES6+、Sass 等)转换为有效的 javaScript 和css。如果您当前没有查看文件的更改,请在my-custom-block插件根文件夹中打开一个命令行窗口并输入npm start
.
打开古腾堡编辑器并添加随机图像块。这一次,如果尚未单击该块,则下拉控件不可见
这给了块一个更具交互性的感觉。
工具栏控件
如果您使用过任何核心 Gutenberg 块(例如段落块),那么您将熟悉工具栏设置。一旦选择了段落块,就会出现一个弹出工具栏,其中包含用于格式化文本的按钮。这种类型的控件非常适合具有开/关类型状态的块设置,例如,文本对齐或粗体或斜体等格式。
我们将使用内置的对齐工具栏控件来允许下拉图像类别控件左对齐(默认)、右对齐或居中对齐。
AlignmentToolBar
首先,我们需要BlockControls
从wp.blocks
. 这些允许我们在选中块时在块上方的浮动工具栏中显示对齐控件。这些是我们可以在自己的块中使用的核心组件的一部分。
const { AlignmentToolbar, BlockControls, registerBlockType } = wp.blocks;
该BlockControls
组件充当工具栏容器,并AlignmentToolbar
放置在其中。
我们仍然需要手动关联对齐工具栏的行为,我们可以通过添加一个新categoryAlign
属性来存储块对齐状态(左、右或居中)。
我们的attributes
对象现在包含两个设置。
attributes: { category: { type: 'string', default: 'nature' }, categoryAlign: { type: 'string' default: '' } }
该categoryAlign
属性的默认值为空字符串,这将导致默认情况下不应用对齐方式。
要引用新属性,我们可以将这个值提取到它自己的常量变量中,就像我们对下拉category
属性所做的那样。
const { attributes: { category, categoryAlign }, setAttributes, isSelected } = props;
我们现在需要做的就是将两个新组件放入edit
函数中并配置属性。
<BlockControls> <AlignmentToolbar value={ categoryAlign } onChange={ value => setAttributes( { categoryAlign: value } ) } /> </BlockControls>
如您所见,我们需要做的就是将 的value
属性分配给属性,Alignmenttoolbar
并 在单击新工具栏按钮时categoryAlign
调用该函数。setAttributes
该函数依次更新categoryAlign
属性并使所有内容保持同步。
要应用下拉控件的对齐样式,我们需要向表单元素添加样式属性。
<form onSubmit={ setCategory } style={ {textAlign: categoryAlign} }>
请注意,我们不需要此控件来影响前端的任何内容,因此我们不需要向块的save
函数添加任何代码。
添加设置面板
块检查器面板为您提供了一个大区域来添加块控件,并且是更复杂控件的理想位置。
我们将专注于向检查器面板添加两个下拉控件。第一个将是类别下拉控件的副本,用于选择随机图像的类型。这演示了如何让多个控件更新一个公共属性。
当一个控件更新时,对应的控件也会自动更新!但在实践中,您通常只需要每个设置一个控件。
第二个下拉控件将允许您选择应用于随机图像的过滤器。PlaceIMG Web服务支持两种类型的过滤器——灰度和棕褐色——我们可以通过简单地 在 HTTP 请求 URL 中添加sepia
或来在它们之间进行选择。grayscale
如果我们不指定过滤器,则将返回标准彩色图像。
这两个下拉菜单的代码非常相似,所以我们将它们加在一起。
首先,让我们定义我们需要的新块和组件。
const { AlignmentToolbar, BlockControls, registerBlockType, InspectorControls } = wp.blocks; const { PanelBody, PanelRow } = wp.components; const { Fragment } = wp.element;
在这里,新变量是InspectorControls
、PanelBody
、PanelRow
和Fragment
,它们都用于帮助创建检查器面板 UI。
当您需要从or函数<Fragment>
返回多个顶级元素 但又不想将它们包装在将要输出的元素中时,该组件非常有用。edit
save
<Fragment>
不会在前端输出任何标记,就像一个不可见的容器。这只是返回多个顶级元素的一种便捷方式,并且可以替代先前返回元素数组的方法。
我们只需要添加一个新属性,称为imageFilter
现有category
属性可以重用。
attributes: { category: { type: 'string', default: 'nature' }, categoryAlign: { type: 'string', default: '' }, imageFilter: { type: 'string', default: '' } }
在edit
函数内部,我们需要添加一个引用新属性的新变量。
const { attributes: { category, categoryAlign, imageFilter }, setAttributes, isSelected } = props;
添加块检查器面板非常容易。我们将使用的组件结构如下:
<InspectorControls> <PanelBody> <PanelRow> ... </PanelRow> <PanelRow> ... </PanelRow> </PanelBody> <PanelBody> <PanelRow> ... </PanelRow> <PanelRow> ... </PanelRow> </PanelBody> </InspectorControls>
该<InspectorControls>
组件充当块检查器容器,并<PanelBody>
定义单独的可折叠部分。在每个内部,您可以拥有任意数量的<PanelRow>
组件,这些组件又包含您的控件。
我们已经为我们可以重用的类别下拉控件定义了标记。为此,请将其抽象为一个单独的函数:
function showForm() { return ( <form onSubmit={ setCategory } style={ {textAlign: categoryAlign} }> <select id="image-category" 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> ); }
然后,只要我们需要呈现类别下拉控件,就可以引用此函数。块检查器面板的标记需要在块标记之外,因此我们可以使用<Fragment>
组件在它们返回之前将它们包装起来。
接下来,我们需要为类别和图像过滤器下拉列表添加块检查器组件。这些需要在<PanelRow>
组件内部定义,我们还必须定义一个新的回调函数来处理onChange
事件。这与上一个教程中的类别下拉代码非常相似,因此您现在应该很熟悉了。
综上所述,该edit
方法的return
函数现在如下所示:
return ( <Fragment> <InspectorControls> <PanelBody title={ __('Image Settings') }> <PanelRow> <label>Set Filter</label> { showForm() } </PanelRow> <PanelRow> <label>Set Filter</label> <form onSubmit={ setFilter }> <select id="image-filter" value={ imageFilter } onChange={ setFilter }> <option value="">None</option> <option value="sepia">Sepia</option> <option value="grayscale">Grayscale</option> </select> </form> </PanelRow> </PanelBody> </InspectorControls> <div className={ props.className }> <BlockControls> <AlignmentToolbar value={ categoryAlign } onChange={ value => setAttributes( { categoryAlign: value } ) } /> </BlockControls> <RandomImage filter={ imageFilter } category={ category } /> { isSelected && ( showForm() ) } </div> </Fragment> );
setFilter
回调定义为:
function setFilter( event ) { const selected = event.target.queryselector( '#image-filter option:checked' ); setAttributes( { imageFilter: selected.value } ); event.preventDefault(); }
要获得过滤后的图像,我们需要在RandomImage
每次下拉列表更改时更新组件以接受新的过滤器值。
function RandomImage( { category, filter } ) { if(filter) { filter = '/' + filter; } const src = 'https://placeimg.com/320/220/' + category + filter; return <img src={ src } alt={ category } />; }
注意我们如何在edit
方法中使用这个新的组件属性将新的过滤器值发送到 PlaceIMG。
<RandomImage filter={ imageFilter } category={ category } />
所有这些代码更改都会创建一个新的块检查器面板,其中包含两个下拉控件来更改图像类别和过滤器。
为了让新的过滤器属性也适用于前端,我们只需要更新save
方法。
save: function( props ) { const { attributes: { category, imageFilter } } = props; return ( <div> <RandomImage filter={ imageFilter } category={ category } /> </div> ); }
结论
在这篇文章中,我们介绍了向块添加设置的三种不同方法:
弹出工具栏
直接在块本身上
块检查面板
我们只为每个块添加了基本设置,但我们可以通过添加对多个图像的支持、添加图像标题以及控制诸如边框颜色、半径或随机图像大小等样式来轻松地更进一步。
我敢肯定,到目前为止,您可能已经有了一些创建自己的自定义块的想法。我很想听听您在自己的项目中会发现什么样的积木!