如何在古腾堡编辑器中为文章添加Meta框和自定义字段

如何在古腾堡编辑器中为文章添加Meta框和自定义字段

自定义字段提供了一种为网站内容分配额外信息的方法。这些信息通常被称为元数据

元数据是关于信息的信息。就WordPress而言,它是与帖子、用户、评论和术语相关的信息。

鉴于WordPress中元数据的多对一关系,你的选择是相当无限的。你可以有你想要的许多元选项,而且你可以在其中存储几乎任何东西。

Plugin Handbook

下面是一些你可以使用自定义字段附加到文章的元数据的例子:

  • 地方或房地产的地理坐标
  • 事件的日期
  • 书的国际标准书号或作者
  • 文章作者当天的心情

或者更多其他信息。

开箱即用,WordPress并没有提供一个简单的方法来添加和管理自定义字段。在经典编辑器中,自定义字段显示在页面底部的一个框中,位于文章编辑器的下面。

经典编辑器中的自定义字段

经典编辑器中的自定义字段。

在Gutenberg中,自定义字段默认是禁用的,但你可以通过选择文章设置中的相应项目来显示它们。

将自定义字段面板添加到区块编辑器中

将自定义字段面板添加到区块编辑器中。

不幸的是,如果不使用插件或不动手写代码,就没有办法在前台显示元数据。

如果你是一个用户,你会发现有几个优秀的插件在为你做这项工作。但是,如果你是一个开发者,想从WordPress的自定义字段中得到更多的东西,把它们无缝地集成到块编辑器中,并使用自定义的Gutenberg块在WordPress网站的前端显示它们,那么你就来对地方了。

因此,如果你想知道对于WordPress开发者来说,在Gutenberg经典编辑器中使用WordPress自定义字段的最佳方式是什么,快速的答案是 “创建一个既适用于经典编辑器又适用于Gutenberg的插件”。

但不要太担心。如果创建一个插件来管理两个编辑器中的自定义字段可能有点棘手,我们会尽量使这个过程简单明了。一旦你理解了我们将在本文中讨论的概念,你将获得在Gutenberg中管理自定义元字段和建立各种网站所需的技能。

Info

本文假设你熟悉Node.js & npmReactJavaScript等技术。还需要有WordPress开发的基本知识。

如果你是Gutenberg区块开发的新手,在开始阅读本文之前,请务必查看我们之前的指南:

注意:在做任何事情之前,确保你的电脑上有最新版本的Node.js

说了这么多,下面是我们的详细介绍:

  1. 用官方的create-block工具创建一个区块插件
  2. 在经典编辑器中添加元数据框
  3. 在古腾堡区块编辑器中添加自定义元字段(三个选项)
  4. 进一步阅读

用官方的create-block工具创建一个区块插件

第一步是创建一个新的插件,包含注册一个新的区块类型所需的所有文件和依赖性。块插件将允许你轻松地建立一个自定义块类型,用于管理和显示自定义元数据。

为了创建一个新的区块类型,我们将使用官方的create-block工具。关于如何使用create-block工具的详细介绍,请查看我们之前关于Gutenberg区块开发的文章

打开你的命令行工具,导航到你的WordPress开发网站的插件目录,运行以下命令:

npx @wordpress/create-block

当出现提示时,添加以下细节:

  • The template variant to use for this block: dynamic
  • The block slug used for identification (also the output folder name): metadata-block
  • The internal namespace for the block name (something unique for your products): meta-fields
  • The display title for your block: Meta Fields
  • The short description for your block (optional): Block description
  • The dashicon to make it easier to identify your block (optional): book
  • The category name to help users browse and discover your block: widgets
  • Do you want to customize the WordPress plugin? Yes/No

让我们花点时间回顾一下这些细节,并尝试了解它们的使用情况。

  • 用于识别的区块slug定义了该插件的文件夹名称文本域
  • 区块名称的内部命名空间定义了整个插件代码中使用的区块内部命名空间函数前缀
  • 区块的显示标题定义了插件的名称和编辑器界面中使用的区块名称

