WordPress.org

Make WordPress Core

Opened 2 years ago

Last modified 2 years ago

#19380 new defect (bug)

There is no way to specify placement of a new menu item in the Admin Bar

Reported by: willshouse Owned by:
Milestone: Future Release Priority: normal
Severity: minor Version: 3.3
Component: Toolbar Keywords:
Focuses: Cc:

Description (last modified by scribu)

I recently opened ticket #19371 and scribu has added a fantastic and simple solution to be able to modify existing menu items. The only problem, however, is that it is impossible to control placement of a new menu item.

For example, if I wanted to add a class on the "wp-logo" menu item, I would use the method specified in #19371 to remove it, modify it, and add it back.

add_action( 'admin_bar_menu', function( $admin_bar ) {
	$node = $admin_bar->remove_menu( 'wp-logo' );

	$node['meta']['class'] = 'foo';

	$admin_bar->add_menu( $node );
}, 99 );

The only problem is that it would put the menu item at the far right of the other menu items. I could then remove and re-add all the other menu items. However I don't think there is a way to get a list of all the top level menu items from within the admin bar class, so you would have to know the ID of each one from a print_r debug of the object and hard code the items in. This would break if a plugin added a menu item that wasn't in the hard coded list.

My thoughts would be either add a parameter to the add_menu() function such as priority, which could be boolean and cause the item to be added with array_unshift() instead of the current method, or a parameter that would be be for the id to "add before menu item x" , or just a method that would return a list of ids of the root menu items.

ps: I don't really need to add a CSS class to the wp-logo menu item, but this is the far-left-most item and I thought it would make the best example.

Change History (7)

comment:1 willshouse2 years ago

  • Summary changed from There is no way to specify placement of a new menu item in the Wordpress Admin Bar to There is no way to specify placement of a new menu item in the Admin Bar

comment:2 linuxologos2 years ago

If that's what you're talking about, WP_Admin_Bar::add_menus does use priorities for default menu items. Someone could use
add_action( 'admin_bar_menu', 'my_menu_item', 1111 )
to get his item appear where he wants.

http://core.trac.wordpress.org/browser/trunk/wp-includes/class-wp-admin-bar.php#L295

comment:3 scribu2 years ago

  • Description modified (diff)

comment:4 koopersmith2 years ago

  • Milestone changed from Awaiting Review to Future Release

I've gone back and forth on whether or not priorities would be a useful addition to the admin bar API. As it stands, priorities are currently too significant of a change to add to 3.3.

linuxologos is correct in ticket:19380:comment:2. For 3.3, developers should use priorities on the admin_bar_menu action to sort the admin bar items.

comment:5 follow-up: willshouse2 years ago

I agree, it does make sense to add priorities in a future release and not do it last minute on 3.3, especially if there is a workaround with the hooks as you mentioned.

But can someone give an example of how to use the actions? I tried in 3.2 and 3.3beta4 and was not successful. I tried the code on this page http://wordpress.stackexchange.com/questions/12502/ and also a modified version I created (included below). I can't seem to use these actions to remove the items or reorder them. What am I doing wrong here? Didn't see any WP documentation on this...

function admin_bar_test() {

 remove_action( 'admin_bar_menu', 'wp_admin_bar_my_account_menu', 10 );
 remove_action( 'admin_bar_menu', 'wp_admin_bar_my_sites_menu', 20 );
 remove_action( 'admin_bar_menu', 'wp_admin_bar_dashboard_view_site_menu', 25 );
 
 
 remove_action( 'admin_bar_menu', 'wp_admin_bar_edit_menu', 30 );
 
 remove_action( 'admin_bar_menu', 'wp_admin_bar_shortlink_menu', 80 );
 remove_action( 'admin_bar_menu', 'wp_admin_bar_updates_menu', 70 );
 
 remove_action( 'admin_bar_menu', 'wp_admin_bar_comments_menu', 50 );
 remove_action( 'admin_bar_menu', 'wp_admin_bar_appearance_menu', 60 );
 
 remove_action( 'admin_bar_menu', 'wp_admin_bar_updates_menu', 70 );
}

add_action( 'wp_before_admin_bar_render', 'admin_bar_test', 2 );

comment:6 in reply to: ↑ 5 koopersmith2 years ago

Replying to willshouse:

I can't seem to use these actions to remove the items or reorder them. What am I doing wrong here?

add_action( 'wp_before_admin_bar_render', 'admin_bar_test', 2 );

Your code calls remove action after the admin_bar_menus action has fired. You can fix your code by attaching your callback to the init action, or at the latest, an early priority on admin_bar_menus.


In the wp_admin_bar_render method, the wp_before_admin_bar_render action is called after the admin_bar_menus action. Check out the code here:

http://core.trac.wordpress.org/browser/trunk/wp-includes/admin-bar.php?rev=19464#L41

comment:7 willshouse2 years ago

Thought I had already tried the init hook but I didn't think it worked at the time. It's working OK now so I'm happier.

I would still like to have more control over the priorities of menu items or possibly just a function to get a list of all the root menu items in order. This would be a useful way to deal with menu items added by other plugins, as I noticed the code above left a few things in the admin bar after I got it working properly (due to another plugin).

Would it be possible to add a function to just return an array of root menu items in order to the 3.3 release?

Last edited 2 years ago by willshouse (previous) (diff)
Note: See TracTickets for help on using tickets.