Modify save function of block

Sometimes there is a block for the WordPress block editor that is almost what we want, but it would be necessary to modify the markup it saves to the database. This post shows how we can filter the save function of a block to get that done.

Update from March 8, 2019: Under the German version of the article, Julian wrote a comment in which he says that you need to pay attention to not modify selectors that the block uses for getting attribute values.

So if, for example, a gallery block uses an element with the class gallery-item to get the attribute values for the images, you must not modify that class, because that would result in an error in the editor.

Recently I used the container block from the Stackable plugin but was not happy with a few styles it comes with. My first plan was to deregister the CSS file of the plugin and enqueue a modified version. But then I decided to just remove a – for me – unnecessary wrapper element that is used by the unwanted styles.

There are several block filters for hooking into blocks, one of them is blocks.getSaveElement to modify the save function. Stackable has a GitHub repo that lets us get the original save function of the Container block easily, and we take the code between the curly brackets as a starting point for our modifications.

This is the final code:

import {
	getColorObjectByColorValue,
	getColorClassName,
} from '@wordpress/editor'
import classnames from 'classnames'

function slugGetSaveElement( element, blockType, attributes ) {
	if ( blockType.name !== 'ugb/container' ) {
		return element;
	}

	if ( blockType.name === 'ugb/container' ) {
		const {
			className,
		} = element.props
	
		const {
			textColor,
			backgroundColor,
		} = attributes

		let hasTextColor = false,
			textColorClass = '',
			hasBackgroundColor = false,
			backgroundColorClass = '';

		const textColorObj = getColorObjectByColorValue( backgroundColors, textColor );
		const backgroundColorObj = getColorObjectByColorValue( backgroundColors, backgroundColor );

		if ( textColorObj !== undefined ) {
			hasTextColor = true;
			textColorClass = getColorClassName( 'color', textColorObj.slug );
		}

		if ( backgroundColorObj !== undefined ) {
			hasBackgroundColor = true;
			backgroundColorClass = getColorClassName( 'background-color', backgroundColorObj.slug );
		}
	
		const mainClasses = classnames(
			'ugb-container', {
				[ textColorClass ]: hasTextColor,
				[ backgroundColorClass ]: hasBackgroundColor,
			}
		)
	
		return (
			<div className={ mainClasses }>
				<div className="ugb-container__wrapper">
					<InnerBlocks.Content />
				</div>
			</div>
		)
	}
}

wp.hooks.addFilter(
	'blocks.getSaveElement',
	'slug/get-save-element',
	slugGetSaveElement
);

First, we test for the block name to only modify the save function of the wanted block. If we have the wanted block, the following modifications are made compared to the block’s original save function:

I removed a lot of the code that handles the class names and inline styles, because I do not need them, and replaced them with classes for text and background color. The props object that is used in the original function is available via element.props in our function, props.attributes via attributes.

Then I removed the div with the class ugb-container__content-wrapper, and that’s it.

Related posts

Leave a Comment

Your email address will not be published. Required fields are marked *