设置可能需要几分钟的时间。当这个过程完成后,你会得到一个可用命令的列表。

区块插件成功安装

区块插件成功安装。

在进入下一节之前,在你的命令行工具中,导航到你的插件的文件夹并运行以下命令:

cd metadata-block
npm start

Important

确保每次启动Gutenberg开发环境时都要运行 npm start 命令。

当你运行 npm start 时,一个观察器将在终端运行,并在任何变化后重建JS和CSS文件(阅读更多)。

你已经准备好构建你的代码了。下一步是编辑插件的主要PHP文件,为经典编辑器建立一个元框。

因此,在进入下一节之前,请安装并激活经典编辑器插件

然后,打开插件界面,激活新的Meta Fields插件。

激活插件

激活插件。

在经典编辑器中添加一个元框

经典编辑器的上下文中,元框是一个容纳表单元素的容器,用于输入特定的信息,如文章作者、标签、类别等。

除了内置的元框,插件开发者可以添加任何数量的自定义元框,以包括HTML表单元素(或任何HTML内容),插件用户可以在其中输入插件的特定数据。

WordPress的API提供了有用的功能,可以轻松地注册自定义元框,包括你的插件工作所需的所有HTML元素。

要开始的话,把下面的代码附加到你刚刚创建的插件的PHP文件中:

// register meta box
function meta_fields_add_meta_box(){
add_meta_box(
'meta_fields_meta_box', 
__( 'Book details' ), 
'meta_fields_build_meta_box_callback', 
'post',
'side',
'default'
);
}
// build meta box
function meta_fields_build_meta_box_callback( $post ){
wp_nonce_field( 'meta_fields_save_meta_box_data', 'meta_fields_meta_box_nonce' );
$title = get_post_meta( $post->ID, '_meta_fields_book_title', true );
$author = get_post_meta( $post->ID, '_meta_fields_book_author', true );
?>
<div class="inside">
<p><strong>Title</strong></p>
<p><input type="text" id="meta_fields_book_title" name="meta_fields_book_title" value="<?php echo esc_attr( $title ); ?>" /></p>	
<p><strong>Author</strong></p>
<p><input type="text" id="meta_fields_book_author" name="meta_fields_book_author" value="<?php echo esc_attr( $author ); ?>" /></p>
</div>
<?php
}
add_action( 'add_meta_boxes', 'meta_fields_add_meta_box' );

add_meta_box 函数注册了一个新的元数据框,而回调函数构建了要注入元数据框的HTML。我们不会深入研究这个话题,因为它超出了我们文章的范围,但你会在这里这里这里找到你需要的所有细节。

下一步是创建一个函数,在save_post 钩子被触发的时候保存帖子作者输入的数据(见开发者资源):

// save metadata
function meta_fields_save_meta_box_data( $post_id ) {
if ( ! isset( $_POST['meta_fields_meta_box_nonce'] ) )
return;
if ( ! wp_verify_nonce( $_POST['meta_fields_meta_box_nonce'], 'meta_fields_save_meta_box_data' ) )
return;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
if ( ! current_user_can( 'edit_post', $post_id ) )
return;
if ( ! isset( $_POST['meta_fields_book_title'] ) )
return;
if ( ! isset( $_POST['meta_fields_book_author'] ) )
return;
$title = sanitize_text_field( $_POST['meta_fields_book_title'] );
$author = sanitize_text_field( $_POST['meta_fields_book_author'] );
update_post_meta( $post_id, '_meta_fields_book_title', $title );
update_post_meta( $post_id, '_meta_fields_book_author', $author );
}
add_action( 'save_post', 'meta_fields_save_meta_box_data' );

同样,请查看在线文档以了解细节。这里我们只指出元键前面的下划线字符 (_) 。这告诉WordPress从默认的自定义字段列表中隐藏这些自定义字段的键,并使你的自定义字段只在你的自定义元框中可见。

