-
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
Pattern block: Add experimental flag and syncStatus attrib to allow testing of partial syncing #50533
Pattern block: Add experimental flag and syncStatus attrib to allow testing of partial syncing #50533
Changes from 13 commits
c6e6662
f7c1418
b4e01bb
39efc21
6016dd7
f7df5d9
cc90aee
6fd82a7
f542328
a888f55
31427d4
e580bc3
e286463
538eeeb
4ac3f8e
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,46 +1,81 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { cloneBlock } from '@wordpress/blocks'; | ||
import { useSelect, useDispatch } from '@wordpress/data'; | ||
import { useEffect } from '@wordpress/element'; | ||
import { | ||
store as blockEditorStore, | ||
useBlockProps, | ||
useInnerBlocksProps, | ||
} from '@wordpress/block-editor'; | ||
|
||
const PatternEdit = ( { attributes, clientId } ) => { | ||
const selectedPattern = useSelect( | ||
( select ) => | ||
select( blockEditorStore ).__experimentalGetParsedPattern( | ||
attributes.slug | ||
), | ||
[ attributes.slug ] | ||
const { slug, syncStatus } = attributes; | ||
const { selectedPattern, innerBlocks } = useSelect( | ||
( select ) => { | ||
return { | ||
selectedPattern: | ||
select( blockEditorStore ).__experimentalGetParsedPattern( | ||
slug | ||
), | ||
innerBlocks: | ||
select( blockEditorStore ).getBlock( clientId ) | ||
?.innerBlocks, | ||
}; | ||
}, | ||
[ slug, clientId ] | ||
); | ||
|
||
const { replaceBlocks, __unstableMarkNextChangeAsNotPersistent } = | ||
useDispatch( blockEditorStore ); | ||
const { | ||
replaceBlocks, | ||
replaceInnerBlocks, | ||
__unstableMarkNextChangeAsNotPersistent, | ||
} = useDispatch( blockEditorStore ); | ||
|
||
// Run this effect when the component loads. | ||
// This adds the Pattern's contents to the post. | ||
// This change won't be saved. | ||
// It will continue to pull from the pattern file unless changes are made to its respective template part. | ||
useEffect( () => { | ||
if ( selectedPattern?.blocks ) { | ||
if ( selectedPattern?.blocks && ! innerBlocks?.length ) { | ||
// We batch updates to block list settings to avoid triggering cascading renders | ||
// for each container block included in a tree and optimize initial render. | ||
// Since the above uses microtasks, we need to use a microtask here as well, | ||
// because nested pattern blocks cannot be inserted if the parent block supports | ||
// inner blocks but doesn't have blockSettings in the state. | ||
window.queueMicrotask( () => { | ||
__unstableMarkNextChangeAsNotPersistent(); | ||
if ( syncStatus === 'partial' ) { | ||
replaceInnerBlocks( | ||
clientId, | ||
selectedPattern.blocks.map( ( block ) => | ||
cloneBlock( block ) | ||
) | ||
); | ||
return; | ||
} | ||
replaceBlocks( clientId, selectedPattern.blocks ); | ||
} ); | ||
} | ||
}, [ clientId, selectedPattern?.blocks ] ); | ||
}, [ | ||
clientId, | ||
selectedPattern?.blocks, | ||
replaceInnerBlocks, | ||
__unstableMarkNextChangeAsNotPersistent, | ||
innerBlocks, | ||
syncStatus, | ||
replaceBlocks, | ||
] ); | ||
|
||
const blockProps = useBlockProps(); | ||
|
||
const innerBlocksProps = useInnerBlocksProps( blockProps, { | ||
templateLock: syncStatus === 'partial' ? 'contentOnly' : false, | ||
} ); | ||
|
||
const props = useBlockProps(); | ||
if ( syncStatus !== 'partial' ) { | ||
return <div { ...blockProps } />; | ||
} | ||
|
||
return <div { ...props } />; | ||
return <div { ...innerBlocksProps } />; | ||
}; | ||
|
||
export default PatternEdit; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,14 +22,22 @@ function register_block_core_pattern() { | |
/** | ||
* Renders the `core/pattern` block on the server. | ||
* | ||
* @param array $attributes Block attributes. | ||
* @param array $attributes Block attributes. | ||
* @param string $content The block rendered content. | ||
* | ||
* @return string Returns the output of the pattern. | ||
*/ | ||
function render_block_core_pattern( $attributes ) { | ||
function render_block_core_pattern( $attributes, $content ) { | ||
if ( empty( $attributes['slug'] ) ) { | ||
return ''; | ||
} | ||
$slug_classname = str_replace( '/', '-', $attributes['slug'] ); | ||
$classnames = isset( $attributes['className'] ) ? $attributes['className'] . ' ' . $slug_classname : $slug_classname; | ||
$wrapper = '<div class="' . esc_attr( $classnames ) . '">%s</div>'; | ||
|
||
if ( isset( $attributes['syncStatus'] ) && 'unsynced' === $attributes['syncStatus'] ) { | ||
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 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. The thinking was that if there is no Adding 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. Good catch @gziolo 👍
That's what the block.json attribute definition indicates. What I think @gziolo is questioning is the 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. 🤦 missed the first code snippet in the original comment! Ignore all of my previous comment, I will get the 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. |
||
return sprintf( $wrapper, $content ); | ||
} | ||
|
||
$slug = $attributes['slug']; | ||
$registry = WP_Block_Patterns_Registry::get_instance(); | ||
|
@@ -38,7 +46,7 @@ function render_block_core_pattern( $attributes ) { | |
} | ||
|
||
$pattern = $registry->get_registered( $slug ); | ||
return do_blocks( $pattern['content'] ); | ||
return sprintf( $wrapper, do_blocks( $pattern['content'] ) ); | ||
} | ||
|
||
add_action( 'init', 'register_block_core_pattern' ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useSelect, useDispatch } from '@wordpress/data'; | ||
import { useEffect } from '@wordpress/element'; | ||
import { | ||
store as blockEditorStore, | ||
useBlockProps, | ||
} from '@wordpress/block-editor'; | ||
|
||
const PatternEdit = ( { attributes, clientId } ) => { | ||
const selectedPattern = useSelect( | ||
( select ) => | ||
select( blockEditorStore ).__experimentalGetParsedPattern( | ||
attributes.slug | ||
), | ||
[ attributes.slug ] | ||
); | ||
|
||
const { replaceBlocks, __unstableMarkNextChangeAsNotPersistent } = | ||
useDispatch( blockEditorStore ); | ||
|
||
// Run this effect when the component loads. | ||
// This adds the Pattern's contents to the post. | ||
// This change won't be saved. | ||
// It will continue to pull from the pattern file unless changes are made to its respective template part. | ||
useEffect( () => { | ||
if ( selectedPattern?.blocks ) { | ||
// We batch updates to block list settings to avoid triggering cascading renders | ||
// for each container block included in a tree and optimize initial render. | ||
// Since the above uses microtasks, we need to use a microtask here as well, | ||
// because nested pattern blocks cannot be inserted if the parent block supports | ||
// inner blocks but doesn't have blockSettings in the state. | ||
window.queueMicrotask( () => { | ||
__unstableMarkNextChangeAsNotPersistent(); | ||
replaceBlocks( clientId, selectedPattern.blocks ); | ||
} ); | ||
} | ||
}, [ | ||
clientId, | ||
selectedPattern?.blocks, | ||
__unstableMarkNextChangeAsNotPersistent, | ||
replaceBlocks, | ||
] ); | ||
|
||
const props = useBlockProps(); | ||
|
||
return <div { ...props } />; | ||
}; | ||
|
||
export default PatternEdit; |
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.
Should the same class get generated in the
edit
implementation?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.
Thanks, yes it should, have added a PR for this.