Admin Bar API changes in 3.3

Howdy! The Admin Bar API has changed quite a bit in WordPress 3.3.

First up, what may break your plugin. The added items are no longer stored in a publicly accessible (but ideally privately used) menu property. So, if you were doing something like $wp_admin_bar->menu->..., you won’t get anything back.

The reason for this is that the internal structure has changed. Nodes are no longer internally stored in a tree. Now, they’re stored in a flat list, and the tree is bound together just before render. This makes the internal API much more stable, and allows us to provide plugin developers some nifty new tools. Even core only handles nodes using the same APIs developers use (mostly).

If you were to open the file you will notice there are a number of new methods and signatures. Here are the ones developers will want to know:

  • Add a node: add_node( $args ) or add_menu( $args ) (these are equivalent)
  • Remove a node: remove_node( $id ) or remove_menu( $id ) (these are equivalent)
  • Fetch a node’s properties: get_node( $id ).
  • Add a group, which wraps nodes (more on that in a bit): add_group( $args ).

Terminology notes

Before I continue: I’m using “item,” “node,” and “menu” synomyously throughout this post. They all are referring to a single link in the admin bar. Nodes can be parents for other nodes, which creates dropdown menus. The API previously emphasized add_menu(), but this can be confusing, so add_node() is now being promoted a bit more. Both methods do the same thing.

Since the optional admin bar has been merged into the admin header, we’re now calling it the toolbar in the UI.


An example of groups in the new toolbar.

Version 3.3 introduces the concept of groups. Groups share the same namespace (in terms of IDs) as nodes, and a node’s parent can be a group, rather than another node. Groups allow us to group nodes together into distinct sections of a menu. As an example, see the new W menu in the top left of the toolbar (screenshot at right). Here’s how it was constructed:
  • The W logo node is added. It has no parent.
  • The “About WordPress” node is added. To create a submenu, we set the parent to the W logo.
  • We add a group for external links. The group’s parent is also the W logo. It uses an additional CSS class to add the gray styling.
  • We then add the four external links, and set their parent to the external links group.

You can see these registrations in wp_admin_bar_wp_menu() and wp_admin_bar_add_secondary_groups().

Groups were added to provide us some styling flexibility and semantic divisions for a few different menus. (The right side of the top menu, “Howdy” and search, are their own group.) But the possibilities for plugins are pretty great. A plugin can bundle all of their nodes into a single group that then maintain visual separation from all other nodes in that menu. You can use the add_group() method to add groups.

Moving and modifying nodes

While this isn’t a change from WordPress 3.2, it’s worth pointing out that add_node() is able to take the ID of an existing node as an argument, and then replace the specified arguments. For example, if you want to make the Network Admin level a top-level item, try this:

add_action( 'admin_bar_menu', 'nacin_promote_network_admin_in_toolbar', 25 );
function nacin_promote_network_admin_in_toolbar( $wp_admin_bar ) {
    $wp_admin_bar->add_node( array(
        'id' => 'network-admin',
        'parent' => false,
    ) );

That was easy!

To make modifications easier, there’s now a get_node() to fetch a node’s properties, and even get_nodes() to fetch a flat list of all nodes, in case you want to loop through them.

#3-3, #dev-notes