I have a hierarchical CPT with the following structure:

- parent item 1
   - child item 1
   - child item 2
   - child item 3
   - child item 4
   - child item 5
- parent item 2
   - child item 1
   - child item 2
   - child item 3
   - child item 4
   - child item 5

each child item has a meta key called "section_id" which is numeric and corresponds to it's order within the parent. The date stamps are approx 5 minutes apart from each other.

what I want to accomplish is sorting each parent item in descending date order, THEN the child items in either ascending date order or by the meta section_id (either will work, since they will product the same results)

running a pre_get_posts or parse_query allow me to do one or the other, but not both. is it possible to do this?

note this is only for the admin post table, not the front end.

  • Where precisely do you want to accomplish this? Post list table?
    – Rarst
    Commented Aug 29, 2013 at 13:20
  • @Rarst correct. the front-end is all set and working as expected. right now, it's all in DESC order, which is good for the parent items, but backwards for the child items.
    – Norcross
    Commented Aug 29, 2013 at 13:34
  • 1
    For me there is no chance. WP_Posts_List_Table do not use query to accomplish hierachical post displaying, only foreach cycles on the retrieved post array that arrange post into two array: one for top level posts and one (two dimensional) for children posts. In addition there are no filter that permit to edit this arrays.
    – gmazzap
    Commented Aug 29, 2013 at 15:32
  • I'm seeing that myself. This was a 'nice to have' thing, so I'm bailing for now.
    – Norcross
    Commented Aug 30, 2013 at 15:33
  • Ideea: if (git) patches aren't a big overhead for your project and you see them as an acceptable form of hacking the core, try adding a filter to _get_list_table() as a patch, so you can extend WP_Posts_List_Table afterwards Commented Sep 24, 2013 at 20:04

2 Answers 2


As I couldn't find any filter to override the WP_Posts_List_Table class, I propose a quite hacky solution by doing this:

  1. Query only parents in pre_get_posts;
  2. Query their children on wp and change $wp_query->posts accordingly.

This might need some more work as I'm probably breaking pagination numbers or so.

// Use a query variable to control when to change the main admin query
add_filter( 'query_vars', 'custom_admin_list_query_vars', 10, 1 );
function custom_admin_list_query_vars( $vars ) {
    array_push( $vars, 'custom_admin_list_children' );
    return $vars;

add_action( 'pre_get_posts', 'custom_admin_pre_get_posts' );
function custom_admin_pre_get_posts( $query ) {

    global $post_type;

    // Change query only if it's a user-triggered query in admin
    if ( ! is_admin()
        || 'page' != $post_type
        || $query->get( 'custom_admin_list_children' ) )
        return false;

    // Query only parents in date order
    $query->set( 'post_parent', 0 );
    $query->set( 'orderby', 'post_date' );
    $query->set( 'order', 'desc' );


// Query the children of the parents above
add_action( 'wp', 'custom_admin_list_wp' );
function custom_admin_list_wp() {

    global $post_type, $wp_query;

    if ( ! is_admin() || 'page' != $post_type )
        return false;

    $args = array(
        'post_type' => 'page',
        'numberposts' => -1,
        'custom_admin_list_children' => true,
        'meta_key' => 'section_id',
        'orderby' => 'meta_value_num',
        'order' => 'asc'

    // Get children
    $children = array();
    for( $i = 0; $i < count( $wp_query->posts ); $i++ ) {
        $args['post_parent'] = $wp_query->posts[ $i ]->ID;
        $children[ $i ] = get_posts( $args );

    // Flag as a children with a '--' in front of the title
    foreach( $children as &$c ) {
        if ( !empty( $c->post_title ) )
            $c->post_title = '&mdash;&nbsp;' . $c->post_title;

    // Put everything together
    $posts = array();
    for( $i = 0; $i < count( $wp_query->posts ); $i++ ) {
        $posts[] = $wp_query->posts[ $i ];
        $posts = array_merge( $posts, $children[ $i ] );

    $wp_query->posts = $posts;
    $wp_query->post_count = count( $posts );


If you want to sort hierarchical posts, then the straightforward way to do this is to use the "order" field. This will allow you to rearrange the order of the child posts in any way you like. Instead of 1,2,3,... I recommend you use 10,20,30,... leaving space for future changes.

It would be nice, of course, if Wordpress offered a drag and drop interface to make that task painless, but as far as I can see, there isn't one (or perhaps there's a plugin).

This isn't exactly what you asked for (the ability to do two kinds of sorting in one list), but hopefully it accomplishes your end goal.

  • thanks, but that wasn't what I was looking for. and a drag and drop can be built (I've done it) but this is over 1000 items, which would kill the admin. I realized it wasn't worth the headache.
    – Norcross
    Commented Sep 16, 2013 at 5:12
  • 1
    There are some decent drag-and-drop plugins out there for reordering pages/post types. I tend to like the Simple Page Ordering plugin myself.
    – Jen
    Commented Nov 26, 2013 at 15:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.