Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
150 views
in Technique[技术] by (71.8m points)

php - Wordpress Sorting CPT according to hierarchy in admin panel

I have problem with sorting my custom post type in admin panel. Is it possible to leave children position below parent? I don't know if this is clear, but below I made examples trees.

My actual hierarchy without any sorting is:

Event 1 
 - AEvent 1
 - BEvent 2
 - CEvent 3
Devent 1 

But, when I'm sorting by title (after click in column header) it look like:

 - AEvent 1 
 - BEvent2
 - CEvent 3
 - DEvent1  
 - Event 1

And I would like it to look like this:

DEvent 1
Event 1 
 - AEvent 1
 - BEvent 2
 - CEvent 3

I'm trying to use this example, with simply modify with my CPT

 // 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()
        || 'events' != $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() || 'events' != $post_type )
        return false;

    $args = array(
        'post_type' => 'events',
        'numberposts' => -1,
        'custom_admin_list_children' => true,
        'meta_key' => '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_children( $args );
        echo '<pre>';
        print_r($children);
        echo '--';
        print_r($wp_query->posts[ $i ]->ID);
        echo '</pre>';
    }
    
    // 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 );
    

}

But this not showing child posts.

question from:https://stackoverflow.com/questions/65877949/wordpress-sorting-cpt-according-to-hierarchy-in-admin-panel

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If anyone have same problem as me, below is my working answer.

On my first post I have incorrect orderby value in $args, so I cannot see my child posts. When I change this to title, then I saw child pages, and at the end I'm getting $_GET value to check ASC, DESC order option.

// 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() || 'events' != $post_type || $query->get('custom_admin_list_children')     )
        return false;
    $orderby = $_GET['orderby'];
    if ($orderby == 'title') {
        $order = $_GET['order'];
        // Query only parents in date order
        $query->set('post_parent', 0);
        $query->set('orderby', 'post_date');
        $query->set('order', $order);
    }
}

// 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() || 'events' != $post_type)
        return false;

    $orderby = $_GET['orderby'];
    if ($orderby == 'title') {
        $order = $_GET['order'];

        $args = array(
            'post_type' => 'events',
            'numberposts' => -1,
            'custom_admin_list_children' => true,
            'orderby' => 'title',
            'order' => $order
        );

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

        // Flag as a children with a '--' in front of the title
        foreach ($children as &$c) {
            if (!empty($c->post_title))
                $c->post_title = '-' . $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);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...