diff --git a/package-lock.json b/package-lock.json
index f9784f50162f40..a749eb4958e5b8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18124,6 +18124,7 @@
"@wordpress/date": "file:packages/date",
"@wordpress/deprecated": "file:packages/deprecated",
"@wordpress/dom": "file:packages/dom",
+ "@wordpress/editor": "file:packages/editor",
"@wordpress/element": "file:packages/element",
"@wordpress/escape-html": "file:packages/escape-html",
"@wordpress/hooks": "file:packages/hooks",
diff --git a/packages/block-library/package.json b/packages/block-library/package.json
index ae87aa4c5e9a4b..821965e9bee975 100644
--- a/packages/block-library/package.json
+++ b/packages/block-library/package.json
@@ -46,6 +46,7 @@
"@wordpress/date": "file:../date",
"@wordpress/deprecated": "file:../deprecated",
"@wordpress/dom": "file:../dom",
+ "@wordpress/editor": "file:../editor",
"@wordpress/element": "file:../element",
"@wordpress/escape-html": "file:../escape-html",
"@wordpress/hooks": "file:../hooks",
diff --git a/packages/block-library/src/page-list/block.json b/packages/block-library/src/page-list/block.json
index a16a0b0abeb0fa..5b248552b872d5 100644
--- a/packages/block-library/src/page-list/block.json
+++ b/packages/block-library/src/page-list/block.json
@@ -3,7 +3,7 @@
"name": "core/page-list",
"title": "Page List",
"category": "widgets",
- "description": "Display a list of all pages.",
+ "description": "Display a list of pages.",
"keywords": [ "menu", "navigation" ],
"textdomain": "default",
"attributes": {
@@ -39,6 +39,9 @@
},
"openSubmenusOnClick" : {
"type": "boolean"
+ },
+ "showOnlyChildPages": {
+ "type": "boolean"
}
},
"usesContext": [
diff --git a/packages/block-library/src/page-list/edit.js b/packages/block-library/src/page-list/edit.js
index 2311308c41b165..3ef26214292dcb 100644
--- a/packages/block-library/src/page-list/edit.js
+++ b/packages/block-library/src/page-list/edit.js
@@ -11,9 +11,11 @@ import {
useBlockProps,
store as blockEditorStore,
getColorClassName,
+ InspectorControls,
} from '@wordpress/block-editor';
import ServerSideRender from '@wordpress/server-side-render';
-import { ToolbarButton } from '@wordpress/components';
+import { PanelBody, ToggleControl, ToolbarButton } from '@wordpress/components';
+import { store as editorStore } from '@wordpress/editor';
import { __ } from '@wordpress/i18n';
import { useEffect, useState } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
@@ -86,7 +88,7 @@ export default function PageListEdit( {
style: { ...style?.color },
} );
- const isParentNavigation = useSelect(
+ const isParentBlockNavigation = useSelect(
( select ) => {
const { getBlockParentsByBlockName } = select( blockEditorStore );
return (
@@ -97,16 +99,23 @@ export default function PageListEdit( {
[ clientId ]
);
+ const showChildPageToggle = useSelect( ( select ) => {
+ const { getCurrentPostType } = select( editorStore );
+ const currentPostType = getCurrentPostType();
+ const allowedTypes = [ 'page', 'wp_template' ];
+ return allowedTypes.includes( currentPostType );
+ } );
+
useEffect( () => {
setAttributes( {
- isNavigationChild: isParentNavigation,
+ isNavigationChild: isParentBlockNavigation,
openSubmenusOnClick: !! context.openSubmenusOnClick,
showSubmenuIcon: !! context.showSubmenuIcon,
} );
}, [ context.openSubmenusOnClick, context.showSubmenuIcon ] );
useEffect( () => {
- if ( isParentNavigation ) {
+ if ( isParentBlockNavigation ) {
apiFetch( {
path: addQueryArgs( '/wp/v2/pages', {
per_page: 1,
@@ -121,22 +130,38 @@ export default function PageListEdit( {
} else {
setAllowConvertToLinks( false );
}
- }, [ isParentNavigation ] );
+ }, [ isParentBlockNavigation ] );
const [ isOpen, setOpen ] = useState( false );
const openModal = () => setOpen( true );
const closeModal = () => setOpen( false );
// Update parent status before component first renders.
- const attributesWithParentStatus = {
+ const attributesWithParentBlockStatus = {
...attributes,
- isNavigationChild: isParentNavigation,
+ isNavigationChild: isParentBlockNavigation,
openSubmenusOnClick: !! context.openSubmenusOnClick,
showSubmenuIcon: !! context.showSubmenuIcon,
};
return (
<>
+
+ { showChildPageToggle && (
+
+
+ setAttributes( {
+ showOnlyChildPages: ! attributes.showOnlyChildPages,
+ } )
+ }
+ help={ __( 'Uses parent to list child pages.' ) }
+ />
+
+ ) }
+
{ allowConvertToLinks && (
@@ -153,7 +178,7 @@ export default function PageListEdit( {
>
diff --git a/packages/block-library/src/page-list/index.php b/packages/block-library/src/page-list/index.php
index 6f99ab14c95ef3..929a96c1ffef6f 100644
--- a/packages/block-library/src/page-list/index.php
+++ b/packages/block-library/src/page-list/index.php
@@ -235,21 +235,30 @@ function block_core_page_list_nest_pages( $current_level, $children ) {
* @return string Returns the page list markup.
*/
function render_block_core_page_list( $attributes, $content, $block ) {
+ global $post;
static $block_id = 0;
$block_id++;
+ $only_child_pages = isset( $attributes['showOnlyChildPages'] ) && $attributes['showOnlyChildPages'];
+ // The pages will be siblings (same parent) or set parent id equal to self if no children.
+ $parent_id = ( $post->post_parent ) ? $post->post_parent : $post->ID;
+
// TODO: When https://core.trac.wordpress.org/ticket/39037 REST API support for multiple orderby values is resolved,
// update 'sort_column' to 'menu_order, post_title'. Sorting by both menu_order and post_title ensures a stable sort.
// Otherwise with pages that have the same menu_order value, we can see different ordering depending on how DB
// queries are constructed internally. For example we might see a different order when a limit is set to <499
// versus >= 500.
- $all_pages = get_pages(
- array(
- 'sort_column' => 'menu_order',
- 'order' => 'asc',
- )
+ $query_args = array(
+ 'sort_column' => 'menu_order',
+ 'order' => 'asc',
);
+ if ( $only_child_pages && $parent_id ) {
+ $query_args['child_of'] = $parent_id;
+ }
+
+ $all_pages = get_pages( $query_args );
+
$top_level_pages = array();
$pages_with_children = array();
@@ -263,7 +272,16 @@ function render_block_core_page_list( $attributes, $content, $block ) {
$active_page_ancestor_ids = get_post_ancestors( $page->ID );
}
- if ( $page->post_parent ) {
+ // When showing only child pages of parent, set the pages to top level
+ // since there is no other top level page.
+ if ( $only_child_pages ) {
+ $top_level_pages[ $page->ID ] = array(
+ 'page_id' => $page->ID,
+ 'title' => $page->post_title,
+ 'link' => get_permalink( $page->ID ),
+ 'is_active' => $is_active,
+ );
+ } else if ( $page->post_parent ) {
$pages_with_children[ $page->post_parent ][ $page->ID ] = array(
'page_id' => $page->ID,
'title' => $page->post_title,