-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Register each reference widget as a separate block #25741
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { pickBy, isEmpty, map } from 'lodash'; | ||
import { isEmpty, map, some } from 'lodash'; | ||
|
||
/** | ||
* WordPress dependencies | ||
|
@@ -11,17 +11,44 @@ import { __ } from '@wordpress/i18n'; | |
import { SelectControl, Placeholder } from '@wordpress/components'; | ||
import { BlockIcon } from '@wordpress/block-editor'; | ||
import { brush } from '@wordpress/icons'; | ||
import { useSelect } from '@wordpress/data'; | ||
|
||
export default function LegacyWidgetPlaceholder( { | ||
availableLegacyWidgets, | ||
currentWidget, | ||
hasPermissionsToManageWidgets, | ||
onChangeWidget, | ||
} ) { | ||
const visibleLegacyWidgets = useMemo( | ||
() => pickBy( availableLegacyWidgets, ( { isHidden } ) => ! isHidden ), | ||
[ availableLegacyWidgets ] | ||
const blocksByClientId = useSelect( ( select ) => | ||
select( 'core/block-editor' ).getBlocksByClientId( | ||
select( 'core/block-editor' ).getClientIdsWithDescendants() | ||
) | ||
); | ||
|
||
const visibleLegacyWidgets = useMemo( () => { | ||
const visible = {}; | ||
for ( const widgetName in availableLegacyWidgets ) { | ||
const { | ||
isReferenceWidget, | ||
blockName, | ||
isHidden, | ||
} = availableLegacyWidgets[ widgetName ]; | ||
if ( isHidden ) { | ||
continue; | ||
} | ||
if ( isReferenceWidget ) { | ||
const blockExists = some( blocksByClientId, { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's probably a nicer way to do this using |
||
name: blockName, | ||
} ); | ||
if ( blockExists ) { | ||
continue; | ||
} | ||
} | ||
visible[ widgetName ] = availableLegacyWidgets[ widgetName ]; | ||
} | ||
return visible; | ||
}, [ availableLegacyWidgets, blocksByClientId ] ); | ||
|
||
let placeholderContent; | ||
if ( ! hasPermissionsToManageWidgets ) { | ||
placeholderContent = __( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
* WordPress dependencies | ||
*/ | ||
import { widget as icon } from '@wordpress/icons'; | ||
import { __ } from '@wordpress/i18n'; | ||
import { __, sprintf } from '@wordpress/i18n'; | ||
|
||
/** | ||
* Internal dependencies | ||
|
@@ -23,6 +23,12 @@ export const settings = { | |
transforms, | ||
}; | ||
|
||
const blockBasis = { | ||
metadata, | ||
name, | ||
settings, | ||
}; | ||
|
||
/** | ||
* Special factory function created specifically for the legacy-widget block. For every other block, JS module exports | ||
* are used for registration. In case of this special block, the return value of the create function is used instead. | ||
|
@@ -34,49 +40,74 @@ export const settings = { | |
* @return {Object} Block object. | ||
*/ | ||
export const create = ( editorSettings ) => { | ||
const legacyWidgets = editorSettings?.availableLegacyWidgets ?? {}; | ||
const legacyWidgets = Object.entries( | ||
editorSettings.availableLegacyWidgets | ||
).filter( ( [ , widget ] ) => ! widget.isHidden ); | ||
|
||
return [ | ||
{ | ||
...blockBasis, | ||
settings: { | ||
...blockBasis.settings, | ||
variations: legacyWidgets | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we go all in with the block per widget approach so that there's only one type of block to test and debug? |
||
.filter( ( [ , widget ] ) => ! widget.isReferenceWidget ) | ||
.map( ( [ className, widget ] ) => | ||
legacyWidgetToBlockVariation( className, widget ) | ||
), | ||
}, | ||
}, | ||
...legacyWidgets | ||
.filter( ( [ , widget ] ) => widget.isReferenceWidget ) | ||
.map( ( [ className, widget ] ) => | ||
referenceLegacyWidgetsToBlockType( className, widget ) | ||
), | ||
]; | ||
}; | ||
|
||
function referenceLegacyWidgetsToBlockType( className, widget ) { | ||
const attrs = blockBasis.metadata.attributes; | ||
return { | ||
metadata, | ||
name, | ||
...blockBasis, | ||
name: widget.blockName, | ||
metadata: { | ||
...blockBasis.metadata, | ||
name: widget.blockName, | ||
supports: { | ||
...blockBasis.metadata.supports, | ||
multiple: false, | ||
}, | ||
attributes: { | ||
...attrs, | ||
referenceWidgetName: { | ||
...attrs.referenceWidgetName, | ||
default: className, | ||
}, | ||
instance: { | ||
...attrs.instance, | ||
default: {}, | ||
}, | ||
}, | ||
}, | ||
Comment on lines
+70
to
+90
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe it's time we bring Or before that happens, could we just |
||
settings: { | ||
...settings, | ||
variations: legacyWidgetsToBlockVariations( legacyWidgets ), | ||
...blockBasis.settings, | ||
title: widget.name, | ||
// translators: %s: widget label e.g: "Marquee". | ||
description: sprintf( __( 'Displays a %s widget' ), widget.name ), | ||
}, | ||
}; | ||
}; | ||
|
||
function legacyWidgetsToBlockVariations( availableLegacyWidgets ) { | ||
const variations = []; | ||
for ( const className in availableLegacyWidgets ) { | ||
const widget = availableLegacyWidgets[ className ]; | ||
if ( widget.isHidden ) { | ||
continue; | ||
} | ||
variations.push( legacyWidgetToBlockVariation( className, widget ) ); | ||
} | ||
return variations; | ||
} | ||
|
||
function legacyWidgetToBlockVariation( className, widget ) { | ||
const blockVariation = { | ||
attributes: {}, | ||
return { | ||
attributes: { | ||
idBase: widget.id_base, | ||
widgetClass: className, | ||
instance: {}, | ||
}, | ||
category: 'widgets', | ||
description: widget.description, | ||
icon: settings.icon, | ||
name: className, | ||
title: widget.name, | ||
}; | ||
if ( widget.isReferenceWidget ) { | ||
blockVariation.attributes = { | ||
referenceWidgetName: className, | ||
instance: {}, | ||
}; | ||
} else { | ||
blockVariation.attributes = { | ||
idBase: widget.id_base, | ||
widgetClass: className, | ||
instance: {}, | ||
}; | ||
} | ||
return blockVariation; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,12 +9,22 @@ | |
* Register legacy widget block. | ||
*/ | ||
function register_block_core_legacy_widget() { | ||
register_block_type_from_metadata( | ||
$block_type = register_block_type_from_metadata( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does using block metadata give us anything at this point? Should we do away with registering the block using metadata altogether and use |
||
__DIR__ . '/legacy-widget', | ||
array( | ||
'render_callback' => 'render_block_core_legacy_widget', | ||
) | ||
); | ||
$settings = gutenberg_get_legacy_widget_settings(); | ||
$legacy_widgets = $settings['availableLegacyWidgets']; | ||
foreach ( $legacy_widgets as $widget_id => $legacy_widget ) { | ||
if ( ! $legacy_widget['isReferenceWidget'] ) { | ||
continue; | ||
} | ||
$legacy_block = clone $block_type; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Personally I'd find |
||
$legacy_block->name = $legacy_widget['blockName']; | ||
WP_Block_Type_Registry::get_instance()->register( $legacy_block ); | ||
} | ||
} | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we've ever done this but I wonder if we should use sub-namespaces here? In other words, the name would be
core/legacy-widget/marquee
.