下面的图片显示了自定义元框在经典编辑器中的样子:

经典编辑器中的一个自定义元框

经典编辑器中的一个自定义元框。

现在,如果你禁用经典编辑器插件,并检查在区块编辑器中发生的情况,你会看到元框仍然出现并工作,但不完全是以你可能期望的方式。

我们的目标是创建一个系统,用于管理附加在博客文章或自定义文章类型上的元数据,并将其无缝集成到块编辑器中。由于这个原因,到目前为止所显示的代码只需要确保与经典编辑器的向后兼容。

因此,在继续前进之前,我们将通过在 add_meta_box 函数中添加 __back_compat_meta_box 标志来告诉WordPress从区块编辑器中移除自定义元框(参见元框兼容标志向后兼容)。

让我们回到注册元数据框的回调函数,并将其修改如下:

// register meta box
function meta_fields_add_meta_box(){
add_meta_box(
'meta_fields_meta_box', 
__( 'Book details' ), 
'meta_fields_build_meta_box_callback', 
'post', 
'side',
'default',
// hide the meta box in Gutenberg
array('__back_compat_meta_box' => true)
);
}

保存该插件文件,然后回到你的WordPress管理区。现在,你不应该再在块状编辑器中看到自定义元框了。如果你重新激活经典编辑器,你的自定义元框就会重新显示出来。

在古腾堡区块编辑中添加自定义元字段(三个选项)

在我们之前关于Gutenberg区块开发的文章中,我们详细介绍了编辑器、它的各个部分,以及如何开发静态区块动态区块

正如我们提到的,在这篇文章中,我们将更进一步,讨论如何为博客文章添加自定义元字段。

在Gutenberg中,有几种方法来存储和使用文章元数据。这里我们将介绍以下内容:

  1. 创建一个自定义块来存储和显示自定义元字段
  2. 在文档侧边栏中添加一个自定义元框
  3. 添加一个自定义侧边栏来管理帖子的元数据

创建一个自定义区块来存储和显示自定义元字段

在本节中,我们将向你展示如何在一个动态区块中创建和管理自定义元字段。根据Block Editor Handbook,一个文章元字段 “是一个WordPress对象,用来存储关于一个文章的额外数据”,我们需要首先注册一个新的元字段,然后才能使用它。

注册自定义元字段

在注册一个自定义元字段之前,你需要确保将使用它的文章类型支持自定义字段。此外,当你注册一个自定义元字段时,你应该把 show_in_rest 参数设置为 true

现在,回到插件文件中。添加以下代码:

/**
* Register the custom meta fields
*/
function meta_fields_register_meta() {
$metafields = [ '_meta_fields_book_title', '_meta_fields_book_author' ];
foreach( $metafields as $metafield ){
// Pass an empty string to register the meta key across all existing post types.
register_post_meta( '', $metafield, array(
'show_in_rest' => true,
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_text_field',
'auth_callback' => function() { 
return current_user_can( 'edit_posts' );
}
));
}  
}
add_action( 'init', 'meta_fields_register_meta' );

register_post_meta 为指定的帖子类型注册了一个元键。在上面的代码中,我们为你网站上注册的所有支持自定义字段的帖子类型注册了两个自定义元字段。更多信息请参见函数参考

完成后,打开你的块插件的src/index.js文件。

在客户端注册区块类型

现在导航到wp-content/plugins/metadata-block/src文件夹,打开index.js文件:

import { registerBlockType } from '@wordpress/blocks';
import './style.scss';
import Edit from './edit';
import metadata from './block.json';
registerBlockType( metadata.name, {
edit: Edit,
} );

对于静态区块,我们也会看到一个 save 函数功能。在这种情况下,由于我们安装了一个动态区块,所以没有 save 函数。前台显示的内容将通过PHP动态生成。

建立区块类型

导航到wp-content/plugins/metadata-block/src文件夹,打开edit.js文件。你应该看到以下代码(注释已删除):

