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

Edit Site: Add convert to template part flow. #20445

Merged
merged 10 commits into from
Oct 23, 2020
5 changes: 4 additions & 1 deletion packages/block-library/src/template-part/edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ export default function TemplatePartEdit( {
return (
<TagName { ...blockProps }>
{ isPlaceholder && (
<TemplatePartPlaceholder setAttributes={ setAttributes } />
<TemplatePartPlaceholder
setAttributes={ setAttributes }
innerBlocks={ innerBlocks }
/>
) }
{ isTemplateFile && (
<BlockControls>
Expand Down
26 changes: 23 additions & 3 deletions packages/block-library/src/template-part/edit/placeholder/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -26,6 +30,7 @@ export default function TemplatePartPlaceholder( { setAttributes } ) {
status: 'publish',
slug,
meta: { theme: 'custom' },
content: serialize( innerBlocks ),
}
);
setAttributes( {
Expand All @@ -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 (
<Placeholder>
<Spinner />
</Placeholder>
);
}

return (
<Placeholder
icon={ blockDefault }
Expand Down
2 changes: 2 additions & 0 deletions packages/edit-site/src/components/block-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
/**
* Internal dependencies
*/
import TemplatePartConverter from '../template-part-converter';
import NavigateToLink from '../navigate-to-link';
import { SidebarInspectorFill } from '../sidebar';

Expand Down Expand Up @@ -49,6 +50,7 @@ export default function BlockEditor( { setIsInserterOpen } ) {
useSubRegistry={ false }
>
<BlockEditorKeyboardShortcuts />
<TemplatePartConverter />
Addison-Stavlo marked this conversation as resolved.
Show resolved Hide resolved
<__experimentalLinkControl.ViewerFill>
{ useCallback(
( fillProps ) => (
Expand Down
55 changes: 55 additions & 0 deletions packages/edit-site/src/components/template-part-converter/index.js
Original file line number Diff line number Diff line change
@@ -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() {
Copy link
Member

Choose a reason for hiding this comment

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

Should this live in the block-editor package? It seems like it would fit well there, since it's basically part of the block menu. (maybe we could then provide a mechanism to turn it off for the post editor?)

Copy link
Contributor

Choose a reason for hiding this comment

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

I would assume that if we want this in both editors (site and post) when FSE is enabled, that this would be better in block-editor as well. However, if it doesn't belong in the post editor I would think this is a fitting location for it? (asked about this below)

Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like the idea is to keep it edit-site only (for now at least). Id say edit-site package makes sense, and we can move it over to block-editor if things change and we want this in the post editor as well.

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 (
<BlockSettingsMenuControls>
{ ( { onClose } ) => (
<MenuItem
onClick={ () => {
replaceBlocks(
clientIds,
createBlock(
'core/template-part',
{},
blocks.map( ( block ) =>
createBlock(
block.name,
block.attributes,
block.innerBlocks
)
)
)
);
onClose();
} }
>
{ __( 'Make template part' ) }
</MenuItem>
) }
</BlockSettingsMenuControls>
);
}