Drag n Drop Post Order for multiple Custom Post Types

It’s common to utilize the WordPress navigational menu UI to get the drag/drop feature for free.

I think there are already some answers, on this site, explaining this better than I can, but I can’t seem to find them for you. So let my try to construct one simple example:

  1. We go to Appearance/Menus and create a menu with e.g. the mylist menu id.

  2. Then we drag/drop posts onto that menu and save it.

  3. Add the following shortcode to a page/post content:

    [wpd_list menu_id="mylist"]
    

with the following code snippet to support it:

/**
 * Shortcode [wpd_list] to display posts ordered by the nav menu UI
 */
add_shortcode( 'wpd_list', function( $atts = array(), $content = null )
{
    $atts  = shortcode_atts( 
        array( 'menu_id' => '', ), 
        $atts, 
        'shortcode_wpd_list' 
    );
    $items = wp_get_nav_menu_items( sanitize_key( $atts['menu_id'] ) );
    $ids   = wp_list_pluck( $items, 'object_id' );   // Don't use db_id or page_name!
    $li    = '';
    $q     = new WP_Query( 
        array( 
            'post_type' => 'any', 
            'post__in'  => (array) $ids,
            'orderby'   => 'post__in',         // Must have for the correct order!
        ) 
    );
    while( $q->have_posts() )
    { 
        $q->the_post();
        $li .= sprintf( 
            '<li><h2><a href="https://wordpress.stackexchange.com/questions/120941/%s">%s</a></h2></li>',    // Modify this HTML to your needs!
             get_permalink(), 
             get_the_title() 
        );
    }
    wp_reset_postdata();
    return ! empty( $li ) ? sprintf( '<ul>%s</ul>', $li ) : '';
} );

PS: When writing this example I did at least two mistakes at first 😉

I first forgot to fetch the posts in the posts__in order, to match the nav menu order.

Secondly I used the db_id as the post ID’s instead, of the object_id field.

After fixing that, this seemed to run as expected, so I just post it here now 😉

Leave a Comment