diff --git a/packages/block-library/src/post-template/index.php b/packages/block-library/src/post-template/index.php index 9126355c096a5..64cdd156a5431 100644 --- a/packages/block-library/src/post-template/index.php +++ b/packages/block-library/src/post-template/index.php @@ -64,6 +64,11 @@ function render_block_core_post_template( $attributes, $content, $block ) { if ( in_the_loop() ) { $query = clone $wp_query; $query->rewind_posts(); + + // If in a single post of any post type, default to the 'post' post type. + if ( is_singular() ) { + query_posts( array( 'post_type' => 'post' ) ); + } } else { $query = $wp_query; } diff --git a/packages/block-library/src/query/block.json b/packages/block-library/src/query/block.json index 9eb8495963823..22bfa7b713801 100644 --- a/packages/block-library/src/query/block.json +++ b/packages/block-library/src/query/block.json @@ -41,6 +41,7 @@ "default": false } }, + "usesContext": [ "postType" ], "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 6c246ab89b3b3..4085128e9aef1 100644 --- a/packages/block-library/src/query/edit/inspector-controls/index.js +++ b/packages/block-library/src/query/edit/inspector-controls/index.js @@ -45,7 +45,7 @@ import { useToolsPanelDropdownMenuProps } from '../../../utils/hooks'; const { BlockInfo } = unlock( blockEditorPrivateApis ); export default function QueryInspectorControls( props ) { - const { attributes, setQuery, setDisplayLayout } = props; + const { attributes, setQuery, setDisplayLayout, isTemplate } = props; const { query, displayLayout } = attributes; const { order, @@ -103,6 +103,7 @@ export default function QueryInspectorControls( props ) { if ( ! hasFormatSupport ) { updateQuery.format = []; } + setQuery( updateQuery ); }; const [ querySearch, setQuerySearch ] = useState( query.search ); @@ -118,20 +119,25 @@ export default function QueryInspectorControls( props ) { onChangeDebounced(); return onChangeDebounced.cancel; }, [ querySearch, onChangeDebounced ] ); - const showInheritControl = isControlAllowed( allowedControls, 'inherit' ); + + const showInheritControl = + isTemplate && isControlAllowed( allowedControls, 'inherit' ); const showPostTypeControl = - ! inherit && isControlAllowed( allowedControls, 'postType' ); + ( ! inherit && isControlAllowed( allowedControls, 'postType' ) ) || + ! isTemplate; const postTypeControlLabel = __( 'Post type' ); const postTypeControlHelp = __( 'Select the type of content to display: posts, pages, or custom post types.' ); const showColumnsControl = false; const showOrderControl = - ! inherit && isControlAllowed( allowedControls, 'order' ); + ( ! inherit && isControlAllowed( allowedControls, 'order' ) ) || + ! isTemplate; const showStickyControl = - ! inherit && - showSticky && - isControlAllowed( allowedControls, 'sticky' ); + ( ! inherit && + showSticky && + isControlAllowed( allowedControls, 'sticky' ) ) || + ( showSticky && ! isTemplate ); const showSettingsPanel = showInheritControl || showPostTypeControl || diff --git a/packages/block-library/src/query/edit/query-content.js b/packages/block-library/src/query/edit/query-content.js index 4624b3b96049e..8b3ff09b17934 100644 --- a/packages/block-library/src/query/edit/query-content.js +++ b/packages/block-library/src/query/edit/query-content.js @@ -3,7 +3,7 @@ */ import { useSelect, useDispatch } from '@wordpress/data'; import { useInstanceId } from '@wordpress/compose'; -import { useEffect } from '@wordpress/element'; +import { useEffect, useCallback } from '@wordpress/element'; import { BlockControls, InspectorControls, @@ -32,6 +32,7 @@ export default function QueryContent( { openPatternSelectionModal, name, clientId, + context, } ) { const { queryId, @@ -41,6 +42,7 @@ export default function QueryContent( { tagName: TagName = 'div', query: { inherit } = {}, } = attributes; + const { postType } = context; const { __unstableMarkNextChangeAsNotPersistent } = useDispatch( blockEditorStore ); const instanceId = useInstanceId( QueryContent ); @@ -48,6 +50,16 @@ 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 } = @@ -81,6 +93,10 @@ export default function QueryContent( { // Changes in query property (which is an object) need to be in the same callback, // because updates are batched after the render and changes in different query properties // would cause to override previous wanted changes. + const updateQuery = useCallback( + ( newQuery ) => setAttributes( { query: { ...query, ...newQuery } } ), + [ query, setAttributes ] + ); useEffect( () => { const newQuery = {}; // When we inherit from global query always need to set the `perPage` @@ -90,11 +106,24 @@ 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 ) { + newQuery.inherit = false; + } if ( !! Object.keys( newQuery ).length ) { __unstableMarkNextChangeAsNotPersistent(); updateQuery( newQuery ); } - }, [ query.perPage, postsPerPage, inherit ] ); + }, [ + query.perPage, + postsPerPage, + inherit, + isTemplate, + query.inherit, + __unstableMarkNextChangeAsNotPersistent, + updateQuery, + ] ); // We need this for multi-query block pagination. // Query parameters for each block are scoped to their ID. useEffect( () => { @@ -102,9 +131,12 @@ export default function QueryContent( { __unstableMarkNextChangeAsNotPersistent(); setAttributes( { queryId: instanceId } ); } - }, [ queryId, instanceId ] ); - const updateQuery = ( newQuery ) => - setAttributes( { query: { ...query, ...newQuery } } ); + }, [ + queryId, + instanceId, + __unstableMarkNextChangeAsNotPersistent, + setAttributes, + ] ); const updateDisplayLayout = ( newDisplayLayout ) => setAttributes( { displayLayout: { ...displayLayout, ...newDisplayLayout }, @@ -135,6 +167,7 @@ export default function QueryContent( { setDisplayLayout={ updateDisplayLayout } setAttributes={ setAttributes } clientId={ clientId } + isTemplate={ isTemplate } /> diff --git a/phpunit/blocks/render-post-template-test.php b/phpunit/blocks/render-post-template-test.php index e375758044681..6241f6f060516 100644 --- a/phpunit/blocks/render-post-template-test.php +++ b/phpunit/blocks/render-post-template-test.php @@ -113,9 +113,10 @@ public function test_rendering_post_template_with_main_query_loop() { } /** - * Tests that the `core/post-template` block does not tamper with the main query loop when rendering within a post + * Tests that the `core/post-template` block does not tamper with the main query loop when rendering within a single post * as the main query loop has already been started. In this case, the main query object needs to be cloned to * prevent an infinite loop. + * Also tests that the default query returns posts of the 'post' post type when in a single post of any post type. */ public function test_rendering_post_template_with_main_query_loop_already_started() { global $wp_query, $wp_the_query; @@ -127,10 +128,18 @@ public function test_rendering_post_template_with_main_query_loop_already_starte $content .= ''; $content .= ''; - $expected = '