diff --git a/packages/block-library/src/post-template/block.json b/packages/block-library/src/post-template/block.json index 4e7eefb97996e3..380b6d55f71fad 100644 --- a/packages/block-library/src/post-template/block.json +++ b/packages/block-library/src/post-template/block.json @@ -12,7 +12,8 @@ "query", "queryContext", "displayLayout", - "templateSlug" + "templateSlug", + "previewPostType" ], "supports": { "reusable": false, diff --git a/packages/block-library/src/post-template/edit.js b/packages/block-library/src/post-template/edit.js index 0d21a98c477d2c..c88e8e3a9c497f 100644 --- a/packages/block-library/src/post-template/edit.js +++ b/packages/block-library/src/post-template/edit.js @@ -89,6 +89,7 @@ export default function PostTemplateEdit( { queryContext = [ { page: 1 } ], templateSlug, displayLayout: { type: layoutType = 'flex', columns = 1 } = {}, + previewPostType, }, } ) { const [ { page } ] = queryContext; @@ -156,8 +157,11 @@ export default function PostTemplateEdit( { postType = query.postType; } } + // When we preview Query Loop blocks we should prefer the current + // block's postType, which is passed through block context. + const usedPostType = previewPostType || postType; return { - posts: getEntityRecords( 'postType', postType, query ), + posts: getEntityRecords( 'postType', usedPostType, query ), blocks: getBlocks( clientId ), }; }, @@ -177,6 +181,7 @@ export default function PostTemplateEdit( { templateSlug, taxQuery, parents, + previewPostType, ] ); const blockContexts = useMemo( diff --git a/packages/block-library/src/query/edit/index.js b/packages/block-library/src/query/edit/index.js index 3cb7996aa26901..c2f8ba13c4e73c 100644 --- a/packages/block-library/src/query/edit/index.js +++ b/packages/block-library/src/query/edit/index.js @@ -2,11 +2,12 @@ * WordPress dependencies */ import { useSelect, useDispatch } from '@wordpress/data'; -import { store as blocksStore, cloneBlock } from '@wordpress/blocks'; +import { store as blocksStore } from '@wordpress/blocks'; import { useInstanceId } from '@wordpress/compose'; -import { useState, useEffect } from '@wordpress/element'; +import { useState, useEffect, useMemo } from '@wordpress/element'; import { BlockControls, + BlockContextProvider, InspectorControls, useBlockProps, useSetting, @@ -30,7 +31,7 @@ import QueryToolbar from './query-toolbar'; import QueryInspectorControls from './inspector-controls'; import QueryPlaceholder from './query-placeholder'; import { DEFAULTS_POSTS_PER_PAGE } from '../constants'; -import { getFirstQueryClientIdFromBlocks } from '../utils'; +import { getTransformedBlocksFromPattern } from '../utils'; const TEMPLATE = [ [ 'core/post-template' ] ]; export function QueryContent( { @@ -177,6 +178,7 @@ function QueryPatternSetup( { { - const { clientId, name } = props; + const { clientId, name, attributes } = props; const [ isPatternSelectionModalOpen, setIsPatternSelectionModalOpen ] = useState( false ); const { replaceBlock, selectBlock } = useDispatch( blockEditorStore ); @@ -226,14 +228,23 @@ const QueryEdit = ( props ) => { ); const Component = hasInnerBlocks ? QueryContent : QueryPatternSetup; const onBlockPatternSelect = ( blocks ) => { - const clonedBlocks = blocks.map( ( block ) => cloneBlock( block ) ); - const firstQueryClientId = - getFirstQueryClientIdFromBlocks( clonedBlocks ); - replaceBlock( clientId, clonedBlocks ); - if ( firstQueryClientId ) { - selectBlock( firstQueryClientId ); + const { newBlocks, queryClientIds } = getTransformedBlocksFromPattern( + blocks, + attributes + ); + replaceBlock( clientId, newBlocks ); + if ( queryClientIds[ 0 ] ) { + selectBlock( queryClientIds[ 0 ] ); } }; + // When we preview Query Loop blocks we should prefer the current + // block's postType, which is passed through block context. + const blockPreviewContext = useMemo( + () => ( { + previewPostType: attributes.query.postType, + } ), + [ attributes.query.postType ] + ); return ( <> { setIsPatternSelectionModalOpen( false ) } > - + + + ) } diff --git a/packages/block-library/src/query/edit/query-placeholder.js b/packages/block-library/src/query/edit/query-placeholder.js index 07151aff4823be..263d7901d23517 100644 --- a/packages/block-library/src/query/edit/query-placeholder.js +++ b/packages/block-library/src/query/edit/query-placeholder.js @@ -12,7 +12,14 @@ import { store as blocksStore, } from '@wordpress/blocks'; -function QueryPlaceholder( { clientId, name, setAttributes, icon, label } ) { +function QueryPlaceholder( { + clientId, + name, + attributes, + setAttributes, + icon, + label, +} ) { const { defaultVariation, scopeVariations } = useSelect( ( select ) => { const { @@ -39,7 +46,15 @@ function QueryPlaceholder( { clientId, name, setAttributes, icon, label } ) { variations={ scopeVariations } onSelect={ ( nextVariation = defaultVariation ) => { if ( nextVariation.attributes ) { - setAttributes( nextVariation.attributes ); + setAttributes( { + ...nextVariation.attributes, + query: { + ...nextVariation.attributes.query, + postType: + attributes.query.postType || + nextVariation.attributes.query.postType, + }, + } ); } if ( nextVariation.innerBlocks ) { replaceInnerBlocks( diff --git a/packages/block-library/src/query/utils.js b/packages/block-library/src/query/utils.js index 4fd81566378e25..fb62191696f115 100644 --- a/packages/block-library/src/query/utils.js +++ b/packages/block-library/src/query/utils.js @@ -10,6 +10,7 @@ import { useSelect } from '@wordpress/data'; import { useMemo } from '@wordpress/element'; import { store as coreStore } from '@wordpress/core-data'; import { decodeEntities } from '@wordpress/html-entities'; +import { cloneBlock } from '@wordpress/blocks'; /** * @typedef IHasNameAndId @@ -127,21 +128,42 @@ export const useTaxonomies = ( postType ) => { }; /** - * Recurses over a list of blocks and returns the first found - * Query Loop block's clientId. + * Clones a pattern's blocks and then recurses over that list of blocks, + * transforming them to retain some `query` attribute properties. + * For now we retain the `postType` and `inherit` properties as they are + * fundamental for the expected functionality of the block and don't affect + * its design and presentation. * - * @param {WPBlock[]} blocks The list of blocks to look through. - * @return {string=} The first found Query Loop's clientId. + * Returns the cloned/transformed blocks and array of existing Query Loop + * client ids for further manipulation, in order to avoid multiple recursions. + * + * @param {WPBlock[]} blocks The list of blocks to look through and transform(mutate). + * @param {Record} queryBlockAttributes The existing Query Loop's attributes. + * @return {{ newBlocks: WPBlock[], queryClientIds: string[] }} An object with the cloned/transformed blocks and all the Query Loop clients from these blocks. */ -export const getFirstQueryClientIdFromBlocks = ( blocks ) => { - const blocksQueue = [ ...blocks ]; +export const getTransformedBlocksFromPattern = ( + blocks, + queryBlockAttributes +) => { + const { + query: { postType, inherit }, + } = queryBlockAttributes; + const clonedBlocks = blocks.map( ( block ) => cloneBlock( block ) ); + const queryClientIds = []; + const blocksQueue = [ ...clonedBlocks ]; while ( blocksQueue.length > 0 ) { const block = blocksQueue.shift(); if ( block.name === 'core/query' ) { - return block.clientId; + block.attributes.query = { + ...block.attributes.query, + postType, + inherit, + }; + queryClientIds.push( block.clientId ); } block.innerBlocks?.forEach( ( innerBlock ) => { blocksQueue.push( innerBlock ); } ); } + return { newBlocks: clonedBlocks, queryClientIds }; };