import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';
export default function Edit() {
return (
<p { ...useBlockProps() }>
{ __( 'Meta Fields – hello from the editor!', 'metadata-block' ) }
</p>
);
}

在这里,你将添加代码来生成要在编辑器中呈现的区块。

第一步是导入构建区块所需的组件和函数。这里是完整的依赖性列表:

import { __ } from '@wordpress/i18n';
import { useBlockProps, InspectorControls, RichText } from '@wordpress/block-editor';
import { useSelect } from '@wordpress/data';
import { useEntityProp } from '@wordpress/core-data';
import { TextControl, PanelBody, PanelRow } from '@wordpress/components';
import './editor.scss';

如果你读过我们以前的文章,你应该对这些 import 声明中的许多内容很熟悉。这里我们只指出其中的几个:

import { useSelect } from '@wordpress/data';
import { useEntityProp } from '@wordpress/core-data';

一旦你导入了这些依赖,下面是你如何在 Edit() 函数中 useSelect 和 useEntityProp :

const postType = useSelect(
( select ) => select( 'core/editor' ).getCurrentPostType(),
[]
);
const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' );

这段代码提供了当前的 postType,一个元字段的对象(meta),以及一个更新它们的setter函数(setMeta)。

现在用下面的代码替换当前 Edit() 函数的代码:

export default function Edit() {
const blockProps = useBlockProps();
const postType = useSelect(
( select ) => select( 'core/editor' ).getCurrentPostType(),
[]
);
const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' );
const bookTitle = meta[ '_meta_fields_book_title' ];
const bookAuthor = meta[ '_meta_fields_book_author' ];
const updateBookTitleMetaValue = ( newValue ) => {
setMeta( { ...meta, _meta_fields_book_title: newValue } );
};
const updateBookAuthorMetaValue = ( newValue ) => {
setMeta( { ...meta, _meta_fields_book_author: newValue } );
};
return ( ... );
}

Again:

  • We used useSelect to get the current post type.我们使用 useSelect 来获取当前的文章类型。
  • useEntityProp 返回一个元字段的数组和一个setter函数来设置新的元值。
  • updateBookTitleMetaValue 和 updateBookAuthorMetaValue是两个事件处理程序,用于保存元字段值。

下一步是建立由 Edit() 函数返回的JSX(JavaScript XML)代码:

export default function Edit() {
...
return (
<>
<InspectorControls>
<PanelBody 
title={ __( 'Book Details' )}
initialOpen={true}
>
<PanelRow>
<fieldset>
<TextControl
label={__( 'Book title' )}
value={ bookTitle }
onChange={ updateBookTitleMetaValue }
/>
</fieldset>
</PanelRow>
<PanelRow>
<fieldset>
<TextControl
label={ __( 'Book author' ) }
value={ bookAuthor }
onChange={ updateBookAuthorMetaValue }
/>
</fieldset>
</PanelRow>
</PanelBody>
</InspectorControls>
<div { ...blockProps }>
<RichText 
tagName="h3"
onChange={ updateBookTitleMetaValue }
allowedFormats={ [ 'core/bold', 'core/italic' ] }
value={ bookTitle }
placeholder={ __( 'Write your text...' ) }
/>
<TextControl
label="Book Author"
value={ bookAuthor }
onChange={ updateBookAuthorMetaValue }
/>
</div>
</>
);
}

RichText 组件提供了一个可编辑内容的输入,而 TextControl 提供了简单的文本字段。

我们还创建了一个包含两个输入字段的侧边栏面板,用来代替块中包含的两个表单控件。

保存文件并回到编辑器。从区块插入器中添加Meta Fields区块,并填入书名和作者。

一个自定义区块包括两个自定义元字段

一个自定义区块包括两个自定义元字段。

你会注意到,每当你改变块中字段的值时,侧边栏中相应文本字段的值也会改变。

接下来,我们要创建PHP代码,生成HTML,在前台显示。

在前台显示该区块

在你的代码编辑器中再次打开主PHP文件,重写生成块输出的回调函数,如下所示:

