diff --git a/packages/block-library/src/query-loop/edit.js b/packages/block-library/src/query-loop/edit.js index aa2bdc38f58da..6f14b7dd71a4a 100644 --- a/packages/block-library/src/query-loop/edit.js +++ b/packages/block-library/src/query-loop/edit.js @@ -35,6 +35,7 @@ export default function QueryLoopEdit( { author, search, exclude, + sticky, } = {}, queryContext, }, @@ -65,6 +66,12 @@ export default function QueryLoopEdit( { if ( exclude?.length ) { query.exclude = exclude; } + // If sticky is not set, it will return all posts in the results. + // If sticky is set to `only`, it will limit the results to sticky posts only. + // If it is anything else, it will exclude sticky posts from results. For the record the value stored is `exclude`. + if ( sticky ) { + query.sticky = sticky === 'only'; + } return { posts: getEntityRecords( 'postType', postType, query ), blocks: getBlocks( clientId ), @@ -83,6 +90,7 @@ export default function QueryLoopEdit( { search, postType, exclude, + sticky, ] ); diff --git a/packages/block-library/src/query-loop/index.php b/packages/block-library/src/query-loop/index.php index a6e619f0841f7..5acc340bd66e2 100644 --- a/packages/block-library/src/query-loop/index.php +++ b/packages/block-library/src/query-loop/index.php @@ -19,18 +19,27 @@ function render_block_core_query_loop( $attributes, $content, $block ) { $page = empty( $_GET[ $page_key ] ) ? 1 : filter_var( $_GET[ $page_key ], FILTER_VALIDATE_INT ); $query = array( - 'post_type' => 'post', - 'offset' => 0, - 'order' => 'DESC', - 'orderby' => 'date', + 'post_type' => 'post', + 'offset' => 0, + 'order' => 'DESC', + 'orderby' => 'date', + 'post__not_in' => array(), ); if ( isset( $block->context['query'] ) ) { if ( isset( $block->context['query']['postType'] ) ) { $query['post_type'] = $block->context['query']['postType']; } + if ( isset( $block->context['query']['sticky'] ) && ! empty( $block->context['query']['sticky'] ) ) { + $sticky = get_option( 'sticky_posts' ); + if ( 'only' === $block->context['query']['sticky'] ) { + $query['post__in'] = $sticky; + } else { + $query['post__not_in'] = array_merge( $query['post__not_in'], $sticky ); + } + } if ( isset( $block->context['query']['exclude'] ) ) { - $query['post__not_in'] = $block->context['query']['exclude']; + $query['post__not_in'] = array_merge( $query['post__not_in'], $block->context['query']['exclude'] ); } if ( isset( $block->context['query']['perPage'] ) ) { $query['offset'] = ( $block->context['query']['perPage'] * ( $page - 1 ) ) + $block->context['query']['offset']; diff --git a/packages/block-library/src/query/block.json b/packages/block-library/src/query/block.json index 02f8f60d76fd1..f01c6b66081e3 100644 --- a/packages/block-library/src/query/block.json +++ b/packages/block-library/src/query/block.json @@ -19,7 +19,8 @@ "orderBy": "date", "author": "", "search": "", - "exclude": [] + "exclude": [], + "sticky": "" } } }, diff --git a/packages/block-library/src/query/edit/query-inspector-controls.js b/packages/block-library/src/query/edit/query-inspector-controls.js index fda77e91000d4..c7ecae5a456fd 100644 --- a/packages/block-library/src/query/edit/query-inspector-controls.js +++ b/packages/block-library/src/query/edit/query-inspector-controls.js @@ -26,9 +26,16 @@ import { getTermsInfo } from '../utils'; import { MAX_FETCHED_TERMS } from '../constants'; export default function QueryInspectorControls( { query, setQuery } ) { - const { order, orderBy, author: selectedAuthorId, postType } = query; + const { + order, + orderBy, + author: selectedAuthorId, + postType, + sticky, + } = query; const [ showCategories, setShowCategories ] = useState( true ); const [ showTags, setShowTags ] = useState( true ); + const [ showSticky, setShowSticky ] = useState( postType === 'post' ); const { authorList, categories, tags, postTypes } = useSelect( ( select ) => { const { getEntityRecords, getPostTypes } = select( 'core' ); @@ -72,6 +79,9 @@ export default function QueryInspectorControls( { query, setQuery } ) { setShowCategories( postTypeTaxonomies.includes( 'category' ) ); setShowTags( postTypeTaxonomies.includes( 'post_tag' ) ); }, [ postType, postTypesTaxonomiesMap ] ); + useEffect( () => { + setShowSticky( postType === 'post' ); + }, [ postType ] ); const postTypesSelectOptions = useMemo( () => ( postTypes || [] ).map( ( { labels, slug } ) => ( { @@ -88,6 +98,9 @@ export default function QueryInspectorControls( { query, setQuery } ) { if ( ! postTypesTaxonomiesMap[ newValue ].includes( 'post_tag' ) ) { updateQuery.tagIds = []; } + if ( newValue !== 'post' ) { + updateQuery.sticky = ''; + } setQuery( updateQuery ); }; // Handles categories and tags changes. @@ -111,6 +124,14 @@ export default function QueryInspectorControls( { query, setQuery } ) { onChangeDebounced(); return onChangeDebounced.cancel; }, [ querySearch, onChangeDebounced ] ); + const stickyOptions = useMemo( () => [ + { + label: __( 'Include' ), + value: '', + }, + { label: __( 'Exclude' ), value: 'exclude' }, + { label: __( 'Only' ), value: 'only' }, + ] ); return ( @@ -161,6 +182,14 @@ export default function QueryInspectorControls( { query, setQuery } ) { value={ querySearch } onChange={ setQuerySearch } /> + { showSticky && ( + setQuery( { sticky: value } ) } + /> + ) } ); diff --git a/packages/e2e-tests/fixtures/blocks/core__embed.json b/packages/e2e-tests/fixtures/blocks/core__embed.json index b76699b65e052..3eab30b025248 100644 --- a/packages/e2e-tests/fixtures/blocks/core__embed.json +++ b/packages/e2e-tests/fixtures/blocks/core__embed.json @@ -1,16 +1,16 @@ [ - { - "clientId": "_clientId_0", - "name": "core/embed", - "isValid": true, - "attributes": { - "url": "https://example.com/", - "caption": "Embedded content from an example URL", - "allowResponsive": true, - "responsive": false, - "previewable": true - }, - "innerBlocks": [], - "originalContent": "
\n
\n https://example.com/\n
\n
Embedded content from an example URL
\n
" - } + { + "clientId": "_clientId_0", + "name": "core/embed", + "isValid": true, + "attributes": { + "url": "https://example.com/", + "caption": "Embedded content from an example URL", + "allowResponsive": true, + "responsive": false, + "previewable": true + }, + "innerBlocks": [], + "originalContent": "
\n
\n https://example.com/\n
\n
Embedded content from an example URL
\n
" + } ] diff --git a/packages/e2e-tests/fixtures/blocks/core__latest-posts.json b/packages/e2e-tests/fixtures/blocks/core__latest-posts.json index 277eb6b63a38b..3a2fbedad6e8f 100644 --- a/packages/e2e-tests/fixtures/blocks/core__latest-posts.json +++ b/packages/e2e-tests/fixtures/blocks/core__latest-posts.json @@ -1,26 +1,26 @@ [ - { - "clientId": "_clientId_0", - "name": "core/latest-posts", - "isValid": true, - "attributes": { - "postsToShow": 5, - "displayPostContent": false, - "displayPostContentRadio": "excerpt", - "excerptLength": 55, - "displayAuthor": false, - "displayPostDate": false, - "postLayout": "list", - "columns": 3, - "order": "desc", - "orderBy": "date", - "displayFeaturedImage": false, - "featuredImageSizeSlug": "thumbnail", - "featuredImageSizeWidth": null, - "featuredImageSizeHeight": null, - "addLinkToFeaturedImage": false - }, - "innerBlocks": [], - "originalContent": "" - } + { + "clientId": "_clientId_0", + "name": "core/latest-posts", + "isValid": true, + "attributes": { + "postsToShow": 5, + "displayPostContent": false, + "displayPostContentRadio": "excerpt", + "excerptLength": 55, + "displayAuthor": false, + "displayPostDate": false, + "postLayout": "list", + "columns": 3, + "order": "desc", + "orderBy": "date", + "displayFeaturedImage": false, + "featuredImageSizeSlug": "thumbnail", + "featuredImageSizeWidth": null, + "featuredImageSizeHeight": null, + "addLinkToFeaturedImage": false + }, + "innerBlocks": [], + "originalContent": "" + } ] diff --git a/packages/e2e-tests/fixtures/blocks/core__latest-posts__displayPostDate.json b/packages/e2e-tests/fixtures/blocks/core__latest-posts__displayPostDate.json index 9f9b5784eb74c..5a0e2d328f714 100644 --- a/packages/e2e-tests/fixtures/blocks/core__latest-posts__displayPostDate.json +++ b/packages/e2e-tests/fixtures/blocks/core__latest-posts__displayPostDate.json @@ -1,26 +1,26 @@ [ - { - "clientId": "_clientId_0", - "name": "core/latest-posts", - "isValid": true, - "attributes": { - "postsToShow": 5, - "displayPostContent": false, - "displayPostContentRadio": "excerpt", - "excerptLength": 55, - "displayAuthor": false, - "displayPostDate": true, - "postLayout": "list", - "columns": 3, - "order": "desc", - "orderBy": "date", - "displayFeaturedImage": false, - "featuredImageSizeSlug": "thumbnail", - "featuredImageSizeWidth": null, - "featuredImageSizeHeight": null, - "addLinkToFeaturedImage": false - }, - "innerBlocks": [], - "originalContent": "" - } + { + "clientId": "_clientId_0", + "name": "core/latest-posts", + "isValid": true, + "attributes": { + "postsToShow": 5, + "displayPostContent": false, + "displayPostContentRadio": "excerpt", + "excerptLength": 55, + "displayAuthor": false, + "displayPostDate": true, + "postLayout": "list", + "columns": 3, + "order": "desc", + "orderBy": "date", + "displayFeaturedImage": false, + "featuredImageSizeSlug": "thumbnail", + "featuredImageSizeWidth": null, + "featuredImageSizeHeight": null, + "addLinkToFeaturedImage": false + }, + "innerBlocks": [], + "originalContent": "" + } ] diff --git a/packages/e2e-tests/fixtures/blocks/core__post-featured-image.json b/packages/e2e-tests/fixtures/blocks/core__post-featured-image.json index 5ff35f8591ad0..5ebd0b2ac8c1f 100644 --- a/packages/e2e-tests/fixtures/blocks/core__post-featured-image.json +++ b/packages/e2e-tests/fixtures/blocks/core__post-featured-image.json @@ -1,12 +1,12 @@ [ - { - "clientId": "_clientId_0", - "name": "core/post-featured-image", - "isValid": true, - "attributes": { - "isLink": false - }, - "innerBlocks": [], - "originalContent": "" - } + { + "clientId": "_clientId_0", + "name": "core/post-featured-image", + "isValid": true, + "attributes": { + "isLink": false + }, + "innerBlocks": [], + "originalContent": "" + } ] diff --git a/packages/e2e-tests/fixtures/blocks/core__post-title.json b/packages/e2e-tests/fixtures/blocks/core__post-title.json index 20aac7e0a3ad9..4505015af6062 100644 --- a/packages/e2e-tests/fixtures/blocks/core__post-title.json +++ b/packages/e2e-tests/fixtures/blocks/core__post-title.json @@ -1,15 +1,15 @@ [ - { - "clientId": "_clientId_0", - "name": "core/post-title", - "isValid": true, - "attributes": { - "level": 2, - "isLink": false, - "linkTarget": "_self", - "rel": "" - }, - "innerBlocks": [], - "originalContent": "" - } + { + "clientId": "_clientId_0", + "name": "core/post-title", + "isValid": true, + "attributes": { + "level": 2, + "isLink": false, + "rel": "", + "linkTarget": "_self" + }, + "innerBlocks": [], + "originalContent": "" + } ] diff --git a/packages/e2e-tests/fixtures/blocks/core__query.json b/packages/e2e-tests/fixtures/blocks/core__query.json index e02bc6db95485..3e90d6a3f9c0f 100644 --- a/packages/e2e-tests/fixtures/blocks/core__query.json +++ b/packages/e2e-tests/fixtures/blocks/core__query.json @@ -1,24 +1,25 @@ [ - { - "clientId": "_clientId_0", - "name": "core/query", - "isValid": true, - "attributes": { - "query": { - "perPage": null, - "pages": 1, - "offset": 0, - "postType": "post", - "categoryIds": [], - "tagIds": [], - "order": "desc", - "orderBy": "date", - "author": "", - "search": "", - "exclude": [] - } - }, - "innerBlocks": [], - "originalContent": "" - } + { + "clientId": "_clientId_0", + "name": "core/query", + "isValid": true, + "attributes": { + "query": { + "perPage": null, + "pages": 1, + "offset": 0, + "postType": "post", + "categoryIds": [], + "tagIds": [], + "order": "desc", + "orderBy": "date", + "author": "", + "search": "", + "exclude": [], + "sticky": "" + } + }, + "innerBlocks": [], + "originalContent": "" + } ] diff --git a/packages/e2e-tests/fixtures/blocks/core__search.json b/packages/e2e-tests/fixtures/blocks/core__search.json index 9bfe776f2127f..26c1bad1c57f4 100644 --- a/packages/e2e-tests/fixtures/blocks/core__search.json +++ b/packages/e2e-tests/fixtures/blocks/core__search.json @@ -4,10 +4,10 @@ "name": "core/search", "isValid": true, "attributes": { - "buttonPosition": "button-outside", - "buttonUseIcon": false, + "showLabel": true, "placeholder": "", - "showLabel": true + "buttonPosition": "button-outside", + "buttonUseIcon": false }, "innerBlocks": [], "originalContent": "" diff --git a/packages/e2e-tests/fixtures/blocks/core__search__custom-text.json b/packages/e2e-tests/fixtures/blocks/core__search__custom-text.json index 5d2c86a18d590..a490ed43df73f 100644 --- a/packages/e2e-tests/fixtures/blocks/core__search__custom-text.json +++ b/packages/e2e-tests/fixtures/blocks/core__search__custom-text.json @@ -4,12 +4,12 @@ "name": "core/search", "isValid": true, "attributes": { - "buttonPosition": "button-outside", "label": "Custom label", + "showLabel": true, "placeholder": "Custom placeholder", "buttonText": "Custom button text", - "buttonUseIcon": false, - "showLabel": true + "buttonPosition": "button-outside", + "buttonUseIcon": false }, "innerBlocks": [], "originalContent": "" diff --git a/packages/e2e-tests/fixtures/blocks/core__social-links.json b/packages/e2e-tests/fixtures/blocks/core__social-links.json index 42232b6887ae5..eaf67458e6938 100644 --- a/packages/e2e-tests/fixtures/blocks/core__social-links.json +++ b/packages/e2e-tests/fixtures/blocks/core__social-links.json @@ -4,8 +4,8 @@ "name": "core/social-links", "isValid": true, "attributes": { - "openInNewTab": false - }, + "openInNewTab": false + }, "innerBlocks": [ { "clientId": "_clientId_0", diff --git a/packages/e2e-tests/fixtures/blocks/core__video.json b/packages/e2e-tests/fixtures/blocks/core__video.json index d3c9d1ddbd380..8b5963a98c714 100644 --- a/packages/e2e-tests/fixtures/blocks/core__video.json +++ b/packages/e2e-tests/fixtures/blocks/core__video.json @@ -11,8 +11,8 @@ "muted": false, "preload": "metadata", "src": "data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE=", - "playsInline": false, - "tracks": [] + "playsInline": false, + "tracks": [] }, "innerBlocks": [], "originalContent": "
"