27

Does anyone know how to add an admin menu separator? I found this but it did not help.

Any ideas?

1
  • In case anyone's still searching for the answer to this, this plugin can handle the job.
    – user31760
    May 2, 2013 at 11:43

7 Answers 7

38

Here's a quick and dirty way to get what you want.

Background

WordPress stores admin menu sections in a global array called $menu. To add a separator you add an element to the $menu array using an index that is between the indexes of the options that you want to separate.

Using the add_admin_menu_separator() function

So I've written a function to encapsulate the logic for this I called add_admin_menu_separator(). You'll need to pick an array index number that is higher than the option after which you want to add a separator, and then call the function add_admin_menu_separator() passing said index as your parameter.

For example:

add_admin_menu_separator(37);

The add_admin_menu_separator() function itself

Here's the definition of the function add_admin_menu_separator() which you can copy into your theme's functions.php file. Yes it is arcane but then so is the code that creates and uses the global $menu array. (Plans are to eventually deprecate it, thankfully, but that'll probably be a few years.)

function add_admin_menu_separator($position) {
  global $menu;
  $index = 0;
  foreach($menu as $offset => $section) {
    if (substr($section[2],0,9)=='separator')
      $index++;
    if ($offset>=$position) {
      $menu[$position] = array('','read',"separator{$index}",'','wp-menu-separator');
      break;
    }
  }
  ksort( $menu );
}

Finding the index into $menu that you need

To figure out what index number you need you can do a var_dump() of $GLOBALS['menu'] from within an admin_init hook. Here's a bit of code you can drop into your theme's functions.php file temporarily to see what the values are. This will only work when requesting a URL starting with /wp-admin/ (but be sure to do with with FTP and not the built in theme editor or you'll loose access to your site, at least until you get FTP access to your theme's functions.php file!):

add_action('admin_init','dump_admin_menu');
function dump_admin_menu() {
  if (is_admin()) {
    header('Content-Type:text/plain');
    var_dump($GLOBALS['menu']);
    exit;
  }
}

See Also:

BTW, you might find these links useful in general for working with admin menus:

Although my admin menu classes don't currently offer an easy way to add separators I think I'll now add that when I have time.

8
  • Thanks Mike, I checked all night studying global var menu, but I didn't managed to add a separator,it is now much clearer to me how menus works in wp.
    – user1147
    Oct 7, 2010 at 16:53
  • Hi @user1147: Yes, they are very hard to figure out. When I first had to it took me quite a lot of time, and I still struggle with them. Hence why I wrote those functions, so I can do it the easy way from now on! Anyway, glad my answer helped. Oct 7, 2010 at 17:39
  • 1
    @MikeSchinkel This method isn't working for me with Wordpress 3.3.1.
    – Jim Geurts
    Jan 9, 2012 at 22:49
  • 1
    @JimGeurts - it's not working for me either :/ Apr 24, 2012 at 17:56
  • 2
    I just tested it and it does "work" in 4.5, but WordPress decided to get rid of the lines do they just do not appear anymore. I think the solution if to add CSS but for the life of me I cannot figure out what CSS to add since I am a backend dev and suck at CSS. Maybe someone else can suggest? Jun 23, 2016 at 1:23
4

It's easy as:

add_action( 'admin_init', 'add_sep' );
function add_sep() {

    if ( ! is_admin() )
        return false;

    global $menu;
    $sep = $menu[4]; // that's the default separator
    $pos = 6; // change it for the desired position
    $menu = array_merge(
        array_slice( $menu, 0, $pos ),
        array( $sep ),
        array_slice( $menu, $pos + 1, -1)
    );
    $menu[ $pos - 1 ][4] .= ' menu-top-last';
    $menu[ $pos + 1 ][4] .= ' menu-top-first';

}

Note: The default separator position ($menu[4]) can be different depending of which configuration you (or your plugins) have done before this hook.

Of course, you can also tweak the menu-top-first and menu-top-last classes introspection.

3

Had some issues with separators not being added, it was due to the way wordpress removes duplicate separators. Adding ksort($menu); to the bottom of the function corrected the issue.

2

You can simply add this in functions.php

add_action('admin_menu', function () {   
  global $menu;
  $menu[49] = ['', 'read', '', '', 'wp-menu-separator'];
});

Where 49 is separator position, You have to remember that separator position can replace your menu element if it has the same position.

1

This builds on MastaBaba's answer, but does not replace anything at the position you specify - it just adds the separator afterwards.

Also uses an anonymous function so it's only compatible with PHP version 5.3 and above.

add_action( 'admin_menu', function () {
    $position = 29;
    global $menu;
    $separator = [
        0 => '',
        1 => 'read',
        2 => 'separator' . $position,
        3 => '',
        4 => 'wp-menu-separator'
    ];
    if (isset($menu[$position])) {
        $menu = array_splice($menu, $position, 0, $separator);
    } else {
        $menu[$position] = $separator;
    }
});
0

It's a little hard to determine what you're trying to do, but I think you're looking to add a top-level entry in the WordPress admin menu.

See this documentation in the WordPress Codex.

In short, you're looking for usage of the add_menu_page() function, which takes a number of arguments and displays an additional item in the administrative menu as a sibling of "Dashboard", "Posts", "Media", etc.

Hope I got it right. :-)

2
  • I'm just trying to add an admin menu seprator. Before posting the question I tried to use add_menu_page().
    – user1147
    Oct 6, 2010 at 20:56
  • Looks like MikeSchinkel got you pretty well covered. Sorry about the misunderstanding. Good luck!
    – dgw
    Oct 7, 2010 at 20:41
0

The below ads an action to Wordpress that is run when the admin menu is rendered. The admin menu is an array and all you're doing, here, is adding an array element that defines a separator, in the position you specify.

From here:

add_action( 'admin_menu', 'set_admin_menu_separator' );
function set_admin_menu_separator() {
$position = 79;
global $menu;
$menu[$position] = array(
0   =>  '',
1   =>  'read',
2   =>  'separator' . $position,
3   =>  '',
4   =>  'wp-menu-separator'
);
}

Note that, though this rather resembles the currently accepted answer, the currently accepted answer did not work for me (and, judging from the comments, for several others).

2
  • There is no difference to the existing, accepted answer, except that you don't give any explanation. Please read How to Answer.
    – fuxia
    Jun 19, 2016 at 15:19
  • @toscho: Well, this works for me and the accepted answer does not.
    – MastaBaba
    Jun 19, 2016 at 17:22

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.