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

Experimental: try new "Widget Group" block to act as container for Widgets #33881

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
528568b
Register new Widget box block for Widgets screen only
getdave Aug 4, 2021
64d5bdc
Better mirror legacy markup for Widgets
getdave Aug 5, 2021
a8b172e
Remove hardcoded class as not needed
getdave Aug 5, 2021
43372b8
Move Widget Box block to widgets package and update registration
getdave Aug 5, 2021
765c72a
Register block in Widget Customizer and allow to appear
getdave Aug 5, 2021
ceb16cf
Utilise block appender style
getdave Aug 5, 2021
3f89a7f
Remove unnecessary /edit subfolder
getdave Aug 5, 2021
f0fef9b
Add transform for any block to allow it to be wrapped in a Widget Box
getdave Aug 5, 2021
1c5d054
Initial attempt at RichText
getdave Aug 5, 2021
1a64c57
Rename misnamed method on filter
getdave Aug 5, 2021
c692d54
Add onReplace and identifier props to RichText in widget box block
talldan Aug 9, 2021
a8cac1b
Improving self documenting code for allowing only single line for Wid…
getdave Aug 9, 2021
83d199d
Remove restriction to limit Widget Box to being child of Widget Area
getdave Aug 9, 2021
69351c1
Rename `widgetTitle` to `title` and update the block.json
getdave Aug 9, 2021
69a9ddc
Update transform to convert preexisting heading blocks to the widget …
getdave Aug 9, 2021
c83a223
Allow richtext to split without overwritng the Widget Box
getdave Aug 9, 2021
a9cd341
Attempt to make block dynamic
getdave Aug 10, 2021
1babfd7
Register the WIdget Box server side
getdave Aug 10, 2021
ff602a7
Render inner blocks on server side
tellthemachines Aug 11, 2021
6db4b04
Rename to Widget Group, render before_title and after_title dynamically
noisysocks Aug 12, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,11 @@ function gutenberg_reregister_core_block_types() {
__DIR__ . '/../build/widgets/blocks/' => array(
'block_folders' => array(
'legacy-widget',
'widget-box',
),
'block_names' => array(
'legacy-widget.php' => 'core/legacy-widget',
'widget-box.php' => 'core/widget-box',
),
),
);
Expand Down
2 changes: 2 additions & 0 deletions packages/customize-widgets/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import {
registerLegacyWidgetBlock,
registerLegacyWidgetVariations,
registerWidgetBoxBlock,
} from '@wordpress/widgets';
import { setFreeformContentHandlerName } from '@wordpress/blocks';

Expand Down Expand Up @@ -49,6 +50,7 @@ export function initialize( editorName, blockEditorSettings ) {
} );
}
registerLegacyWidgetVariations( blockEditorSettings );
registerWidgetBoxBlock();

// As we are unregistering `core/freeform` to avoid the Classic block, we must
// replace it with something as the default freeform content handler. Failure to
Expand Down
4 changes: 4 additions & 0 deletions packages/edit-widgets/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { __experimentalFetchLinkSuggestions as fetchLinkSuggestions } from '@wor
import {
registerLegacyWidgetBlock,
registerLegacyWidgetVariations,
registerWidgetBoxBlock,
} from '@wordpress/widgets';

/**
Expand All @@ -24,6 +25,7 @@ import {
import './store';
import './filters';
import * as widgetArea from './blocks/widget-area';

import Layout from './components/layout';
import {
ALLOW_REUSABLE_BLOCKS,
Expand Down Expand Up @@ -80,6 +82,8 @@ export function initialize( id, settings ) {
}
registerLegacyWidgetVariations( settings );
registerBlock( widgetArea );
registerWidgetBoxBlock();

settings.__experimentalFetchLinkSuggestions = ( search, searchOptions ) =>
fetchLinkSuggestions( search, searchOptions, settings );

Expand Down
18 changes: 18 additions & 0 deletions packages/widgets/src/blocks/widget-box/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"apiVersion": 2,
"name": "core/widget-box",
"category": "widgets",
"attributes": {
"title": {
"type": "string"
}
},
"supports": {
"html": false,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we allow this? I guess we ought to. There's no harm right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I would not allow HTML of blocks to be changed in any block in the entire widgets editor.

"inserter": true,
"customClassName": true,
"reusable": false
},
"editorStyle": "wp-block-widget-box-editor",
"style": "wp-block-widget-box"
}
12 changes: 12 additions & 0 deletions packages/widgets/src/blocks/widget-box/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';

export const HEADING_PLACEHOLDER = [
'core/heading',
{
placeholder: __( 'Add your Widget title' ),
className: 'widget-title',
},
];
65 changes: 65 additions & 0 deletions packages/widgets/src/blocks/widget-box/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* WordPress dependencies
*/
import {
__experimentalUseInnerBlocksProps as useInnerBlocksProps,
useBlockProps,
RichText,
store as blockEditorStore,
} from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';
import { createBlock } from '@wordpress/blocks';
import { useDispatch, useSelect } from '@wordpress/data';

