extend-block-example-wp-plugin icon indicating copy to clipboard operation
extend-block-example-wp-plugin copied to clipboard

Block validation fails

Open amuscalu opened this issue 5 years ago • 0 comments

Hello,

Thank you for this example, it has helped allot on extending multiple gutenberg blocks and adding more options to them.

I’m facing issue with block validation on certain blocks after removing the tests for the core/image block, for example on woocommerce/all-products block added with WooCommerce Blocks as seen in the video attached.

The error generated in the console are:

blocks.js?ver=423068d7079f57cf9f02458ccb4a6131:8778 Block validation: Expected attributes Array(2), instead saw Array(3).
log @ blocks.js?ver=423068d7079f57cf9f02458ccb4a6131:8778
blocks.js?ver=423068d7079f57cf9f02458ccb4a6131:8778 Block validation: Block validation failed for `woocommerce/all-products` (Object).

Content generated by `save` function:

<div class="wp-block-woocommerce-all-products wc-block-all-products has-spacing-large" data-attributes="{&quot;alignButtons&quot;:false,&quot;className&quot;:&quot;has-spacing-large&quot;,&quot;columns&quot;:3,&quot;contentVisibility&quot;:{&quot;orderBy&quot;:true},&quot;isPreview&quot;:false,&quot;layoutConfig&quot;:[[&quot;woocommerce/product-image&quot;],[&quot;woocommerce/product-title&quot;],[&quot;woocommerce/product-price&quot;],[&quot;woocommerce/product-rating&quot;],[&quot;woocommerce/product-button&quot;]],&quot;orderby&quot;:&quot;date&quot;,&quot;rows&quot;:3}"></div>

Content retrieved from post body:

<div class="wp-block-woocommerce-all-products wc-block-all-products has-spacing-large" data-attributes="{&quot;alignButtons&quot;:false,&quot;className&quot;:&quot;has-spacing-large&quot;,&quot;columns&quot;:3,&quot;contentVisibility&quot;:{&quot;orderBy&quot;:true},&quot;isPreview&quot;:false,&quot;layoutConfig&quot;:[[&quot;woocommerce/product-image&quot;],[&quot;woocommerce/product-title&quot;],[&quot;woocommerce/product-price&quot;],[&quot;woocommerce/product-rating&quot;],[&quot;woocommerce/product-button&quot;]],&quot;orderby&quot;:&quot;date&quot;,&quot;rows&quot;:3,&quot;spacing&quot;:&quot;large&quot;}" style="margin-bottom:30px"></div>

Plugin is exactly the same, only difference is commenting out the test for the single core/image block inside the spacing-control.js

import assign from 'lodash.assign';

const { createHigherOrderComponent } = wp.compose;
const { Fragment } = wp.element;
const { InspectorControls } = wp.blockEditor;
const { PanelBody, SelectControl } = wp.components;
const { addFilter } = wp.hooks;
const { __ } = wp.i18n;

// Enable spacing control on the following blocks
const enableSpacingControlOnBlocks = [
	'core/image',
];

// Available spacing control options
const spacingControlOptions = [
	{
		label: __( 'None' ),
		value: '',
	},
	{
		label: __( 'Small' ),
		value: 'small',
	},
	{
		label: __( 'Medium' ),
		value: 'medium',
	},
	{
		label: __( 'Large' ),
		value: 'large',
	},
];

/**
 * Add spacing control attribute to block.
 *
 * @param {object} settings Current block settings.
 * @param {string} name Name of block.
 *
 * @returns {object} Modified block settings.
 */
const addSpacingControlAttribute = ( settings, name ) => {
	// Do nothing if it's another block than our defined ones.
	/* if ( ! enableSpacingControlOnBlocks.includes( name ) ) {
		return settings;
	} */

	// Use Lodash's assign to gracefully handle if attributes are undefined
	settings.attributes = assign( settings.attributes, {
		spacing: {
			type: 'string',
			default: spacingControlOptions[ 0 ].value,
		},
	} );

	return settings;
};

addFilter( 'blocks.registerBlockType', 'extend-block-example/attribute/spacing', addSpacingControlAttribute );

/**
 * Create HOC to add spacing control to inspector controls of block.
 */
const withSpacingControl = createHigherOrderComponent( ( BlockEdit ) => {
	return ( props ) => {
		// Do nothing if it's another block than our defined ones.
		/* if ( ! enableSpacingControlOnBlocks.includes( props.name ) ) {
			return (
				<BlockEdit { ...props } />
			);
		} */

		const { spacing } = props.attributes;

		// add has-spacing-xy class to block
		if ( spacing ) {
			props.attributes.className = `has-spacing-${ spacing }`;
		}

		return (
			<Fragment>
				<BlockEdit { ...props } />
				<InspectorControls>
					<PanelBody
						title={ __( 'My Spacing Control' ) }
						initialOpen={ true }
					>
						<SelectControl
							label={ __( 'Spacing' ) }
							value={ spacing }
							options={ spacingControlOptions }
							onChange={ ( selectedSpacingOption ) => {
								props.setAttributes( {
									spacing: selectedSpacingOption,
								} );
							} }
						/>
					</PanelBody>
				</InspectorControls>
			</Fragment>
		);
	};
}, 'withSpacingControl' );

addFilter( 'editor.BlockEdit', 'extend-block-example/with-spacing-control', withSpacingControl );

/**
 * Add margin style attribute to save element of block.
 *
 * @param {object} saveElementProps Props of save element.
 * @param {Object} blockType Block type information.
 * @param {Object} attributes Attributes of block.
 *
 * @returns {object} Modified props of save element.
 */
const addSpacingExtraProps = ( saveElementProps, blockType, attributes ) => {
	// Do nothing if it's another block than our defined ones.
	/* if ( ! enableSpacingControlOnBlocks.includes( blockType.name ) ) {
		return saveElementProps;
	} */

	const margins = {
		small: '5px',
		medium: '15px',
		large: '30px',
	};

	if ( attributes.spacing in margins ) {
		// Use Lodash's assign to gracefully handle if attributes are undefined
		assign( saveElementProps, { style: { 'margin-bottom': margins[ attributes.spacing ] } } );
	}

	return saveElementProps;
};

addFilter( 'blocks.getSaveContent.extraProps', 'extend-block-example/get-save-content/extra-props', addSpacingExtraProps );

Any advices on how to tweak this plugin to fix validation issues ?

Screenshot 2020-07-22 at 16 01 53

screencast 2020-07-22 15-51-23

amuscalu avatar Jul 22 '20 15:07 amuscalu