古腾堡块无法保存块元数据

问题描述

我尝试复制标题以创建自定义标题

不幸的是,该块未保存元数据。

为什么内容正确保存,但backgroundColor不正确?

index.js

/**
 * External dependencies
 */
import { isEmpty } from 'lodash';

/**
 * wordpress dependencies
 */
import { heading as icon } from '@wordpress/icons';
import { __,sprintf } from '@wordpress/i18n';

/**
 * Internal dependencies
 */
import deprecated from './deprecated';
import edit from './edit';
import Metadata from './block.json';
import save from './save';
import transforms from './transforms';

const { name } = Metadata;

export { Metadata,name };

export const settings = {
    title: __( 'heading' ),description: __(
        'Introduce new sections and organize content to help visitors (and search engines) understand the structure of your content.'
    ),icon,keywords: [ __( 'title' ),__( 'subtitle' ) ],example: {
        attributes: {
            content: __( 'Code is Poetry' ),level: 2,},__experimentalLabel( attributes,{ context } ) {
        if ( context === 'accessibility' ) {
            const { content,level } = attributes;

            return isEmpty( content )
                ? sprintf(
                        /* translators: accessibility text. %s: heading level. */
                        __( 'Level %s. Empty.' ),level
                  )
                : sprintf(
                        /* translators: accessibility text. 1: heading level. 2: heading content. */
                        __( 'Level %1$s. %2$s' ),level,content
                  );
        }
    },transforms,deprecated,merge( attributes,attributesToMerge ) {
        return {
            content:
                ( attributes.content || '' ) +
                ( attributesToMerge.content || '' ),};
    },edit,save,};

block.json

{
    "name": "afs/heading","category": "text","attributes": {
        "align": {
            "type": "string"
        },"backgroundColor": {
            "type": "string","source": "Meta"
        },"content": {
            "type": "string","source": "html","selector": "h1,h2,h3,h4,h5,h6","default": ""
        },"level": {
            "type": "number","default": 2
        },"placeholder": {
            "type": "string"
        }
    },"supports": {
        "anchor": true,"className": false,"lightBlockWrapper": true,"__experimentalColor": {
            "linkColor": true
        },"__experimentalFontSize": true,"__experimentalLineHeight": true,"__experimentalSelector": {
            "afs/heading/h1": "h1","afs/heading/h2": "h2","afs/heading/h3": "h3","afs/heading/h4": "h4","afs/heading/h5": "h5","afs/heading/h6": "h6"
        },"__unstablePasteTextInline": true
    }
}

edit.js

/**
 * External dependencies
 */
import classnames from 'classnames';

/**
 * wordpress dependencies
 */
import { __ } from '@wordpress/i18n';
import { createBlock } from '@wordpress/blocks';
import {
    AlignmentToolbar,BlockControls,RichText,InspectorControls,__experimentalBlock as Block,} from '@wordpress/block-editor';
import { ToolbarGroup } from '@wordpress/components';
const {
    PanelColorSettings,} = wp.editor;
/**
 * Internal dependencies
 */
import headingLevelDropdown from './heading-level-dropdown';

function headingEdit( {
    attributes,setAttributes,mergeBlocks,onReplace,mergedStyle,} ) {
    const { align,content,placeholder,backgroundColor } = attributes;
    const tagName = 'h' + level;

    const onChangeBackgroundColor = ( colorValue ) => {
        setAttributes( { backgroundColor: colorValue } );
    };

    return (
        <div>
            {
            <InspectorControls>
                <PanelColorSettings
                    title={ __( 'Color Settings' ) }
                    colorSettings={ [
                        {
                            value: backgroundColor,onChange: onChangeBackgroundColor,label: __( 'Background Color' ),}
                    ] }
                >

                </PanelColorSettings>
            </InspectorControls>
            }
            <BlockControls>
                <ToolbarGroup>
                    <headingLevelDropdown
                        selectedLevel={ level }
                        onChange={ ( newLevel ) =>
                            setAttributes( { level: newLevel } )
                        }
                    />
                </ToolbarGroup>
                <AlignmentToolbar
                    value={ align }
                    onChange={ ( nextAlign ) => {
                        setAttributes( { align: nextAlign } );
                    } }
                />
            </BlockControls>

            <RichText
                identifier="content"
                tagName={ Block[ tagName ] }
                value={ content }
                onChange={ ( value ) => setAttributes( { content: value } ) }
                onMerge={ mergeBlocks }
                onSplit={ ( value ) => {
                    if ( ! value ) {
                        return createBlock( 'core/paragraph' );
                    }

                    return createBlock( 'afs/heading',{
                        ...attributes,content: value,} );
                } }
                onReplace={ onReplace }
                onRemove={ () => onReplace( [] ) }
                className={ classnames( {
                    [ `has-text-align-${ align }` ]: align,} ) }
                placeholder={ placeholder || __( 'Write heading…' ) }
                textAlign={ align }
                style={ mergedStyle }
                allowedFormats={ [ 'afs/light','core/link','core/code','core/image','core/strikethrough','core/subscript','core/superscript','core/text-color' ] }
            />
        </div>
    );
}

export default headingEdit;

save.js

/**
 * External dependencies
 */
import classnames from 'classnames';

/**
 * wordpress dependencies
 */
import { RichText } from '@wordpress/block-editor';


export default function save( { attributes } ) {
    const { align,level } = attributes;
    const tagName = 'h' + level;

    const className = classnames( {
        [ `has-text-align-${ align }` ]: align,} );

    return (
        <RichText.Content
            className={ className ? className : undefined }
            tagName={ tagName }
            value={ content }
        />
    );
}

解决方法

即使创建新的Gutenberg块,也需要通过PHP函数注册元字段,参考:https://developer.wordpress.org/block-editor/tutorials/metabox/meta-block-2-register-meta/

如果您已经注册了元字段backgroundColor,则接下来检查 show_in_rest 的属性是否设置为 true ,因为这是使用Gutenberg保存/更新元值的方式。下面是注册元字段backgroundColor所需功能的示例:

<?php 
function afs_heading_register_meta(){
    register_meta( 'post','backgroundColor',array(
      'show_in_rest' => true,'single' => true,'type' => 'string',) );
}
add_action( 'init','afs_heading_register_meta' );
?>

另一个常见问题是帖子类型(或自定义帖子类型)不支持元值-可以通过调用来确认:

<?php post_type_supports( $post_type,'custom-fields' ); ?>

如果您发现自己的帖子类型不支持元值(也称为自定义字段),则可以通过add_post_type_support启用它。

您块中的“内容”已正确保存为源于html的内容,并保存在post_content中。如果backgroundColor属性仅适用于您的块的实例,则也许它也可以另存为一个属性并用作内联样式。