17

I just figured out the menu_position parameter it seems like you can place the menu of your custom post type almost everywhere. Except above the Posts menu!

How can I accomplish that?

| improve this question | | | | |
  • Good question, it seems that is the one place it won't go. – jnthnclrk Aug 29 '13 at 12:44

10 Answers 10

15

Positions for Core Menu Items

  • 2 Dashboard
  • 4 Separator
  • 5 Posts
  • 10 Media
  • 15 Links
  • 20 Pages
  • 25 Comments
  • 59 Separator
  • 60 Appearance
  • 65 Plugins
  • 70 Users
  • 75 Tools
  • 80 Settings
  • 99 Separator

Parameter description for "menu position"

$position (integer) (optional) The position in the menu order this menu should appear. By default, if this parameter is omitted, the menu will appear at the bottom of the menu structure. The higher the number, the lower its position in the menu.

WARNING: if two menu items use the same position attribute, one of the items may be overwritten so that only one item displays! Risk of conflict can be reduced by using decimal instead of integer values, e.g. 63.3 instead of 63.

Default: bottom of menu structure

| improve this answer | | | | |
  • How to use decimal In 'menu_position' =>3,? I wanna use position=3 for many custom post types. – Bikram Feb 4 at 9:19
4

The new JetPack Plugin places its menu link immediately below the Dashboard link. It does so by setting its menu order to 0, by filtering the $menu_order array:

function jetpack_menu_order( $menu_order ) {
        $jp_menu_order = array();

        foreach ( $menu_order as $index => $item ) {
            if ( $item != 'jetpack' )
                $jp_menu_order[] = $item;

            if ( $index == 0 )
                $jp_menu_order[] = 'jetpack';
        }

        return $jp_menu_order;
    }

Out of curiosity, what would happen if you tried 0 as menu_position?

| improve this answer | | | | |
3

Looking for a solution on the web but didn't found. Simply does this trick (for example). Here you have the native list of positions:

  • 2 Dashboard
  • 4 Separator
  • 5 Posts
  • 10 Media
  • 15 Links
  • 20 Pages
  • 25 Comments
  • 59 Separator
  • 60 Appearance
  • 65 Plugins
  • 70 Users
  • 75 Tools
  • 80 Settings
  • 99 Separator

If you have more items, you can read the current position for each items by printing the global $menu :

global $menu; 
print_r($menu); 

So if I well understand, nothing can prevent us too re-order the menu like we want :

function re_order_menu () {
    // ------- Put away items 
    $dashboard = $menu[2]
    $separator1 = $menu[4]
    $posts = $menu[5]
    $media = $menu[10]
    $links = $menu[15]
    $pages = $menu[20]
    $comments = $menu[25]
    $separator2 = $menu[59]
    $appearance = $menu[60]
    $plugins = $menu[65]
    $users = $menu[70]
    $tools = $menu[75]
    $settings = $menu[80]
    $separator3 = $menu[99]

    // -------- Reset menu  
    unset($menu[2]);
    unset($menu[4]);
    unset($menu[5]);
    unset($menu[10]);
    unset($menu[15]);
    unset($menu[20]);
    unset($menu[25]);
    unset($menu[59]);
    unset($menu[60]);
    unset($menu[65]);
    unset($menu[70]);
    unset($menu[75]);
    unset($menu[80]);
    unset($menu[99]);

    // -------- Re-order menu as you want
    $dashboard = $menu[2];
    $separator1 = $menu[4]
    $posts = $menu[5];
    $books = $menu[6];
    /* my tons of custom items */
    $authors  = $menu[7];
    $requests = $menu[8];
    $clients = $menu[9];
    $sellers  = $menu[10];
    $services = $menu[11];
    $schedules = $menu[12];
    /* let some space after */ 
    $media = $menu[30];
    $links = $menu[31];
    $pages = $menu[32];
    $comments = $menu[33];
    $separator2 = $menu[59];
    $appearance = $menu[60];
    $plugins = $menu[65];
    $users = $menu[70];
    $tools = $menu[75];
    $settings = $menu[80]
    $separator3 = $menu[99];

} 
add_action('admin_menu', 're_order_menu');

It works fine for me so, I think this is legit, I'm wrong ?

| improve this answer | | | | |
  • Very fragile solution which relies on magic numbers. It would break as soon as some other plugin is added/removed that places an item amongst the others. – Walf Nov 12 '19 at 23:19
