diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js index 0a124995c166ed..b7934216f61d4b 100644 --- a/packages/block-library/src/template-part/edit/index.js +++ b/packages/block-library/src/template-part/edit/index.js @@ -79,7 +79,10 @@ export default function TemplatePartEdit( { return ( { isPlaceholder && ( - + ) } { isTemplateFile && ( diff --git a/packages/block-library/src/template-part/edit/placeholder/index.js b/packages/block-library/src/template-part/edit/placeholder/index.js index 7359538cd00f54..74df19517a0a8f 100644 --- a/packages/block-library/src/template-part/edit/placeholder/index.js +++ b/packages/block-library/src/template-part/edit/placeholder/index.js @@ -2,18 +2,22 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { useCallback } from '@wordpress/element'; +import { useCallback, useEffect } from '@wordpress/element'; import { useDispatch } from '@wordpress/data'; import { cleanForSlug } from '@wordpress/url'; -import { Placeholder, Dropdown, Button } from '@wordpress/components'; +import { Placeholder, Dropdown, Button, Spinner } from '@wordpress/components'; import { blockDefault } from '@wordpress/icons'; +import { serialize } from '@wordpress/blocks'; /** * Internal dependencies */ import TemplatePartSelection from '../selection'; -export default function TemplatePartPlaceholder( { setAttributes } ) { +export default function TemplatePartPlaceholder( { + setAttributes, + innerBlocks, +} ) { const { saveEntityRecord } = useDispatch( 'core' ); const onCreate = useCallback( async () => { const title = 'Untitled Template Part'; @@ -26,6 +30,7 @@ export default function TemplatePartPlaceholder( { setAttributes } ) { status: 'publish', slug, meta: { theme: 'custom' }, + content: serialize( innerBlocks ), } ); setAttributes( { @@ -35,6 +40,21 @@ export default function TemplatePartPlaceholder( { setAttributes } ) { } ); }, [ setAttributes ] ); + // If there are inner blocks present, the content for creation is clear. + // Therefore immediately create the template part with the given inner blocks as its content. + useEffect( () => { + if ( innerBlocks.length ) { + onCreate(); + } + }, [] ); + if ( innerBlocks.length ) { + return ( + + + + ); + } + return ( + <__experimentalLinkControl.ViewerFill> { useCallback( ( fillProps ) => ( diff --git a/packages/edit-site/src/components/template-part-converter/index.js b/packages/edit-site/src/components/template-part-converter/index.js new file mode 100644 index 00000000000000..0af7add211a188 --- /dev/null +++ b/packages/edit-site/src/components/template-part-converter/index.js @@ -0,0 +1,55 @@ +/** + * WordPress dependencies + */ +import { useSelect, useDispatch } from '@wordpress/data'; +import { BlockSettingsMenuControls } from '@wordpress/block-editor'; +import { MenuItem } from '@wordpress/components'; +import { createBlock } from '@wordpress/blocks'; +import { __ } from '@wordpress/i18n'; + +export default function TemplatePartConverter() { + const { clientIds, blocks } = useSelect( ( select ) => { + const { getSelectedBlockClientIds, getBlocksByClientId } = select( + 'core/block-editor' + ); + const selectedBlockClientIds = getSelectedBlockClientIds(); + return { + clientIds: selectedBlockClientIds, + blocks: getBlocksByClientId( selectedBlockClientIds ), + }; + } ); + const { replaceBlocks } = useDispatch( 'core/block-editor' ); + + // Avoid transforming a single `core/template-part` block. + if ( blocks.length === 1 && blocks[ 0 ]?.name === 'core/template-part' ) { + return null; + } + + return ( + + { ( { onClose } ) => ( + { + replaceBlocks( + clientIds, + createBlock( + 'core/template-part', + {}, + blocks.map( ( block ) => + createBlock( + block.name, + block.attributes, + block.innerBlocks + ) + ) + ) + ); + onClose(); + } } + > + { __( 'Make template part' ) } + + ) } + + ); +}