Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transforms: Wrapping transform in core/group fails due to JavaScript errors. #33440

Closed
peterwilsoncc opened this issue Jul 15, 2021 · 3 comments
Labels
[Feature] Widgets Screen The block-based screen that replaced widgets.php. [Package] Edit Widgets /packages/edit-widgets [Type] Help Request Help with setup, implementation, or "How do I?" questions.

Comments

@peterwilsoncc
Copy link
Contributor

Description

When transforming a widget to a core group, JavaScript errors prevent the conversion.

I'm attempting to provide a widget to block transformation for the WP Call Button plugin. As the widget includes a heading and a description, my transformation is to a core group containing three inner blocks. The transform code is available as a gist.

Logging the transform returns the blocks as expected.

{
attributes: { tagName: "div" },
​clientId: "aca5e046-bb3b-4851-8b88-9bd3e36f0798",
innerBlocks: 
  [
​​    { clientId: "9158df41-7628-4f26-b141-24cb153529bd", name: "core/heading", isValid: true, … },
​​    { clientId: "e34049c0-eac3-4056-b8e7-dbdc850fb59f", name: "core/paragraph", isValid: true, … },
​​    { clientId: "4c54a03c-80e7-43ec-be77-df76ce3c5515", name: "wp-call-button/wp-call-button-block", isValid: true, … },
  ],
​​isValid: true,
​name: "core/group",
}​

The block transformation shows in the menu (although hovering doesn't show a preview) but when I click the menu item to transform, the console logs the error Uncaught (in promise) TypeError: can't access property "name", block is null. The error is thrown from this line of the block editor package.

const blockName = block.name;

My plugin's file doesn't show in the stack trace, but I suspect that's because core code is running and using my returned object. I've also tried wrapping a single core/paragraph in the group and the same error occurs.

Step-by-step reproduction instructions

  1. Develop code to transform a legacy widget to a group of blocks
  2. Insert a legacy widget on the new widget screen
  3. Click the legacy widget's transform menu and select the developed transform
  4. Observe the error in the console, nothing will change in the UI

Expected behaviour

A lovely transformation.

Actual behaviour

No change to legacy widget.

Screenshots or screen recording (optional)

transformation

Code snippet (optional)

https://gist.github.com/peterwilsoncc/74d5e1ed58c1d703619ac5245819ded1

WordPress information

  • WordPress version: 5.8 RC3
  • Gutenberg version: Not installed
  • Are all plugins except Gutenberg deactivated? No, using custom widget for transformation
  • Are you using a default theme? Yes, Twenty Twenty-One

Device information

  • Device: Laptop
  • Operating system: macOS Big Sur
  • Browser: Firefox Developer Edition 91.0b1
@Mamaduka Mamaduka added [Feature] Widgets Screen The block-based screen that replaced widgets.php. [Package] Edit Widgets /packages/edit-widgets labels Jul 15, 2021
@talldan
Copy link
Contributor

talldan commented Jul 15, 2021

@peterwilsoncc I think it's because of this:

const hasSwitchedBlock = some(
transformationResults,
( result ) => result.name === name
);
// Ensure that at least one block object returned by the transformation has
// the expected "destination" block type.
if ( ! hasSwitchedBlock ) {
return null;
}

The code checks to see whether the block name (this'll be the name of the block that the transform is declared on) matches one of the blocks in the list returned by the transform function, but it doesn't check inner blocks, which is where your block with the matching name ends up. It essentially makes your transform return null.

I think it's been like this a while, so not a widget editor specific thing, but I see that creating a group like this is a desired feature for the widget editor.

The fact that it throws an obscure error is not great! Seems like this should at least log something and fail more gracefully.

And then potentially it can also check all the way down the block hierarchy for the block name.

@getdave
Copy link
Contributor

getdave commented Aug 9, 2021

@peterwilsoncc To avoid the check Dan references, perhaps you could try the global matcher * for the target blocks.

E.g.

blocks: [ '*' ],

Indeed this is what I have done on the proposed new "Widget Box" block which does something quite similar to what you are trying to achieve:

transforms: {
		from: [
			{
				type: 'block',
				isMultiBlock: true,
				blocks: [ '*' ], // here is the "global" matcher
				__experimentalConvert( blocks ) {
					// Avoid transforming existing `widget-box` blocks.
					const blocksContainWidgetBox = !! blocks.filter(
						( block ) => block.name === 'core/widget-box'
					)?.length;

					if ( blocksContainWidgetBox ) {
						return;
					}

					// Put the selected blocks inside the new Widget Box's innerBlocks.
					// Also include a placeholder for a heading.
					const innerBlocks = [
						createBlock( ...HEADING_PLACEHOLDER ),
						...blocks.map( ( block ) => {
							return createBlock(
								block.name,
								block.attributes,
								block.innerBlocks
							);
						} ),
					];

					return createBlock( 'core/widget-box', {}, innerBlocks );
				},
			},
		],
	},

Note I'm using the __experimentalConvert because it provides access to the entire block objects not just the attributes but you shouldn't need to do that.

I'm curious to see whether this resolves the issue.

@noisysocks noisysocks added this to the WordPress 5.8.1 milestone Aug 30, 2021
@noisysocks noisysocks added the [Type] Help Request Help with setup, implementation, or "How do I?" questions. label Feb 4, 2022
@noisysocks
Copy link
Member

I'm going to close this out as it looks like there were solutions provided. Let me know if that doesn't smell right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Widgets Screen The block-based screen that replaced widgets.php. [Package] Edit Widgets /packages/edit-widgets [Type] Help Request Help with setup, implementation, or "How do I?" questions.
Projects
None yet
Development

No branches or pull requests

6 participants