function meta_fields_metadata_block_block_init() {
register_block_type(
__DIR__ . '/build',
array(
'render_callback' => 'meta_fields_metadata_block_render_callback',
)
);
}
add_action( 'init', 'meta_fields_metadata_block_block_init' );
function meta_fields_metadata_block_render_callback( $attributes, $content, $block ) {
$book_title = get_post_meta( get_the_ID(), '_meta_fields_book_title', true );
$book_author = get_post_meta( get_the_ID(), '_meta_fields_book_author', true );
$output = "";
if( ! empty( $book_title ) ){
$output .= '<h3>' . esc_html( $book_title ) . '</h3>';
}
if( ! empty( $book_author ) ){
$output .= '<p>' . __( 'Book author: ' ) . esc_html( $book_author ) . '</p>';
}
if( strlen( $output ) > 0 ){
return '<div ' . get_block_wrapper_attributes() . '>' . $output . '</div>';
} else {
return '<div ' . get_block_wrapper_attributes() . '>' . '<strong>' . __( 'Sorry. No fields available here!' ) . '</strong>' . '</div>';
}
}

这段代码是不言自明的。首先,我们使用 get_post_meta 来检索自定义元字段的值。然后,我们使用这些值来构建块的内容。最后,回调函数返回该块的HTML。

块已经准备好被使用了。我们有意让这个例子中的代码尽可能简单,但使用Gutenberg的本地组件,你可以建立更高级的块,并从WordPress的自定义元字段中获得最大的收益。

一个包括几个元字段的自定义区块

一个包括几个元字段的自定义区块。

在我们的例子中,我们使用 h3 和 p 元素来建立前端的区块。

但是你可以用很多方式来显示数据。下面的图片显示了一个简单的无序的元字段列表。

前台的一个示例区块

前台的一个示例区块。

你可以在这个公开的gist中找到这个例子的完整代码。

在文档侧边栏添加一个自定义元框

第二个选择是使用一个插件将自定义元字段附加到帖子上,该插件在文档侧边栏生成一个设置面板。

这个过程与前面的例子很相似,只是在这种情况下,我们将不需要一个区块来管理元数据。我们将按照以下步骤创建一个组件,在文档侧边栏中生成一个包括一系列控件的面板:

  1. 用create-block创建一个新的区块插件
  2. 为经典编辑器注册一个自定义元域框
  3. 通过register_post_meta()函数在主插件文件中注册自定义元域
  4. 在index.js文件中注册一个插件
  5. 使用内置的Gutenberg组件构建该组件

用create-block创建一个新的区块插件

要创建一个新的区块插件,请按照上一节的步骤进行。你可以创建一个新的插件,或者编辑我们在前面的例子中建立的脚本。

为经典编辑器注册一个自定义元域框

接下来,你需要注册一个自定义元框,以确保仍然使用经典编辑器的WordPress网站向后兼容。这个过程与上一节所述的相同。

通过register_post_meta()函数在主插件文件中注册自定义元域

下一步是通过 register_post_meta() 函数在主插件文件中注册自定义元域。同样,你可以按照前面的例子

在index.js文件中注册一个插件

一旦你完成了前面的步骤,现在是时候在index.js文件中注册一个插件来渲染一个自定义组件了。

在注册该插件之前,在该插件的src文件夹内创建一个components文件夹。在components文件夹内,创建一个新的MetaBox.js文件。你可以选择任何你认为对你的组件有利的名字。只要确保遵循React中命名的最佳实践

在继续前进之前,从你的命令行工具中安装 @wordpress/plugins 模块 。

停止进程(mac),安装模块并再次启动进程:

^C
npm install @wordpress/plugins --save
npm start

一旦完成,打开你的插件的index.js文件,添加以下代码:

/**
* Registers a plugin for adding items to the Gutenberg Toolbar
*
* @see https://developer.wordpress.org/block-editor/reference-guides/slotfills/plugin-sidebar/
*/
import { registerPlugin } from '@wordpress/plugins';
import MetaBox from './components/MetaBox';