2

I've used 'menu_postion' => 0, 1,2,3,4.

Doesn't matter really. If you play around with it you can easily figure it out.

Using 'menu_position' => 1 should place it below the Dashboard menu item above the separator thing. 0 Should place it above the Dashboard

| improve this answer | | | | |
2

This is a bug in WordPress. Please see this thread in Trac: http://core.trac.wordpress.org/ticket/14755

Fixed in 4.4...

https://developer.wordpress.org/reference/functions/add_menu_page/#notes

| improve this answer | | | | |
1

You can use this:

function my_move_post () {
    global $menu;
    $menu[6] = $menu[5]; //move post from post 5 to 6
    unset($menu[5]); //free the position 5 so you can use it!
}
add_action('admin_menu', 'my_move_post');

Now you can use position 5 to add you menu above Post menu.

| improve this answer | | | | |
  • This did not work for me. I placed it within my sitewide plugin where my custom-post-type.php file is – Daniel Aug 14 '14 at 16:19
1

here is the caveat to the whole issue...

WordPress 4.9.2

wp-admin/menu.php:

// If we're to use $_wp_last_object_menu, increment it first.
$ptype_menu_position = is_int( $ptype_obj->menu_position ) ? $ptype_obj->menu_position : ++$_wp_last_object_menu; 

NOTICE: must be an integer and NOT set already, otherwise it goes to the bottom of the list.

| improve this answer | | | | |
1

For a working solution in WordPress 5 and below, reposition it with the following code:

add_filter('custom_menu_order', '__return_true');
add_filter('menu_order', function($menu_order) {
    if (
        false !== ($k1 = array_search($v1 = 'edit.php', $menu_order))
        && false !== ($k2 = array_search($v2 = 'edit.php?post_type=foo', $menu_order))
    ) {
        array_splice($menu_order, $k1, 0, $v2);
        array_splice($menu_order, $k2 + 1, 1);
    }
    return $menu_order;
});

This assumes you don't have more than one menu item vying for pole position.

| improve this answer | | | | |
0

On the same link you linked, it reads:

menu_position
(integer) (optional) The position in the menu order the post type should appear.
Default: null - defaults to below Comments
5 - below Posts
10 - below Media
20 - below Pages
60 - below first separator
100 - below second separator

So, if you set menu_position to something like 4, then it should put it above posts.

A position of -1 puts it above the Dashboard link.

| improve this answer | | | | |
  • I tried 4 but it exactly the same as 5. – janoChen Feb 7 '11 at 19:23
  • Hrm. Tried 1-3? I think perhaps "1" (or "0") is the Dashboard. Perhaps something 2-3 would work – Zack Feb 7 '11 at 20:32
  • 0 1 2 3 Goes before the Dashboard and 4 Goes below Posts. Is really impossible! – janoChen Feb 8 '11 at 5:44
  • Wow. broken much WordPress? I don't know then. :-/ – Zack Feb 8 '11 at 5:52
  • I think that 4 is the separator right above Posts, and 5 is Posts, so if you set your menu-position to 3 it will be right before the separator. With default configuration of course. Setting my plugin page to 4 overwrote the separator, but did appear just above Posts. hmmm... – goldenapples Mar 28 '11 at 19:50
0

You can use decimal values (as strings). For example, I have some custom post types that I placed at the last position in menu (100001, 100002, 100003).

Then, just put this code to move them above Posts and below Dashboard menu items.

function reorder_admin_menu() {

  global $menu;

  // Add one separator

  $menu["3.1"] = array(
    0 =>  '',
    1 =>  'read',
    2 =>  'separator_' . "anything_unique",
    3 =>  '',
    4 =>  'wp-menu-separator'
    );

  // I have put my menu items waay at the end (exactly these values), so move them up

  $menu["3.2"] = $menu[100001];
  $menu["3.3"] = $menu[100002];
  $menu["3.4"] = $menu[100003];

  unset($menu[100001]);
  unset($menu[100002]);
  unset($menu[100003]);

  // move Media menu (position 10) item to front, in the same group
  $menu["3.5"] = $menu[10];
  unset($menu[10]);

  // Debug: ksort($menu); error_log( var_export( $menu, true ) );
}

add_action( 'admin_menu', 'reorder_admin_menu', 999 );
| improve this answer | | | | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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