admin管理员组

文章数量:1129630

We have a simple plugin to display a tree menu, which includes the parent page, plus the parent page's children (so, the siblings of the current page).

We're using the following get_pages code:

$pages = get_pages( [
   'child_of' => $parent,
   'sort_order' => 'ASC',
   'sort_column' => 'menu_order',
]);

However, the pages are listed in ascending order of date created (oldest first).

How do we make the pages be listed in the page order in the right sidebar of the edit page screen?

We have a simple plugin to display a tree menu, which includes the parent page, plus the parent page's children (so, the siblings of the current page).

We're using the following get_pages code:

$pages = get_pages( [
   'child_of' => $parent,
   'sort_order' => 'ASC',
   'sort_column' => 'menu_order',
]);

However, the pages are listed in ascending order of date created (oldest first).

How do we make the pages be listed in the page order in the right sidebar of the edit page screen?

Share Improve this question edited Dec 2, 2020 at 3:03 Steve asked Dec 2, 2020 at 2:21 SteveSteve 1,75719 gold badges66 silver badges114 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 2

When the child_of parameter is set, get_pages() will use get_page_children() to get the child pages, and unfortunately, the sort_column will no longer be used, hence the final list will not be sorted by the specified custom sort column, so you'll need to use your own code for getting the list with the expected sort column (and order).

Here's an example which uses a custom function that's called recursively (until all child pages are retrieved) and then walk_page_tree() is used (instead of wp_list_pages() which has the same issue as get_pages()) to output the pages in a list (li) layout:

// In the theme functions file:
function my_get_pages( $parent, $orderby = 'menu_order', $order = 'ASC' ) {
    $pages = get_pages( array(
        'parent'      => $parent,
        'sort_column' => $orderby,
        'sort_order'  => $order,
    ) );

    $children = array();
    foreach ( $pages as $page ) {
        $children[] = $page;

        // Retrieve grandchildren.
        $children2 = my_get_pages( $page->ID, $orderby, $order );
        if ( ! empty( $children2 ) ) {
            $children = array_merge( $children, $children2 );
        }
    }

    return $children;
}

// In your template:
$parent = 123; // parent post/Page ID

$pages = my_get_pages( $parent );

echo '<ul>' .
    walk_page_tree( $pages, 0, get_queried_object_id(), array() ) .
'</ul>';

Here's another example, similar to the above, but this one doesn't use walk_page_tree() — and you've got full control over the HTML:

// In the theme functions file:
function my_wp_list_pages( $parent, $orderby = 'menu_order', $order = 'ASC' ) {
    $pages = get_pages( array(
        'parent'      => $parent,
        'sort_column' => $orderby,
        'sort_order'  => $order,
    ) );

    if ( empty( $pages ) ) {
        return;
    }

    // Just change the HTML markup based on your liking..
    echo '<ul>';

    foreach ( $pages as $page ) {
        printf( '<li><a href="%s">%s</a></li>',
            esc_url( get_permalink( $page ) ),
            get_the_title( $page ) );

        // Display grandchildren.
        my_wp_list_pages( $page->ID, $orderby, $order );
    }

    echo '</ul>';
}

// In your template:
$parent = 123; // parent post/Page ID

my_wp_list_pages( $parent );

Both the wp_list_pages() and get_pages() functions have a sort_column parameter where you can pass in menu_order. For example:

$output = wp_list_pages( [
    'include'       => $page_ids,
    'title_li'      => false,
    'echo'          => false,
    'sort_column'   => 'menu_order',
] );

Menu Order will be the "Order" field seen in the Page Attributes Metabox or Page Attributes section of the Block Editor.

Use usort to sort the resulting $pages array based on menu_order

usort($pages, function ($a, $b) {
    return $a->menu_order - $b->menu_order;
});

本文标签: sort39sortcolumn39 gt 39menuorder39 not working