这段代码是不言自明的。然而,我们想花点时间为那些没有高级React技能的读者详细介绍一下这两条 import 语句。

在第一条 import 语句中,我们将函数的名称用大括号括起来。在第二条 import 语句中,组件的名字没有用大括号括起来。

Info

不带大括号的 import 语句用于导入默认导出。带大括号的 import 语句用于导入一个命名的导出。有关其他细节,请参阅以下资源:

接下来,注册你的插件:

registerPlugin( 'metadata-plugin', {
render: MetaBox
} );

registerPlugin 简单地注册了一个插件。该函数接受两个参数:

  • 一个唯一的字符串,用于识别该插件
  • 一个插件设置的对象。注意,必须指定 render 属性,并且必须是一个有效的函数。

使用内置的Gutenberg组件构建该组件

现在是时候建立我们的React组件了。打开MetaBox.js文件(或者你叫它什么),添加以下导入语句:

import { __ } from '@wordpress/i18n';
import { compose } from '@wordpress/compose';
import { withSelect, withDispatch } from '@wordpress/data';
import { PluginDocumentSettingPanel } from '@wordpress/edit-post';
import { PanelRow, TextControl, DateTimePicker } from '@wordpress/components';
  • compose 函数执行函数组合,意味着一个函数的结果被传递给另一个函数。在你使用 compose 之前,你可能需要安装相应的模块。
    npm install @wordpress/compose --save

    我们稍后将看到 compose 函数的运行。

  • withSelect 和 withDispatch 是两个高阶组件,允许你从WordPress商店获取或调度数据。withSelect 用于使用注册的选择器注入源自状态的道具,withDispatch 用于使用注册的动作创建者调度道具。
  • PluginDocumentSettingPanel 渲染文档侧边栏的项目(见Github上的源代码)。

接下来,你将创建组件,在文档侧边栏显示元框面板。在你的MetaBox.js文件中,添加以下代码:

const MetaBox = ( { postType, metaFields, setMetaFields } ) => {
if ( 'post' !== postType ) return null;
return(
<PluginDocumentSettingPanel 
title={ __( 'Book details' ) } 
icon="book"
initialOpen={ false }
>
<PanelRow>
<TextControl 
value={ metaFields._meta_fields_book_title }
label={ __( "Title" ) }
onChange={ (value) => setMetaFields( { _meta_fields_book_title: value } ) }
/>
</PanelRow>
<PanelRow>
<TextControl 
value={ metaFields._meta_fields_book_author }
label={ __( "Author" ) }
onChange={ (value) => setMetaFields( { _meta_fields_book_author: value } ) }
/>
</PanelRow>
<PanelRow>
<TextControl 
value={ metaFields._meta_fields_book_publisher }
label={ __( "Publisher" ) }
onChange={ (value) => setMetaFields( { _meta_fields_book_publisher: value } ) }
/>
</PanelRow>
<PanelRow>
<DateTimePicker
currentDate={ metaFields._meta_fields_book_date }
onChange={ ( newDate ) => setMetaFields( { _meta_fields_book_date: newDate } ) }
__nextRemoveHelpButton
__nextRemoveResetButton
/>
</PanelRow>
</PluginDocumentSettingPanel>
);
}
const applyWithSelect = withSelect( ( select ) => {
return {
metaFields: select( 'core/editor' ).getEditedPostAttribute( 'meta' ),
postType: select( 'core/editor' ).getCurrentPostType()
};
} );
const applyWithDispatch = withDispatch( ( dispatch ) => {
return {
setMetaFields ( newValue ) {
dispatch('core/editor').editPost( { meta: newValue } )
}
}
} );
export default compose([
applyWithSelect,
applyWithDispatch
])(MetaBox);

