Skip to content

Commit

Permalink
Update Page List with toggle to show child pages
Browse files Browse the repository at this point in the history
- Adds a showOnlyChildPages attribute to Edit
- Update render to use attribute and only pull in children
- Do not show on post pages which will not have a parent
- Allow showing on wp_template pages

Fixes #31063
  • Loading branch information
mkaz committed Oct 30, 2021
1 parent 14a30f0 commit c60c176
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 45 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/block-library/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
5 changes: 4 additions & 1 deletion packages/block-library/src/page-list/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
"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": {
"showOnlyChildPages": {
"type": "boolean"
}
},
"usesContext": [
"textColor",
Expand Down
115 changes: 77 additions & 38 deletions packages/block-library/src/page-list/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import {
BlockControls,
useBlockProps,
getColorClassName,
InspectorControls,
} from '@wordpress/block-editor';
import { ToolbarButton, Placeholder, Spinner } from '@wordpress/components';
import { PanelBody, ToggleControl, ToolbarButton } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { useEffect, useState, memo } from '@wordpress/element';
import apiFetch from '@wordpress/api-fetch';
Expand All @@ -31,32 +33,80 @@ const MAX_PAGE_COUNT = 100;
export default function PageListEdit( { context, clientId } ) {
const { pagesByParentId, totalPages } = usePagesByParentId();

const isNavigationChild = 'showSubmenuIcon' in context;
const allowConvertToLinks =
isNavigationChild && totalPages <= MAX_PAGE_COUNT;
const isParentBlockNavigation = useSelect(
( select ) => {
const { getBlockParentsByBlockName } = select( blockEditorStore );
return (
getBlockParentsByBlockName( clientId, 'core/navigation' )
.length > 0
);
},
[ clientId ]
);

const showChildPageToggle = useSelect( ( select ) => {
const { getCurrentPostType } = select( editorStore );
const currentPostType = getCurrentPostType();
const allowedTypes = [ 'page', 'wp_template' ];
return allowedTypes.includes( currentPostType );
} );

useEffect( () => {
setAttributes( {
isNavigationChild: isParentBlockNavigation,
openSubmenusOnClick: !! context.openSubmenusOnClick,
showSubmenuIcon: !! context.showSubmenuIcon,
} );
}, [ context.openSubmenusOnClick, context.showSubmenuIcon ] );

useEffect( () => {
if ( isParentBlockNavigation ) {
apiFetch( {
path: addQueryArgs( '/wp/v2/pages', {
per_page: 1,
_fields: [ 'id' ],
} ),
parse: false,
} ).then( ( res ) => {
setAllowConvertToLinks(
res.headers.get( 'X-WP-Total' ) <= MAX_PAGE_COUNT
);
} );
} else {
setAllowConvertToLinks( false );
}
}, [ isParentBlockNavigation ] );

const [ isOpen, setOpen ] = useState( false );
const openModal = () => setOpen( true );
const closeModal = () => setOpen( false );

const blockProps = useBlockProps( {
className: classnames( 'wp-block-page-list', {
'has-text-color': !! context.textColor,
[ getColorClassName(
'color',
context.textColor
) ]: !! context.textColor,
'has-background': !! context.backgroundColor,
[ getColorClassName(
'background-color',
context.backgroundColor
) ]: !! context.backgroundColor,
} ),
style: { ...context.style?.color },
} );
// Update parent status before component first renders.
const attributesWithParentBlockStatus = {
...attributes,
isNavigationChild: isParentBlockNavigation,
openSubmenusOnClick: !! context.openSubmenusOnClick,
showSubmenuIcon: !! context.showSubmenuIcon,
};

return (
<>
<InspectorControls>
{ showChildPageToggle && (
<PanelBody>
<ToggleControl
label={ __( 'List child pages' ) }
checked={ !! attributes.showOnlyChildPages }
onChange={ () =>
setAttributes( {
showOnlyChildPages: ! attributes.showOnlyChildPages,
} )
}
help={ __( 'Uses parent to list child pages.' ) }
/>
</PanelBody>
) }
</InspectorControls>
{ allowConvertToLinks && (
<BlockControls group="other">
<ToolbarButton title={ __( 'Edit' ) } onClick={ openModal }>
Expand All @@ -70,26 +120,15 @@ export default function PageListEdit( { context, clientId } ) {
clientId={ clientId }
/>
) }
{ totalPages === null && (
<div { ...blockProps }>
<Placeholder>
<Spinner />
</Placeholder>
</div>
) }
{ totalPages === 0 && (
<div { ...blockProps }>
<span>{ __( 'Page List: No pages to show.' ) }</span>
</div>
) }
{ totalPages > 0 && (
<ul { ...blockProps }>
<PageItems
context={ context }
pagesByParentId={ pagesByParentId }
/>
</ul>
) }
<div { ...blockProps }>
<ServerSideRender
block="core/page-list"
attributes={ attributesWithParentBlockStatus }
EmptyResponsePlaceholder={ () => (
<span>{ __( 'Page List: No pages to show.' ) }</span>
) }
/>
</div>
</>
);
}
Expand Down
35 changes: 29 additions & 6 deletions packages/block-library/src/page-list/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -236,16 +236,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++;

$all_pages = get_pages(
array(
'sort_column' => 'menu_order,post_title',
'order' => 'asc',
)
$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.
$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 );

// If thare are no pages, there is nothing to show.
if ( empty( $all_pages ) ) {
return;
Expand All @@ -264,7 +278,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,
Expand Down

0 comments on commit c60c176

Please sign in to comment.