diff --git a/packages/block-library/src/post-template/block.json b/packages/block-library/src/post-template/block.json index 6a57585558352..da576a83312a4 100644 --- a/packages/block-library/src/post-template/block.json +++ b/packages/block-library/src/post-template/block.json @@ -13,7 +13,8 @@ "displayLayout", "templateSlug", "previewPostType", - "enhancedPagination" + "enhancedPagination", + "postType" ], "supports": { "reusable": false, diff --git a/packages/block-library/src/post-template/edit.js b/packages/block-library/src/post-template/edit.js index a9e279ee2c305..4e7e514ed82b1 100644 --- a/packages/block-library/src/post-template/edit.js +++ b/packages/block-library/src/post-template/edit.js @@ -100,6 +100,7 @@ export default function PostTemplateEdit( { } = {}, templateSlug, previewPostType, + postType: postTypeFromContext, }, attributes: { layout }, __unstableLayoutClassNames, @@ -186,7 +187,10 @@ export default function PostTemplateEdit( { } // When we preview Query Loop blocks we should prefer the current // block's postType, which is passed through block context. - const usedPostType = previewPostType || postType; + const usedPostType = + postTypeFromContext !== 'page' + ? postTypeFromContext + : previewPostType || postType; return { posts: getEntityRecords( 'postType', usedPostType, { ...query, diff --git a/packages/block-library/src/query/block.json b/packages/block-library/src/query/block.json index b2225192c6b21..2379a1d1da53c 100644 --- a/packages/block-library/src/query/block.json +++ b/packages/block-library/src/query/block.json @@ -42,7 +42,7 @@ "default": false } }, - "usesContext": [ "postType" ], + "usesContext": [ "postType", "templateSlug" ], "providesContext": { "queryId": "queryId", "query": "query", diff --git a/packages/block-library/src/query/edit/inspector-controls/index.js b/packages/block-library/src/query/edit/inspector-controls/index.js index 06105bef4e026..bc900c073f648 100644 --- a/packages/block-library/src/query/edit/inspector-controls/index.js +++ b/packages/block-library/src/query/edit/inspector-controls/index.js @@ -45,9 +45,15 @@ import { useToolsPanelDropdownMenuProps } from '../../../utils/hooks'; const { BlockInfo } = unlock( blockEditorPrivateApis ); export default function QueryInspectorControls( props ) { - const { attributes, setQuery, setDisplayLayout, isTemplate } = props; - const { query, displayLayout } = attributes; const { + attributes, + setQuery, + setDisplayLayout, + postTypeFromContext, + isSingular, + } = props; + const { query, displayLayout } = attributes; + let { order, orderBy, author: authorIds, @@ -61,6 +67,16 @@ export default function QueryInspectorControls( props ) { parents, format, } = query; + // If a post type is set in context, update `postType` to match it, + // unless the post type is `page`, as it usually doesn't make sense to loop + // through pages. + if ( + postTypeFromContext && + postTypeFromContext !== 'page' && + postTypeFromContext !== postType + ) { + postType = postTypeFromContext; + } const allowedControls = useAllowedControls( attributes ); const showSticky = postType === 'post'; const { @@ -118,7 +134,7 @@ export default function QueryInspectorControls( props ) { }, [ querySearch, onChangeDebounced ] ); const showInheritControl = - isTemplate && isControlAllowed( allowedControls, 'inherit' ); + ! isSingular && isControlAllowed( allowedControls, 'inherit' ); const showPostTypeControl = ! inherit && isControlAllowed( allowedControls, 'postType' ); const postTypeControlLabel = __( 'Post type' ); diff --git a/packages/block-library/src/query/edit/query-content.js b/packages/block-library/src/query/edit/query-content.js index 8b3ff09b17934..bdfcbe0498ec4 100644 --- a/packages/block-library/src/query/edit/query-content.js +++ b/packages/block-library/src/query/edit/query-content.js @@ -22,6 +22,7 @@ import EnhancedPaginationControl from './inspector-controls/enhanced-pagination- import QueryToolbar from './query-toolbar'; import QueryInspectorControls from './inspector-controls'; import EnhancedPaginationModal from './enhanced-pagination-modal'; +import { getQueryContextFromTemplate } from '../utils'; const DEFAULTS_POSTS_PER_PAGE = 3; @@ -42,7 +43,8 @@ export default function QueryContent( { tagName: TagName = 'div', query: { inherit } = {}, } = attributes; - const { postType } = context; + const { templateSlug, postType } = context; + const { isSingular } = getQueryContextFromTemplate( templateSlug ); const { __unstableMarkNextChangeAsNotPersistent } = useDispatch( blockEditorStore ); const instanceId = useInstanceId( QueryContent ); @@ -50,16 +52,6 @@ export default function QueryContent( { const innerBlocksProps = useInnerBlocksProps( blockProps, { template: TEMPLATE, } ); - const isTemplate = useSelect( - ( select ) => { - const currentTemplate = - select( coreStore ).__experimentalGetTemplateForLink()?.type; - const isInTemplate = 'wp_template' === currentTemplate; - const isInSingularContent = postType !== undefined; - return isInTemplate && ! isInSingularContent; - }, - [ postType ] - ); const { postsPerPage } = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); const { getEntityRecord, getEntityRecordEdits, canUser } = @@ -106,9 +98,9 @@ export default function QueryContent( { } else if ( ! query.perPage && postsPerPage ) { newQuery.perPage = postsPerPage; } - // We need to reset the `inherit` value if not in a template, as queries - // are not inherited when outside a template (e.g. when in singular content). - if ( ! isTemplate && query.inherit ) { + // We need to reset the `inherit` value if in a singular template, as queries + // are not inherited when in singular content (e.g. post, page, 404, blank). + if ( isSingular && query.inherit ) { newQuery.inherit = false; } if ( !! Object.keys( newQuery ).length ) { @@ -117,10 +109,10 @@ export default function QueryContent( { } }, [ query.perPage, + query.inherit, postsPerPage, inherit, - isTemplate, - query.inherit, + isSingular, __unstableMarkNextChangeAsNotPersistent, updateQuery, ] ); @@ -167,7 +159,8 @@ export default function QueryContent( { setDisplayLayout={ updateDisplayLayout } setAttributes={ setAttributes } clientId={ clientId } - isTemplate={ isTemplate } + postTypeFromContext={ postType } + isSingular={ isSingular } /> diff --git a/packages/block-library/src/query/test/utils.js b/packages/block-library/src/query/test/utils.js index 1b71185008677..8c2d88ade8051 100644 --- a/packages/block-library/src/query/test/utils.js +++ b/packages/block-library/src/query/test/utils.js @@ -2,7 +2,11 @@ * Internal dependencies */ import { terms } from './fixtures'; -import { getEntitiesInfo, getValueFromObjectPath } from '../utils'; +import { + getEntitiesInfo, + getValueFromObjectPath, + getQueryContextFromTemplate, +} from '../utils'; describe( 'Query block utils', () => { describe( 'getEntitiesInfo', () => { @@ -61,4 +65,58 @@ describe( 'Query block utils', () => { expect( result ).toBe( 'test' ); } ); } ); + + describe( 'getQueryContextFromTemplate', () => { + it( 'should return the correct query context based on template slug', () => { + expect( getQueryContextFromTemplate() ).toStrictEqual( { + isSingular: true, + } ); + expect( getQueryContextFromTemplate( '404' ) ).toStrictEqual( { + isSingular: true, + templateType: '404', + } ); + expect( getQueryContextFromTemplate( 'blank' ) ).toStrictEqual( { + isSingular: true, + templateType: 'blank', + } ); + expect( getQueryContextFromTemplate( 'single' ) ).toStrictEqual( { + isSingular: true, + templateType: 'single', + } ); + expect( + getQueryContextFromTemplate( 'single-film' ) + ).toStrictEqual( { + isSingular: true, + templateType: 'single', + } ); + expect( getQueryContextFromTemplate( 'page' ) ).toStrictEqual( { + isSingular: true, + templateType: 'page', + } ); + expect( getQueryContextFromTemplate( 'wp' ) ).toStrictEqual( { + isSingular: true, + templateType: 'custom', + } ); + expect( getQueryContextFromTemplate( 'category' ) ).toStrictEqual( { + isSingular: false, + templateType: 'category', + } ); + expect( + getQueryContextFromTemplate( 'category-dog' ) + ).toStrictEqual( { + isSingular: false, + templateType: 'category', + } ); + expect( getQueryContextFromTemplate( 'archive' ) ).toStrictEqual( { + isSingular: false, + templateType: 'archive', + } ); + expect( + getQueryContextFromTemplate( 'archive-film' ) + ).toStrictEqual( { + isSingular: false, + templateType: 'archive', + } ); + } ); + } ); } ); diff --git a/packages/block-library/src/query/utils.js b/packages/block-library/src/query/utils.js index 68da2573bab0f..fc22ca46d471c 100644 --- a/packages/block-library/src/query/utils.js +++ b/packages/block-library/src/query/utils.js @@ -435,3 +435,32 @@ export const useUnsupportedBlocks = ( clientId ) => { [ clientId ] ); }; + +/** + * Helper function that returns the query context from the editor based on the + * available template slug. + * + * @param {string} templateSlug Current template slug based on context. + * @return {Object} An object with isSingular and templateType properties. + */ +export function getQueryContextFromTemplate( templateSlug ) { + // In the Post Editor, the template slug is not available. + if ( ! templateSlug ) { + return { isSingular: true }; + } + let isSingular = false; + let templateType = templateSlug === 'wp' ? 'custom' : templateSlug; + const singularTemplates = [ '404', 'blank', 'single', 'page', 'custom' ]; + const templateTypeFromSlug = templateSlug.includes( '-' ) + ? templateSlug.split( '-', 1 )[ 0 ] + : templateSlug; + const queryFromTemplateSlug = templateSlug.includes( '-' ) + ? templateSlug.split( '-' ).slice( 1 ).join( '-' ) + : ''; + if ( queryFromTemplateSlug ) { + templateType = templateTypeFromSlug; + } + isSingular = singularTemplates.includes( templateType ); + + return { isSingular, templateType }; +}