让我们来分解一下这段代码。

  • PluginDocumentSettingPanel 元素在Document侧边栏渲染了一个新的面板。我们设置了标题(”Book details”)和图标,并将 initialOpen 设置为 false,这意味着最初面板是关闭的。
  • 在 PluginDocumentSettingPanel 中,我们有三个文本字段和一个 DateTimePicker 元素,允许用户设置出版日期。
  • withSelect 提供了对 select 函数的访问,我们用它来检索 metaFields 和 postTypewithDispatch 提供了对 dispatch函数的访问,它允许更新元数据值。
  • 最后, compose 函数允许我们将我们的组件与 withSelect 和 withDispatch 的高阶组件进行组合。这使得组件可以访问 metaFields 和 postType 属性以及 setMetaFields 函数。

保存你的MetaBox.js文件,在你的WordPress开发网站上创建一个新的帖子,看看文档侧边栏。你应该看到新的图书细节面板。

Gutenberg中的一个自定义元框面板

Gutenberg中的一个自定义元框面板。

现在运行你的测试。设置你的自定义元字段的值并保存帖子。然后重新加载页面,检查你输入的值是否到位。

添加我们在上一节中建立的块,并检查一切是否正常工作。

添加自定义侧边栏以管理文章的元数据

如果你有大量的自定义元字段需要添加到你的文章或自定义文章类型中,你也可以专门为你的插件创建一个自定义设置侧边栏。

这个过程与前面的例子非常相似,所以如果你已经理解了上一节所讨论的步骤,你在为Gutenberg建立自定义侧栏时不会有任何困难。

Again:

  1. 用create-block创建一个新的区块插件
  2. 为经典编辑器注册一个自定义元域框
  3. 通过register_post_meta()函数在主插件文件中注册自定义元域
  4. 在index.js文件中注册一个插件
  5. 使用内置的Gutenberg组件构建该组件

用create-block工具创建一个新的区块插件

同样,要创建一个新的区块插件,请遵循上面讨论的步骤。你可以创建一个新的插件,也可以编辑前面例子中建立的脚本。

为经典编辑器注册一个自定义元框

现在注册一个自定义元框,以确保仍然使用经典编辑器的WordPress网站的向后兼容性。这个过程与上一节所述的相同。

在主插件文件中注册自定义元字段

通过 register_post_meta() 函数在主插件文件中注册自定义元字段。

在index.js文件中注册一个插件

现在在你的components文件夹中创建一个空的CustomSidebar.js文件。

一旦完成,请修改你的index.js文件,如下所示:

/**
* Registers a plugin for adding items to the Gutenberg Toolbar
*
* @see https://developer.wordpress.org/block-editor/reference-guides/slotfills/plugin-sidebar/
*/
import { registerPlugin } from '@wordpress/plugins';
import CustomSidebar from './components/CustomSidebar';
// import MetaBox from './components/MetaBox';
registerPlugin( 'metadata-block', {
render: CustomSidebar
} );

通过上面的代码,我们首先导入 CustomSidebar 组件,然后告诉 registerPlugin 函数来渲染新的组件。

使用内置的Gutenberg组件构建该组件

接下来,打开CustomSidebar.js文件,添加以下依赖项:

import { __ } from '@wordpress/i18n';
import { compose } from '@wordpress/compose';
import { withSelect, withDispatch } from '@wordpress/data';
import { PluginSidebar, PluginSidebarMoreMenuItem } from '@wordpress/edit-post';
import { PanelBody, PanelRow, TextControl, DateTimePicker } from '@wordpress/components';

你应该注意到,我们正在导入两个新的组件:

  • PluginSidebar 在Gutenberg工具栏中添加了一个图标,点击后会显示一个侧边栏,包括<PluginSidebar /> 元素中包裹的内容(该组件在GitHub上也有记录)。
  • PluginSidebarMoreMenuItem renders a menu item under Plugins in More Menu dropdown and can be used to activate the corresponding PluginSidebar component (see also on GitHub).在更多下拉菜单中的Plugins下渲染了一个菜单项,可以用来激活相应的 PluginSidebar 组件(也见GitHub上的文档)。

现在你可以建立你的自定义组件了:

