Skip to content

Conversation

@dougwollison
Copy link
Contributor

What?

This PR enables the transform menu/command to offer multiple transformations for the same block, either eligible variations (via a new "switcher" scope), or named transforms that suit more niche use cases.

Why?

  1. Transforming directly into a desired block variation can be considered a QoL enhancement, but also because some custom block variations may be too specific to count as the active one compared to other variations. For example, a custom Group block variation may apply alignment/style changes, and be independent of the layout settings. At best you can transform it to the desired layout, then select the variation from the transform menu, only for the original to show as still active.

  2. Some more complex blocks could warrant offering multiple transformation results regardless of the source block, particularly if they split/wrap the source block in other blocks. For example, a custom List Grid block that offers transforming the selection into a grid of either Snippet Item blocks or Profile Item blocks.

How?

The getBlockTransformItems selector now returns items based on valid block transformations, not block types with valid transformations, and includes the specific transformation to use. By default, the results will be the same; however, additional items can be listed by one of two means:

  1. A block variation specifies the new "switcher" scope; it will be added if the default transformation option for a block is present.
  2. A block transformation is given a name attribute (and optional title/icon overrides), and will be listed alongside the default one.

The "default" transformation is, as before, the highest priority valid transformation candidate (named ones are not considered).

When selected, the transformation is applied via the new getBlockTransformationResults() utility, which abstracts the results half of switchToBlockType().

In addition, switchToBlockType() now supports a variation argument; it will apply the variation to the transformation results if it exists.

Testing Instructions

  1. Add the following code to your test theme. This registers a Quote block variation using the Plain style, and patches in a alternate columns transformation that takes a heading + any other blocks, and puts them in a 25/75 column layout.
function demo_multiple_transforms_per_block_type() {
	$script = <<<JS
	const { addFilter } = wp.hooks;
	const { registerBlockVariation, createBlock } = wp.blocks;

	registerBlockVariation( 'core/quote', {
		name: 'plain',
		title: 'Plain Quote',
		attributes: {
			className: 'is-style-plain',
		},
		scope: [ 'inserter', 'switcher' ],
		isActive: attributes => attributes.className?.includes( 'is-style-plain' ),
	} );

	const headingContentColumnsTransform = {
		name: 'heading-and-content',
		title: 'Heading + Content Columns',
		type: 'block',
		isMultiBlock: true,
		blocks: [ 'core/heading', '*' ],
		__experimentalConvert: ( blocks ) => {
			const [ heading, ...content ] = blocks;

			return createBlock( 'core/columns', {}, [
				createBlock( 'core/column', { width: '25%' }, [
					createBlock( heading.name, heading.attributes ),
				] ),
				createBlock(
					'core/column',
					{ width: '75%' },
					content.map( ( block ) =>
						createBlock(
							block.name,
							block.attributes,
							block.innerBlocks
						)
					)
				),
			] );
		},
		isMatch( blockAttributes, blocks ) {
			return blocks.length > 1 && blocks[ 0 ].name === 'core/heading';
		},
	};

	addFilter(
		'blocks.registerBlockType',
		'named-transforms/heading-and-content-columns',
		( settings ) => {
			if ( settings.name !== 'core/columns' ) {
				return settings;
			}

			return {
				...settings,
				transforms: {
					from: [
						...settings.transforms.from,
						headingContentColumnsTransform,
					],
					to: settings.transforms.to,
				},
			};
		},
	);
	JS;

	wp_add_inline_script( 'wp-edit-post', $script );
}
add_action( 'enqueue_block_editor_assets', 'demo_multiple_transforms_per_block_type' );
  1. Open the editor to a page.

  2. Select a paragraph block and open the block switcher. The block variation "Plain Quote" will appear as an option. Selecting it should wrap it in a Quote block with the Plain style already applied.

  3. Insert a heading above the paragraph, then select it plus any number of blocks after it. Open the block switcher, the "Columns" transform will appear, but also the "Heading + Content Columns" transform as well. Selecting the latter should create a 2 column layout with the heading in the first and the remaining blocks in the second.

Screenshots or screencast

The Plain Quote variation transform in action.

chrome_CdlzQt7GqO.mp4

The Heading + Content Columns alternative transform in action.

chrome_fOOKBXNZYS.mp4

@dougwollison dougwollison changed the title Allow multiple transform per block type Transforms: Allow multiple transforms per block type Oct 18, 2024
@github-actions
Copy link

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: dougwollison <dougwollison@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

- Block transform options now based on valid block transforms, not block types with valid transforms.
- Alternative transforms, separate from the default one(s), designated by specifying a name, title, and optional icon.
- Includes tranforming directly to variations that opt-in with 'switcher' scope; only listed the default transform for a block is applicable.
@dougwollison dougwollison force-pushed the enhancement/multiple-transforms-per-block-type branch from 3ee7ec8 to d83c9c8 Compare October 23, 2024 13:20
@dougwollison
Copy link
Contributor Author

Resycned branch and fixed the block-switcher test fail I somehow missed. Updated test to include the id in the mockImplementation since the items are now keyed with that.

@Mamaduka Mamaduka added [Type] Enhancement A suggestion for improvement. [Feature] Block Transforms Block transforms from one block to another labels Jan 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] Block Transforms Block transforms from one block to another [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants