diff --git a/lib/block-patterns.php b/lib/block-patterns.php
index d376fb59aea1e..dd5dc83638958 100644
--- a/lib/block-patterns.php
+++ b/lib/block-patterns.php
@@ -62,3 +62,95 @@
',
)
);
+
+register_block_pattern(
+ 'template-part/tt1-header',
+ array(
+ 'title' => __( 'test-TT1 header', 'gutenberg' ),
+ 'scope' => array(
+ 'inserter' => false,
+ 'block' => array( 'core/template-part' ),
+ 'variation' => 'header',
+ ),
+ 'categories' => array( 'core/template-part_header' ),
+ 'content' => '
+
+
+
+
+
+
+
+
+
+ ',
+ )
+);
+
+register_block_pattern(
+ 'template-part/tt1-footer',
+ array(
+ 'title' => __( 'test-TT1 footer', 'gutenberg' ),
+ 'scope' => array(
+ 'inserter' => false,
+ 'block' => array( 'core/template-part' ),
+ 'variation' => 'footer',
+ ),
+ 'categories' => array( 'core/template-part_footer' ),
+ 'content' => '
+
+
+
+
+
+
+
+
+
+
2, Rue Louis-Boilly
Paris, France
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ',
+ )
+);
+
diff --git a/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js b/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js
index 069b33f6bc0ac..e180424c44928 100644
--- a/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js
+++ b/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js
@@ -106,10 +106,24 @@ function useInsertionPoint( {
} = useDispatch( blockEditorStore );
const onInsertBlocks = useCallback(
- ( blocks, meta, shouldForceFocusBlock = false ) => {
+ (
+ blocks,
+ meta,
+ shouldForceFocusBlock = false,
+ __experimentalReplaceInnerBlocks = false,
+ innerBlocksToReplace = []
+ ) => {
const selectedBlock = getSelectedBlock();
- if (
+ if ( __experimentalReplaceInnerBlocks ) {
+ replaceBlocks(
+ innerBlocksToReplace,
+ blocks,
+ null,
+ shouldFocusBlock || shouldForceFocusBlock ? 0 : null,
+ meta
+ );
+ } else if (
! isAppender &&
selectedBlock &&
isUnmodifiedDefaultBlock( selectedBlock )
diff --git a/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js b/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js
index 1b14286c821bf..6d776dc1f36e5 100644
--- a/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js
+++ b/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js
@@ -7,7 +7,12 @@ import { map } from 'lodash';
* WordPress dependencies
*/
import { useCallback } from '@wordpress/element';
-import { cloneBlock } from '@wordpress/blocks';
+import {
+ store as blocksStore,
+ cloneBlock,
+ __experimentalGetBlockLabel as getBlockLabel,
+ getBlockType,
+} from '@wordpress/blocks';
import { useDispatch, useSelect } from '@wordpress/data';
import { __, sprintf } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';
@@ -26,29 +31,104 @@ import { store as blockEditorStore } from '../../../store';
* @return {Array} Returns the patterns state. (patterns, categories, onSelect handler)
*/
const usePatternsState = ( onInsert, rootClientId ) => {
- const { patternCategories, patterns } = useSelect(
+ const {
+ patternCategories,
+ patterns,
+ activeTemplatePartId,
+ innerBlocksToReplace,
+ } = useSelect(
( select ) => {
const { __experimentalGetAllowedPatterns, getSettings } = select(
blockEditorStore
);
+
+ const _activeTemplatePartId = select(
+ blockEditorStore
+ ).__experimentalGetActiveBlockIdByBlockNames( [
+ 'core/template-part',
+ ] );
+
+ const contextualPatterns = {
+ patterns: [],
+ patternCategories: [],
+ };
+
+ if ( _activeTemplatePartId ) {
+ const block = select( blockEditorStore ).getBlock(
+ _activeTemplatePartId
+ );
+ const variations = select( blocksStore ).getBlockVariations(
+ 'core/template-part'
+ );
+
+ const activeVariation = variations.find( ( variation ) =>
+ variation.isActive?.(
+ block.attributes,
+ variation.attributes
+ )
+ );
+
+ const templatePartpatterns = select(
+ blockEditorStore
+ ).__experimentalGetScopedBlockPatterns(
+ 'block',
+ 'core/template-part'
+ );
+
+ const contextualInserterPatterns = templatePartpatterns.filter(
+ ( pattern ) =>
+ pattern.scope.variation === activeVariation?.name
+ );
+
+ contextualPatterns.patterns = contextualInserterPatterns;
+ contextualPatterns.patternCategories = [
+ {
+ name: `${ block.name }_` + activeVariation.name,
+ label: getBlockLabel(
+ getBlockType( block.name ),
+ block.attributes
+ ),
+ },
+ ];
+ }
+
const inserterPatterns = __experimentalGetAllowedPatterns(
rootClientId
).filter(
( pattern ) => ! pattern.scope || pattern.scope.inserter
);
+
return {
- patterns: inserterPatterns,
- patternCategories: getSettings()
- .__experimentalBlockPatternCategories,
+ patterns: [
+ ...contextualPatterns.patterns,
+ ...inserterPatterns,
+ ],
+ patternCategories: [
+ ...contextualPatterns.patternCategories,
+ ...getSettings().__experimentalBlockPatternCategories,
+ ],
+ activeTemplatePartId: _activeTemplatePartId,
+ innerBlocksToReplace: _activeTemplatePartId
+ ? select( blockEditorStore )
+ .getBlocks( _activeTemplatePartId )
+ .map( ( item ) => item.clientId )
+ : [],
};
},
[ rootClientId ]
);
const { createSuccessNotice } = useDispatch( noticesStore );
const onClickPattern = useCallback( ( pattern, blocks ) => {
+ const shouldReplaceInnerBlocks =
+ !! activeTemplatePartId &&
+ pattern.scope?.block?.includes( 'core/template-part' );
+
onInsert(
map( blocks, ( block ) => cloneBlock( block ) ),
- pattern.name
+ pattern.name,
+ false,
+ shouldReplaceInnerBlocks,
+ innerBlocksToReplace
);
createSuccessNotice(
sprintf(
@@ -62,7 +142,13 @@ const usePatternsState = ( onInsert, rootClientId ) => {
);
}, [] );
- return [ patterns, patternCategories, onClickPattern ];
+ return [
+ patterns,
+ patternCategories,
+ onClickPattern,
+ activeTemplatePartId,
+ innerBlocksToReplace,
+ ];
};
export default usePatternsState;
diff --git a/packages/block-editor/src/components/inserter/menu.js b/packages/block-editor/src/components/inserter/menu.js
index d18973d1d37db..08191b1a8bece 100644
--- a/packages/block-editor/src/components/inserter/menu.js
+++ b/packages/block-editor/src/components/inserter/menu.js
@@ -75,8 +75,20 @@ function InserterMenu( {
);
const onInsertPattern = useCallback(
- ( blocks, patternName ) => {
- onInsertBlocks( blocks, { patternName } );
+ (
+ blocks,
+ patternName,
+ shouldForceFocusBlock,
+ shouldReplaceInnerBlocks,
+ innerBlocksToReplace
+ ) => {
+ onInsertBlocks(
+ blocks,
+ { patternName },
+ shouldForceFocusBlock,
+ shouldReplaceInnerBlocks,
+ innerBlocksToReplace
+ );
onSelect();
},
[ onInsertBlocks, onSelect ]