const CustomSidebar = ( { postType, metaFields, setMetaFields } ) => {
if ( 'post' !== postType ) return null;
return (
<>
<PluginSidebarMoreMenuItem 
target="metadata-sidebar" 
icon="book"
>
Metadata Sidebar
</PluginSidebarMoreMenuItem>
<PluginSidebar 
name="metadata-sidebar" 
icon="book" 
title="My Sidebar"
>
<PanelBody title="Book details" initialOpen={ true }>
<PanelRow>
<TextControl 
value={ metaFields._meta_fields_book_title }
label={ __( "Title" ) }
onChange={ (value) => setMetaFields( { _meta_fields_book_title: value } ) }
/>
</PanelRow>
<PanelRow>
<TextControl 
value={ metaFields._meta_fields_book_author }
label={ __("Author", "textdomain") }
onChange={ (value) => setMetaFields( { _meta_fields_book_author: value } ) }
/>
</PanelRow>
<PanelRow>
<TextControl 
value={ metaFields._meta_fields_book_publisher }
label={ __("Publisher", "textdomain") }
onChange={ (value) => setMetaFields( { _meta_fields_book_publisher: value } ) }
/>
</PanelRow>
<PanelRow>
<DateTimePicker
currentDate={ metaFields._meta_fields_book_date }
onChange={ ( newDate ) => setMetaFields( { _meta_fields_book_date: newDate } ) }
__nextRemoveHelpButton
__nextRemoveResetButton
/>
</PanelRow>
</PanelBody>
</PluginSidebar>
</>
)
}

最后一步是用 withSelect 和 withDispatch 高阶组件组成:

const applyWithSelect = withSelect( ( select ) => {
return {
metaFields: select( 'core/editor' ).getEditedPostAttribute( 'meta' ),
postType: select( 'core/editor' ).getCurrentPostType()
};
} );
const applyWithDispatch = withDispatch( ( dispatch ) => {
return {
setMetaFields ( newValue ) {
dispatch('core/editor').editPost( { meta: newValue } )
}
}
} );
export default compose([
applyWithSelect,
applyWithDispatch
])(CustomSidebar);

保存你的修改,然后检查编辑器界面。如果你打开Options下拉菜单,你会在插件部分看到一个新的Metadata Sidebar项目。点击这个新项目将激活你全新的自定义侧边栏。

插件侧边栏更多菜单项

PluginSidebarMoreMenuItem组件在Options – Plugins下增加了一个菜单项。

当你点击右上角的书籍图标时,也会发生同样的情况。

插件设置侧边栏

插件设置侧边栏。

现在回到你的开发网站,并创建一个新的博客文章。填写你的元字段,然后将该块添加到编辑器的画布上。它应该包括你在自定义侧边栏中输入的相同元值。

保存文章并在前台预览页面。你应该看到你的卡片包括书名、作者、出版商和出版日期。

你可以在这个公开的gist中找到这篇文章的完整代码。

进一步阅读

在这篇文章中,我们涵盖了多个主题,从选择器到高阶组件以及更多。我们在文章中也链接了我们所使用的顶级资源作为参考。

但是,如果你想更深入地了解这些主题,你可能还想查看以下额外的资源:

Gutenberg文档和官方WordPress资源

更多官方资源

来自社区的其他资源

本站可参考的文章

小结

在这篇关于Gutenberg区块开发系列的第三篇文章中,我们涵盖了新的高级主题,这些主题应该使之前关于静态动态区块开发的文章中所概述的情况更加完整。

你现在应该能够利用Gutenberg中自定义字段的潜力,并创建更先进、更实用的WordPress网站。

但还有更多。凭借你从我们关于区块开发的文章中获得的技能,你也应该对如何在WordPress之外开发React组件有一个好的想法。毕竟,Gutenberg是一个基于React的SPA。

现在就看你的了! 你已经创建了使用自定义元字段的Gutenberg区块了吗?请在下面的评论中与我们分享你的创作。

评论留言