Skip to content

Commit

Permalink
Query Loop: Default to querying posts when on singular content (WordP…
Browse files Browse the repository at this point in the history
…ress#65067)

* Fix linter warnings

* Replace the postType if current post type is different

* Remove currentPostType logic

* Default to posts if is_singular

* Update test_rendering_post_template_with_main_query_loop_already_started test

* Add test for query loop not inside a singular query

* Revert changes to QueryContent

* Show query type control only when on a template

* Move template logic to QueryInspectorControls

* Ensure inherit value is updated when not in a template

* Update comment

* Rename showDefaultControl to isTemplate

* Get postType from context

* Add a check for singular content based on available post type

* Move inherit reset to a useEffect

* Move isTemplate logic to QueryContent

* Fix lint warnings

Unlinked contributors: alaczek, autumnfjeld.

Co-authored-by: mikachan <mikachan@git.wordpress.org>
Co-authored-by: fabiankaegy <fabiankaegy@git.wordpress.org>
Co-authored-by: creativecoder <grantmkin@git.wordpress.org>
Co-authored-by: jameskoster <jameskoster@git.wordpress.org>
Co-authored-by: richtabor <richtabor@git.wordpress.org>
Co-authored-by: jasmussen <joen@git.wordpress.org>
  • Loading branch information
7 people committed Sep 18, 2024
1 parent bf63906 commit 623f268
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 17 deletions.
5 changes: 5 additions & 0 deletions packages/block-library/src/post-template/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions packages/block-library/src/query/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"default": false
}
},
"usesContext": [ "postType" ],
"providesContext": {
"queryId": "queryId",
"query": "query",
Expand Down
20 changes: 13 additions & 7 deletions packages/block-library/src/query/edit/inspector-controls/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -103,6 +103,7 @@ export default function QueryInspectorControls( props ) {
if ( ! hasFormatSupport ) {
updateQuery.format = [];
}

setQuery( updateQuery );
};
const [ querySearch, setQuerySearch ] = useState( query.search );
Expand All @@ -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 ||
Expand Down
43 changes: 38 additions & 5 deletions packages/block-library/src/query/edit/query-content.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -32,6 +32,7 @@ export default function QueryContent( {
openPatternSelectionModal,
name,
clientId,
context,
} ) {
const {
queryId,
Expand All @@ -41,13 +42,24 @@ export default function QueryContent( {
tagName: TagName = 'div',
query: { inherit } = {},
} = attributes;
const { postType } = context;
const { __unstableMarkNextChangeAsNotPersistent } =
useDispatch( blockEditorStore );
const instanceId = useInstanceId( QueryContent );
const blockProps = useBlockProps();
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 } =
Expand Down Expand Up @@ -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`
Expand All @@ -90,21 +106,37 @@ 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( () => {
if ( ! Number.isFinite( queryId ) ) {
__unstableMarkNextChangeAsNotPersistent();
setAttributes( { queryId: instanceId } );
}
}, [ queryId, instanceId ] );
const updateQuery = ( newQuery ) =>
setAttributes( { query: { ...query, ...newQuery } } );
}, [
queryId,
instanceId,
__unstableMarkNextChangeAsNotPersistent,
setAttributes,
] );
const updateDisplayLayout = ( newDisplayLayout ) =>
setAttributes( {
displayLayout: { ...displayLayout, ...newDisplayLayout },
Expand Down Expand Up @@ -135,6 +167,7 @@ export default function QueryContent( {
setDisplayLayout={ updateDisplayLayout }
setAttributes={ setAttributes }
clientId={ clientId }
isTemplate={ isTemplate }
/>
</InspectorControls>
<BlockControls>
Expand Down
70 changes: 65 additions & 5 deletions phpunit/blocks/render-post-template-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -127,10 +128,18 @@ public function test_rendering_post_template_with_main_query_loop_already_starte
$content .= '<!-- /wp:post-template -->';
$content .= '<!-- /wp:query -->';

$expected = '<ul class="alignwide wp-block-post-template is-layout-flow wp-block-post-template-is-layout-flow wp-block-query-is-layout-flow">';
$expected .= '<li class="wp-block-post post-' . self::$post->ID . ' post type-post status-publish format-standard hentry category-uncategorized">';
$expected .= '<h2 class="wp-block-post-title">' . self::$post->post_title . '</h2>';
$expected .= '</li>';
$expected = '<ul class="alignwide wp-block-post-template is-layout-flow wp-block-post-template-is-layout-flow wp-block-query-is-layout-flow">';

// Find all the posts of the 'post' post type.
$wp_query_posts = new WP_Query( array( 'post_type' => 'post' ) );

while ( $wp_query_posts->have_posts() ) {
$wp_query_posts->the_post();
$expected .= '<li class="wp-block-post post-' . get_the_ID() . ' post type-post status-publish format-standard hentry category-uncategorized">';
$expected .= '<h2 class="wp-block-post-title">' . get_the_title() . '</h2>';
$expected .= '</li>';
}

$expected .= '</ul>';

// Update the post's content to have a query block for the same query as the main query.
Expand All @@ -156,4 +165,55 @@ public function test_rendering_post_template_with_main_query_loop_already_starte

$this->assertSame( $expected, $output, 'Unexpected parsed post content' );
}

/**
* Tests that the `core/post-template` block rewinds the default query when not in a single post of any post type.
*/
public function test_rendering_post_template_with_main_query_loop_not_single_post() {
global $wp_query, $wp_the_query;

// Query block with post template block.
$content = '<!-- wp:query {"query":{"inherit":true}} -->';
$content .= '<!-- wp:post-template {"align":"wide"} -->';
$content .= '<!-- wp:post-title /-->';
$content .= '<!-- /wp:post-template -->';
$content .= '<!-- /wp:query -->';

$expected = '<ul class="alignwide wp-block-post-template is-layout-flow wp-block-post-template-is-layout-flow wp-block-query-is-layout-flow">';

// Find all the posts of the 'post' post type.
$wp_query_posts = new WP_Query( array( 'post_type' => 'post' ) );

while ( $wp_query_posts->have_posts() ) {
$wp_query_posts->the_post();
$expected .= '<li class="wp-block-post post-' . get_the_ID() . ' post type-post status-publish format-standard hentry category-uncategorized">';
$expected .= '<h2 class="wp-block-post-title">' . get_the_title() . '</h2>';
$expected .= '</li>';
}

$expected .= '</ul>';

// Update the post's content to have a query block for the same query as the main query.
wp_update_post(
array(
'ID' => self::$post->ID,
'post_content' => $content,
'post_content_filtered' => $content,
)
);

// Set main query to all posts.
$wp_query = new WP_Query( array( 'post_type' => 'post' ) );
$wp_the_query = $wp_query;

// Get post content within main query loop.
$output = '';
while ( $wp_query->have_posts() ) {
$wp_query->the_post();

$output = get_echo( 'the_content' );
}

$this->assertSame( $expected, $output, 'Unexpected parsed post content' );
}
}

0 comments on commit 623f268

Please sign in to comment.