2

We're looking to add two new (custom post type) entries between Dashboard and Posts.

In this project, for the end user, two items are going to be by far the most used items in his dashboard. So we want them at the top.

These seem to be the built in menu_position settings:

enter image description here

This only gives a single slot, menu_position=3, between Dashboard and Posts. And we need two slots!

What we've tried:

1) Using decimals - as strings - is sometimes suggested (ie. 3.1 and 3.2). But this definitely doesn't work in current WordPress. Our menu entries drop down to the default position.

2) Setting both of them to 3. This isn't allowed. It results in one of them dropping down to the default position.

Other suggestions on this site involve a custom function which grabs all the menu items one by one and reorders them individually but this looks fragile. What if other items are added at a later date? Can't we just reorder Dashboard up (or Posts down) to make space?

2 Answers 2

2

The order of the menu items can be changed using the filter menu_order

add_filter( 'menu_order', 'se354759_menu_order' );
add_filter( 'custom_menu_order', '__return_true' );

function se354759_menu_order ($menu_order)
{
    $cpts = [
        'edit.php?post_type=' . 'custom-post-type', 
        'edit.php?post_type=' . 'another-cpt'
    ];
    //
    // remove and save first item ("dashboard") in variable
    $first_item = array_shift( $menu_order );
    foreach( $cpts as $ctp )
    {
        $idx = array_search( $ctp, $menu_order );
        if ( $idx === false )
            continue;
        //
        // remove CPT menu item from array
        unset( $menu_order[$idx] );
        //
        // add CPT item to the beginning of the array
        array_unshift( $menu_order, $ctp );
    }
    //
    // re-add "dashboard" item
    array_unshift( $menu_order, $first_item );

    return $menu_order;
}
1
  • works perfectly, thanks
    – hawbsl
    Dec 17, 2019 at 17:11
0

@nmr answer was incredibly helpful. For anyone who stumbles upon this, I also had an ACF options page fighting for order, as well. I modified the code to accommodate this by including the menu slug for the ACF options page:

if( function_exists('acf_add_options_page') ) { 
    acf_add_options_page(array(
        'page_title'    => 'Site Settings',
        'menu_title'    => 'Site Settings',
        'menu_slug'     => 'my-ACF-slug'
    )); 
}

And then the filter modified:

add_filter( 'menu_order', 'se354759_menu_order' );
add_filter( 'custom_menu_order', '__return_true' );

function se354759_menu_order ($menu_order) {
    $cpts = [
        'edit.php?post_type=' . 'custom-post-type', 
        'edit.php?post_type=' . 'another-cpt',
        'my-ACF-slug'
    ];

    $first_item = array_shift( $menu_order );
    foreach( $cpts as $ctp ) {
        $idx = array_search( $ctp, $menu_order );
        if ( $idx === false ) { continue; }
        unset( $menu_order[$idx] );
        array_unshift( $menu_order, $ctp );
    }
    array_unshift( $menu_order, $first_item );
    return $menu_order; 
 }

Your Answer

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

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