From 09726076cbee8f2cb55af3a159ddb0d9a6c5ed98 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 27 Nov 2023 10:53:20 +1300 Subject: [PATCH 1/6] Add a new block editing mode of `syncedPattern` and disable editing of children if this is set --- packages/block-editor/README.md | 3 ++- .../src/components/block-editing-mode/index.js | 5 +++-- packages/block-editor/src/components/block-list/block.js | 7 +++++-- .../src/components/block-list/use-in-between-inserter.js | 3 ++- packages/block-editor/src/components/block-lock/modal.js | 2 +- .../block-editor/src/components/block-toolbar/index.js | 6 ++++-- .../src/components/block-tools/block-contextual-toolbar.js | 4 +++- packages/block-editor/src/components/list-view/block.js | 4 +++- packages/block-library/src/block/edit.js | 2 ++ 9 files changed, 25 insertions(+), 11 deletions(-) diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 2d6a5627a52a44..210babd78f63f5 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -867,13 +867,14 @@ function MyBlock( { attributes, setAttributes } ) { } ``` -`mode` can be one of three options: +`mode` can be one of four options: - `'disabled'`: Prevents editing the block entirely, i.e. it cannot be selected. - `'contentOnly'`: Hides all non-content UI, e.g. auxiliary controls in the toolbar, the block movers, block settings. - `'default'`: Allows editing the block as normal. +- `'syncedPattern'`: Restricts editing of pattern block entities to only child blocks that have attribute connections set. The mode is inherited by all of the block's inner blocks, unless they have their own mode. diff --git a/packages/block-editor/src/components/block-editing-mode/index.js b/packages/block-editor/src/components/block-editing-mode/index.js index 5d916d9816e606..e457c9d79febf9 100644 --- a/packages/block-editor/src/components/block-editing-mode/index.js +++ b/packages/block-editor/src/components/block-editing-mode/index.js @@ -11,7 +11,7 @@ import { store as blockEditorStore } from '../../store'; import { BlockListBlockContext } from '../block-list/block-list-block-context'; /** - * @typedef {'disabled'|'contentOnly'|'default'} BlockEditingMode + * @typedef {'disabled'|'contentOnly'|'default'|'syncedPattern'} BlockEditingMode */ /** @@ -26,13 +26,14 @@ import { BlockListBlockContext } from '../block-list/block-list-block-context'; * } * ``` * - * `mode` can be one of three options: + * `mode` can be one of four options: * * - `'disabled'`: Prevents editing the block entirely, i.e. it cannot be * selected. * - `'contentOnly'`: Hides all non-content UI, e.g. auxiliary controls in the * toolbar, the block movers, block settings. * - `'default'`: Allows editing the block as normal. + * - `'syncedPattern'`: Restricts editing of pattern block entities to only child blocks that have attribute connections set. * * The mode is inherited by all of the block's inner blocks, unless they have * their own mode. diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js index a95075c6f9b42c..7e2246fff21cd5 100644 --- a/packages/block-editor/src/components/block-list/block.js +++ b/packages/block-editor/src/components/block-list/block.js @@ -113,6 +113,8 @@ function BlockListBlock( { ); const { removeBlock } = useDispatch( blockEditorStore ); const onRemove = useCallback( () => removeBlock( clientId ), [ clientId ] ); + const isSyncedPatternChild = + name !== 'core/block' && blockEditingMode === 'syncedPattern'; const parentLayout = useLayout() || {}; @@ -142,7 +144,7 @@ function BlockListBlock( { const blockType = getBlockType( name ); - if ( blockEditingMode === 'disabled' ) { + if ( blockEditingMode === 'disabled' || isSyncedPatternChild ) { wrapperProps = { ...wrapperProps, tabIndex: -1, @@ -216,7 +218,8 @@ function BlockListBlock( { clientId, className: classnames( { - 'is-editing-disabled': blockEditingMode === 'disabled', + 'is-editing-disabled': + blockEditingMode === 'disabled' || isSyncedPatternChild, 'is-content-locked-temporarily-editing-as-blocks': isTemporarilyEditingAsBlocks, }, diff --git a/packages/block-editor/src/components/block-list/use-in-between-inserter.js b/packages/block-editor/src/components/block-list/use-in-between-inserter.js index a60453716ff29c..3effeb6d6b1aac 100644 --- a/packages/block-editor/src/components/block-list/use-in-between-inserter.js +++ b/packages/block-editor/src/components/block-list/use-in-between-inserter.js @@ -75,7 +75,8 @@ export function useInBetweenInserter() { if ( getTemplateLock( rootClientId ) || - getBlockEditingMode( rootClientId ) === 'disabled' + getBlockEditingMode( rootClientId ) === 'disabled' || + getBlockEditingMode( rootClientId ) === 'syncedPattern' ) { return; } diff --git a/packages/block-editor/src/components/block-lock/modal.js b/packages/block-editor/src/components/block-lock/modal.js index cfafa6c031bbd1..c08159faa05fd6 100644 --- a/packages/block-editor/src/components/block-lock/modal.js +++ b/packages/block-editor/src/components/block-lock/modal.js @@ -25,7 +25,7 @@ import useBlockDisplayInformation from '../use-block-display-information'; import { store as blockEditorStore } from '../../store'; // Entity based blocks which allow edit locking -const ALLOWS_EDIT_LOCKING = [ 'core/block', 'core/navigation' ]; +const ALLOWS_EDIT_LOCKING = [ 'core/navigation' ]; function getTemplateLockValue( lock ) { // Prevents all operations. diff --git a/packages/block-editor/src/components/block-toolbar/index.js b/packages/block-editor/src/components/block-toolbar/index.js index 963cd8a475328a..239b677fa04ad6 100644 --- a/packages/block-editor/src/components/block-toolbar/index.js +++ b/packages/block-editor/src/components/block-toolbar/index.js @@ -91,6 +91,7 @@ const BlockToolbar = ( { hideDragHandle } ) => { const isSynced = isReusableBlock( blockType ) || isTemplatePart( blockType ); + const isSyncedPattern = isReusableBlock( blockType ); const classes = classnames( 'block-editor-block-toolbar', { 'is-synced': isSynced, } ); @@ -101,7 +102,8 @@ const BlockToolbar = ( { hideDragHandle } ) => { isLargeViewport && blockEditingMode === 'default' && } { ( shouldShowVisualToolbar || isMultiToolbar ) && - blockEditingMode === 'default' && ( + ( blockEditingMode === 'default' || + blockEditingMode === 'syncedPattern' ) && (
@@ -148,7 +150,7 @@ const BlockToolbar = ( { hideDragHandle } ) => { ) } - { blockEditingMode === 'default' && ( + { ( blockEditingMode === 'default' || isSyncedPattern ) && ( ) }
diff --git a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js index b24a25ee60ed42..670f2f39bfe5f5 100644 --- a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js +++ b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js @@ -70,7 +70,9 @@ export default function BlockContextualToolbar( { const hasAnyBlockControls = useHasAnyBlockControls(); if ( ! isToolbarEnabled || - ( blockEditingMode !== 'default' && ! hasAnyBlockControls ) + ( blockEditingMode !== 'syncedPattern' && + blockEditingMode !== 'default' && + ! hasAnyBlockControls ) ) { return null; } diff --git a/packages/block-editor/src/components/list-view/block.js b/packages/block-editor/src/components/list-view/block.js index 4957f79fa0d481..1bab5a69a9906d 100644 --- a/packages/block-editor/src/components/list-view/block.js +++ b/packages/block-editor/src/components/list-view/block.js @@ -89,7 +89,9 @@ function ListViewBlock( { // List View respects this by also hiding the block settings menu. hasBlockSupport( blockName, '__experimentalToolbar', true ) && // Don't show the settings menu if block is disabled or content only. - blockEditingMode === 'default'; + ( blockEditingMode === 'default' || + ( blockName === 'core/block' && + blockEditingMode === 'syncedPattern' ) ); const instanceId = useInstanceId( ListViewBlock ); const descriptionId = `list-view-block-select-button__${ instanceId }`; const blockPositionDescription = getBlockPositionDescription( diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 979ae04c62282c..cc4f04ff2be0c9 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -27,6 +27,7 @@ import { useBlockProps, Warning, privateApis as blockEditorPrivateApis, + useBlockEditingMode, } from '@wordpress/block-editor'; import { useRef, useMemo } from '@wordpress/element'; @@ -72,6 +73,7 @@ export default function ReusableBlockEdit( { attributes: { ref }, __unstableParentLayout: parentLayout, } ) { + useBlockEditingMode( 'syncedPattern' ); const hasAlreadyRendered = useHasRecursion( ref ); const { record, hasResolved } = useEntityRecord( 'postType', From 04623928b707196292977ae272343ae9289cf8a1 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 27 Nov 2023 11:25:39 +1300 Subject: [PATCH 2/6] Add link to edit pattern --- packages/block-library/src/block/edit.js | 39 ++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index cc4f04ff2be0c9..510ea3cda63851 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -10,12 +10,16 @@ import { useEntityBlockEditor, useEntityProp, useEntityRecord, + store as coreStore, } from '@wordpress/core-data'; +import { useSelect } from '@wordpress/data'; import { Placeholder, Spinner, TextControl, PanelBody, + ToolbarButton, + ToolbarGroup, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { @@ -28,8 +32,12 @@ import { Warning, privateApis as blockEditorPrivateApis, useBlockEditingMode, + BlockControls, + store as editorStore, } from '@wordpress/block-editor'; + import { useRef, useMemo } from '@wordpress/element'; +import { addQueryArgs } from '@wordpress/url'; /** * Internal dependencies @@ -73,6 +81,30 @@ export default function ReusableBlockEdit( { attributes: { ref }, __unstableParentLayout: parentLayout, } ) { + const editUrl = useSelect( + ( select ) => { + const { canUser } = select( coreStore ); + const { getSettings } = select( editorStore ); + + const isBlockTheme = getSettings().__unstableIsBlockBasedTheme; + const defaultUrl = addQueryArgs( 'post.php', { + action: 'edit', + post: ref, + } ); + const siteEditorUrl = addQueryArgs( 'site-editor.php', { + postType: 'wp_block', + postId: ref, + categoryType: 'pattern', + canvas: 'edit', + } ); + + // For editing link to the site editor if the theme and user permissions support it + return canUser( 'read', 'templates' ) && isBlockTheme + ? siteEditorUrl + : defaultUrl; + }, + [ ref ] + ); useBlockEditingMode( 'syncedPattern' ); const hasAlreadyRendered = useHasRecursion( ref ); const { record, hasResolved } = useEntityRecord( @@ -143,6 +175,13 @@ export default function ReusableBlockEdit( { return ( + + + + { __( 'Edit' ) } + + + Date: Mon, 27 Nov 2023 11:28:54 +1300 Subject: [PATCH 3/6] Add . --- packages/block-library/src/block/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 510ea3cda63851..723a10f0bc8638 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -98,7 +98,7 @@ export default function ReusableBlockEdit( { canvas: 'edit', } ); - // For editing link to the site editor if the theme and user permissions support it + // For editing link to the site editor if the theme and user permissions support it. return canUser( 'read', 'templates' ) && isBlockTheme ? siteEditorUrl : defaultUrl; From 829f86a82a67694edca0c3954104221cd95bcaab Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 27 Nov 2023 15:51:22 +1300 Subject: [PATCH 4/6] Prevent editing of children from listview --- packages/block-editor/src/components/list-view/block.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/list-view/block.js b/packages/block-editor/src/components/list-view/block.js index 1bab5a69a9906d..591057a4de036c 100644 --- a/packages/block-editor/src/components/list-view/block.js +++ b/packages/block-editor/src/components/list-view/block.js @@ -245,7 +245,9 @@ function ListViewBlock( { path={ path } id={ `list-view-${ listViewInstanceId }-block-${ clientId }` } data-block={ clientId } - data-expanded={ canEdit ? isExpanded : undefined } + data-expanded={ + canEdit && blockName !== 'core/block' ? isExpanded : undefined + } ref={ rowRef } > Date: Mon, 27 Nov 2023 16:03:09 +1300 Subject: [PATCH 5/6] Update doc comment --- packages/block-editor/README.md | 2 +- .../block-editor/src/components/block-editing-mode/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 210babd78f63f5..990148cbc855f3 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -874,7 +874,7 @@ function MyBlock( { attributes, setAttributes } ) { - `'contentOnly'`: Hides all non-content UI, e.g. auxiliary controls in the toolbar, the block movers, block settings. - `'default'`: Allows editing the block as normal. -- `'syncedPattern'`: Restricts editing of pattern block entities to only child blocks that have attribute connections set. +- `'syncedPattern'`: Restricts editing of synced pattern blocks to only child blocks that have attribute connections set. The mode is inherited by all of the block's inner blocks, unless they have their own mode. diff --git a/packages/block-editor/src/components/block-editing-mode/index.js b/packages/block-editor/src/components/block-editing-mode/index.js index e457c9d79febf9..5a40604d0eaa5a 100644 --- a/packages/block-editor/src/components/block-editing-mode/index.js +++ b/packages/block-editor/src/components/block-editing-mode/index.js @@ -33,7 +33,7 @@ import { BlockListBlockContext } from '../block-list/block-list-block-context'; * - `'contentOnly'`: Hides all non-content UI, e.g. auxiliary controls in the * toolbar, the block movers, block settings. * - `'default'`: Allows editing the block as normal. - * - `'syncedPattern'`: Restricts editing of pattern block entities to only child blocks that have attribute connections set. + * - `'syncedPattern'`: Restricts editing of synced pattern blocks to only child blocks that have attribute connections set. * * The mode is inherited by all of the block's inner blocks, unless they have * their own mode. From 4229cbed90773f709ee2604fe17520b0f4ee7493 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 27 Nov 2023 20:02:41 +1300 Subject: [PATCH 6/6] Add a back link to header in site editor --- packages/block-library/src/block/block.json | 1 + packages/block-library/src/block/edit.js | 4 +++- .../components/header-edit-mode/document-actions/index.js | 8 ++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/block/block.json b/packages/block-library/src/block/block.json index aeccdbfc1051db..21ab21b8ee251a 100644 --- a/packages/block-library/src/block/block.json +++ b/packages/block-library/src/block/block.json @@ -6,6 +6,7 @@ "category": "reusable", "description": "Create and save content to reuse across your site. Update the pattern, and the changes apply everywhere it’s used.", "keywords": [ "reusable" ], + "usesContext": [ "postId" ], "textdomain": "default", "attributes": { "ref": { diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 723a10f0bc8638..f20b1eace1d339 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -80,6 +80,7 @@ export default function ReusableBlockEdit( { name, attributes: { ref }, __unstableParentLayout: parentLayout, + context: { postId }, } ) { const editUrl = useSelect( ( select ) => { @@ -96,6 +97,7 @@ export default function ReusableBlockEdit( { postId: ref, categoryType: 'pattern', canvas: 'edit', + refererId: postId, } ); // For editing link to the site editor if the theme and user permissions support it. @@ -103,7 +105,7 @@ export default function ReusableBlockEdit( { ? siteEditorUrl : defaultUrl; }, - [ ref ] + [ postId, ref ] ); useBlockEditingMode( 'syncedPattern' ); const hasAlreadyRendered = useHasRecursion( ref ); diff --git a/packages/edit-site/src/components/header-edit-mode/document-actions/index.js b/packages/edit-site/src/components/header-edit-mode/document-actions/index.js index 132dbcb249ffb3..e9960657053a1a 100644 --- a/packages/edit-site/src/components/header-edit-mode/document-actions/index.js +++ b/packages/edit-site/src/components/header-edit-mode/document-actions/index.js @@ -27,6 +27,7 @@ import { displayShortcut } from '@wordpress/keycodes'; import { store as coreStore } from '@wordpress/core-data'; import { store as editorStore } from '@wordpress/editor'; import { useRef, useState, useEffect } from '@wordpress/element'; +import { getQueryArgs } from '@wordpress/url'; /** * Internal dependencies @@ -144,6 +145,13 @@ function TemplateDocumentActions( { className, onBack } ) { typeIcon = symbol; } + const { refererId } = getQueryArgs( window.location.href ); + + if ( ! onBack && refererId ) { + onBack = () => + ( document.location = `post.php?post=${ refererId }&action=edit` ); + } + return (