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,