diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md
index ac43e93ccbcc6..27182a0f87ead 100644
--- a/docs/reference-guides/core-blocks.md
+++ b/docs/reference-guides/core-blocks.md
@@ -609,7 +609,7 @@ An advanced block that allows displaying post types based on different query par
- **Name:** core/query
- **Category:** theme
- **Supports:** align (full, wide), color (background, gradients, link, text), ~~html~~
-- **Attributes:** displayLayout, query, queryId, tagName
+- **Attributes:** displayLayout, namespace, query, queryId, tagName
## No results
diff --git a/packages/block-library/src/query/block.json b/packages/block-library/src/query/block.json
index 6267e53f24c12..cd09e22ee57f7 100644
--- a/packages/block-library/src/query/block.json
+++ b/packages/block-library/src/query/block.json
@@ -37,6 +37,9 @@
"default": {
"type": "list"
}
+ },
+ "namespace": {
+ "type": "string"
}
},
"providesContext": {
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 72db4563054e4..33e77def49352 100644
--- a/packages/block-library/src/query/edit/inspector-controls/index.js
+++ b/packages/block-library/src/query/edit/inspector-controls/index.js
@@ -19,8 +19,6 @@ import {
import { __ } from '@wordpress/i18n';
import { InspectorControls } from '@wordpress/block-editor';
import { useEffect, useState, useCallback } from '@wordpress/element';
-import { useSelect } from '@wordpress/data';
-import { store as coreStore } from '@wordpress/core-data';
/**
* Internal dependencies
@@ -30,23 +28,19 @@ import AuthorControl from './author-control';
import ParentControl from './parent-control';
import { TaxonomyControls, useTaxonomiesInfo } from './taxonomy-controls';
import StickyControl from './sticky-control';
-import { usePostTypes } from '../../utils';
-
-function useIsPostTypeHierarchical( postType ) {
- return useSelect(
- ( select ) => {
- const type = select( coreStore ).getPostType( postType );
- return type?.viewable && type?.hierarchical;
- },
- [ postType ]
- );
-}
+import {
+ usePostTypes,
+ useIsPostTypeHierarchical,
+ useAllowedControls,
+ isControlAllowed,
+} from '../../utils';
export default function QueryInspectorControls( {
- attributes: { query, displayLayout },
+ attributes,
setQuery,
setDisplayLayout,
} ) {
+ const { query, displayLayout } = attributes;
const {
order,
orderBy,
@@ -57,6 +51,7 @@ export default function QueryInspectorControls( {
taxQuery,
parents,
} = query;
+ const allowedControls = useAllowedControls( attributes );
const [ showSticky, setShowSticky ] = useState( postType === 'post' );
const { postTypesTaxonomiesMap, postTypesSelectOptions } = usePostTypes();
const taxonomiesInfo = useTaxonomiesInfo( postType );
@@ -102,70 +97,90 @@ export default function QueryInspectorControls( {
onChangeDebounced();
return onChangeDebounced.cancel;
}, [ querySearch, onChangeDebounced ] );
+ const showInheritControl = isControlAllowed( allowedControls, 'inherit' );
+ const showPostTypeControl =
+ ! inherit && isControlAllowed( allowedControls, 'postType' );
+ const showColumnsControl = displayLayout?.type === 'flex';
+ const showOrderControl =
+ ! inherit && isControlAllowed( allowedControls, 'order' );
+ const showStickyControl =
+ ! inherit &&
+ showSticky &&
+ isControlAllowed( allowedControls, 'sticky' );
+ const showSettingsPanel =
+ showInheritControl ||
+ showPostTypeControl ||
+ showColumnsControl ||
+ showOrderControl ||
+ showStickyControl;
return (
<>
-
-
-
+
+ { showInheritControl && (
+
+ setQuery( { inherit: !! value } )
+ }
+ />
) }
- checked={ !! inherit }
- onChange={ ( value ) =>
- setQuery( { inherit: !! value } )
- }
- />
- { ! inherit && (
-
- ) }
- { displayLayout?.type === 'flex' && (
- <>
-
+ ) }
+ { showColumnsControl && (
+ <>
+
+ setDisplayLayout( { columns: value } )
+ }
+ min={ 2 }
+ max={ Math.max( 6, displayLayout.columns ) }
+ />
+ { displayLayout.columns > 6 && (
+
+ { __(
+ 'This column count exceeds the recommended amount and may cause visual breakage.'
+ ) }
+
+ ) }
+ >
+ ) }
+ { showOrderControl && (
+
+ ) }
+ { showStickyControl && (
+
- setDisplayLayout( { columns: value } )
+ setQuery( { sticky: value } )
}
- min={ 2 }
- max={ Math.max( 6, displayLayout.columns ) }
/>
- { displayLayout.columns > 6 && (
-
- { __(
- 'This column count exceeds the recommended amount and may cause visual breakage.'
- ) }
-
- ) }
- >
- ) }
- { ! inherit && (
-
- ) }
- { ! inherit && showSticky && (
-
- setQuery( { sticky: value } )
- }
- />
- ) }
-
-
+ ) }
+
+
+ ) }
{ ! inherit && (
- { !! taxonomiesInfo?.length && (
+ { !! taxonomiesInfo?.length &&
+ isControlAllowed( allowedControls, 'taxQuery' ) && (
+
+ Object.values( taxQuery || {} ).some(
+ ( terms ) => !! terms.length
+ )
+ }
+ onDeselect={ () =>
+ setQuery( { taxQuery: null } )
+ }
+ >
+
+
+ ) }
+ { isControlAllowed( allowedControls, 'author' ) && (
- Object.values( taxQuery || {} ).some(
- ( terms ) => !! terms.length
- )
- }
- onDeselect={ () =>
- setQuery( { taxQuery: null } )
- }
+ hasValue={ () => !! authorIds }
+ label={ __( 'Authors' ) }
+ onDeselect={ () => setQuery( { author: '' } ) }
>
-
) }
- !! authorIds }
- label={ __( 'Authors' ) }
- onDeselect={ () => setQuery( { author: '' } ) }
- >
-
-
- !! querySearch }
- label={ __( 'Keyword' ) }
- onDeselect={ () => setQuerySearch( '' ) }
- >
-
-
- { isPostTypeHierarchical && (
+ { isControlAllowed( allowedControls, 'search' ) && (
!! parents?.length }
- label={ __( 'Parents' ) }
- onDeselect={ () => setQuery( { parents: [] } ) }
+ hasValue={ () => !! querySearch }
+ label={ __( 'Keyword' ) }
+ onDeselect={ () => setQuerySearch( '' ) }
>
-
) }
+ { isPostTypeHierarchical &&
+ ! isControlAllowed(
+ allowedControls,
+ 'parents'
+ ) && (
+ !! parents?.length }
+ label={ __( 'Parents' ) }
+ onDeselect={ () =>
+ setQuery( { parents: [] } )
+ }
+ >
+
+
+ ) }
) }
diff --git a/packages/block-library/src/query/utils.js b/packages/block-library/src/query/utils.js
index fb62191696f11..d363357561663 100644
--- a/packages/block-library/src/query/utils.js
+++ b/packages/block-library/src/query/utils.js
@@ -10,7 +10,12 @@ 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';
+import { cloneBlock, store as blocksStore } from '@wordpress/blocks';
+
+/**
+ * Internal dependencies
+ */
+import { name as queryLoopName } from './block.json';
/**
* @typedef IHasNameAndId
@@ -127,6 +132,48 @@ export const useTaxonomies = ( postType ) => {
return taxonomies;
};
+/**
+ * Hook that returns whether a specific post type is hierarchical.
+ *
+ * @param {string} postType The post type to check.
+ * @return {boolean} Whether a specific post type is hierarchical.
+ */
+export function useIsPostTypeHierarchical( postType ) {
+ return useSelect(
+ ( select ) => {
+ const type = select( coreStore ).getPostType( postType );
+ return type?.viewable && type?.hierarchical;
+ },
+ [ postType ]
+ );
+}
+
+/**
+ * Hook that returns the query properties' names defined by the active
+ * block variation, to determine which block's filters to show.
+ *
+ * @param {Object} attributes Block attributes.
+ * @return {string[]} An array of the query attributes.
+ */
+export function useAllowedControls( attributes ) {
+ return useSelect(
+ ( select ) =>
+ select( blocksStore ).getActiveBlockVariation(
+ queryLoopName,
+ attributes
+ )?.allowControls,
+
+ [ attributes ]
+ );
+}
+export function isControlAllowed( allowedControls, key ) {
+ // Every controls is allowed if the list is not defined.
+ if ( ! allowedControls ) {
+ return true;
+ }
+ return allowedControls.includes( key );
+}
+
/**
* Clones a pattern's blocks and then recurses over that list of blocks,
* transforming them to retain some `query` attribute properties.