export default function Edit( {
attributes,
setAttributes,
clientId,
onReplace,
mergeBlocks,
} ) {
const { getBlock } = useSelect( blockEditorStore );
const { replaceInnerBlocks } = useDispatch( blockEditorStore );

const { innerBlocks } = getBlock( clientId );

const innerBlocksProps = useInnerBlocksProps( {
className: 'wp-widget-box__inner-blocks',
} );

const blockProps = useBlockProps();

/**
* Split RichText on ENTER by manually creating a new paragraph block
* within the innerBlocks of the **existing** Widget Box block.
* If we don't do this then RichText will be split into heading + para
* thereby entirely removint the Widget Box block altogether.
*/
function allowSingleLineOnly() {
replaceInnerBlocks(
clientId,
[ createBlock( 'core/paragraph', {} ), ...innerBlocks ],
true
);
}

return (
<div { ...blockProps }>
<RichText
identifier="content"
className="widget-title"
tagName="h2"
aria-label={ __( 'Widget title' ) }
placeholder={ __( 'Add title' ) }
value={ attributes.title }
onChange={ ( value ) => setAttributes( { title: value } ) }
onReplace={ onReplace }
onMerge={ mergeBlocks }
onSplit={ allowSingleLineOnly }
onRemove={ () => onReplace( [] ) }
{ ...blockProps }
/>
<div { ...innerBlocksProps } />
</div>
);
}
78 changes: 78 additions & 0 deletions packages/widgets/src/blocks/widget-box/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { createBlock } from '@wordpress/blocks';
import { group as icon } from '@wordpress/icons';

/**
* Internal dependencies
*/
import metadata from './block.json';
import edit from './edit';
// eslint-disable-next-line no-unused-vars
import save from './save';
const { name } = metadata;
export { metadata, name };

export const settings = {
title: __( 'Widget Group' ),
description: __( 'A widget container.' ),
icon,
__experimentalLabel: ( { name: label } ) => label,
edit,
save,
transforms: {
from: [
{
type: 'block',
isMultiBlock: true,
blocks: [ '*' ],
__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.
let innerBlocks = [
...blocks.map( ( block ) => {
return createBlock(
block.name,
block.attributes,
block.innerBlocks
);
} ),
];

// If the first block is a heading then assume this is intended
// to be the Widget's "title".
const firstHeadingBlock =
innerBlocks[ 0 ].name === 'core/heading'
? innerBlocks[ 0 ]
: null;

// Remove the first heading block as we're copying
// it's content into the Widget Box's title attribute.
innerBlocks = innerBlocks.filter(
( block ) => block !== firstHeadingBlock
);

return createBlock(
'core/widget-box',
{
...( firstHeadingBlock && {
title: firstHeadingBlock.attributes.content,
} ),
},
innerBlocks
);
},
},
],
},
};
59 changes: 59 additions & 0 deletions packages/widgets/src/blocks/widget-box/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
/**
* Server-side rendering of the `core/widget-box` block.
*
* @package WordPress
*/


function render_block_core_widget_box( $attributes, $content, $block ) {
global $wp_registered_sidebars, $_sidebar_being_rendered;

if ( isset( $wp_registered_sidebars[ $_sidebar_being_rendered ] ) ) {
$before_title = $wp_registered_sidebars[ $_sidebar_being_rendered ]['before_title'];
$after_title = $wp_registered_sidebars[ $_sidebar_being_rendered ]['after_title'];
} else {
$before_title = '<h2 class="widget-title">';
$after_title = '</h2>';
}

$html = '';

if ( ! empty( $attributes['title'] ) ) {
$html .= $before_title . $attributes['title'] . $after_title;
}

$html .= '<div class="wp-widget-box__inner-blocks">';
foreach ( $block->inner_blocks as $inner_block ) {
$html .= $inner_block->render();
}
$html .= '</div>';

return $html;
}

/**
* Registers the 'core/widget-box' block.
*/
function register_block_core_widget_box() {
register_block_type_from_metadata(
__DIR__ . '/widget-box',
array(
'render_callback' => 'render_block_core_widget_box',
)
);
}

add_action( 'init', 'register_block_core_widget_box' );

function note_sidebar_being_rendered( $index ) {
global $_sidebar_being_rendered;
$_sidebar_being_rendered = $index;
}
add_action( 'dynamic_sidebar_before', 'note_sidebar_being_rendered' );

function discard_sidebar_being_rendered( $index ) {
global $_sidebar_being_rendered;
unset( $_sidebar_being_rendered );
}
add_action( 'dynamic_sidebar_after', 'discard_sidebar_being_rendered' );
17 changes: 17 additions & 0 deletions packages/widgets/src/blocks/widget-box/save.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* WordPress dependencies
*/
import { InnerBlocks, RichText } from '@wordpress/block-editor';

export default function save( { attributes } ) {
return (
<>
<RichText.Content
tagName="h2"
className="widget-title"
value={ attributes.title }
/>
<InnerBlocks.Content />
</>
);
}
6 changes: 6 additions & 0 deletions packages/widgets/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { registerBlockType } from '@wordpress/blocks';
* Internal dependencies
*/
import * as legacyWidget from './blocks/legacy-widget';
import * as widgetBox from './blocks/widget-box';

export * from './components';
export * from './utils';
Expand All @@ -24,4 +25,9 @@ export function registerLegacyWidgetBlock() {
registerBlockType( { name, ...metadata }, settings );
}

export function registerWidgetBoxBlock() {
const { metadata, settings, name } = widgetBox;
registerBlockType( { name, ...metadata }, settings );
}

export { default as registerLegacyWidgetVariations } from './register-legacy-widget-variations';