Admin Toolbar Menu Generator
Add a node to the WordPress admin bar with submenu items, a capability check, and the choice of showing it on the front end, the admin, or both.
<?php
/**
* The "My Plugin" toolbar menu.
*/
/**
* Resolves a menu link.
*
* An absolute URL is used as written; anything else is treated as a path
* inside wp-admin, which is what a settings page link is.
*
* @param string $link URL or admin path.
* @return string
*/
function my_plugin_admin_bar_url( $link ) {
return preg_match( '#^https?://#', $link ) ? $link : admin_url( $link );
}
/**
* Adds the node and its submenu.
*
* @param WP_Admin_Bar $wp_admin_bar The toolbar.
*/
function my_plugin_admin_bar( $wp_admin_bar ) {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$wp_admin_bar->add_node(
array(
'id' => 'my_plugin_tools',
// The icon is markup, so the title is escaped before it goes in.
'title' => '<span class="ab-icon dashicons-admin-generic" aria-hidden="true"></span>'
. '<span class="ab-label">' . esc_html__( 'My Plugin', 'my-plugin' ) . '</span>',
// No href: the node opens its submenu instead of going anywhere.
'href' => false,
'meta' => array(
'title' => esc_attr__( 'My Plugin', 'my-plugin' ),
),
)
);
$wp_admin_bar->add_node(
array(
'id' => 'my_plugin_settings',
'parent' => 'my_plugin_tools',
'title' => esc_html__( 'Settings', 'my-plugin' ),
'href' => my_plugin_admin_bar_url( 'options-general.php?page=my-plugin' ),
)
);
$wp_admin_bar->add_node(
array(
'id' => 'my_plugin_docs',
'parent' => 'my_plugin_tools',
'title' => esc_html__( 'Documentation', 'my-plugin' ),
'href' => my_plugin_admin_bar_url( 'https://example.com/docs/' ),
)
);
}
add_action( 'admin_bar_menu', 'my_plugin_admin_bar', 100 );
Output is valid and updates as you type.
Fix the highlighted fields to update the output.
Add your own menu to the WordPress toolbar, with submenu items, a capability check and a choice of where it shows. The generator writes the node, the children and the link handling.
How to use
- Give the node a unique ID. Reusing a core ID such as
new-contentreplaces that menu instead of adding one. - Decide the parent. A plugin shortcut usually belongs under the site name menu rather than as another top level item competing for space.
- Leave the link empty for a node that only opens its submenu. WordPress renders it as a label rather than a dead link.
- Set the capability. The toolbar is visible to every logged-in user on the front end, so an unguarded node is visible to subscribers.
- Register on
admin_bar_menuat a late priority. Core builds its own nodes first, and yours has to come after the parent it attaches to.
Example
A node under the site name menu with one child:
function acme_admin_bar( $wp_admin_bar ) {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$wp_admin_bar->add_node(
array(
'id' => 'acme_tools',
'title' => esc_html__( 'Acme', 'acme' ),
'parent' => 'site-name',
'href' => acme_admin_bar_url( 'options-general.php?page=acme' ),
)
);
}
add_action( 'admin_bar_menu', 'acme_admin_bar', 100 );
The helper is there because a submenu link can be either an admin path or an external URL, and admin_url() mangles the second.
Pitfalls
- The toolbar renders on the front end too, for any logged-in user. A node with no capability check is visible to subscribers.
- Adding a child before its parent produces nothing. A late priority, 100 or more, avoids ordering problems with core and other plugins.
- Reusing a core node ID replaces that node.
site-name,my-account,new-contentandeditare all taken. - An icon has to be markup in the title, which means the title is no longer plain text: escape the label yourself before concatenating.
admin_url()on an absolute URL produces a broken link with the admin path glued onto the front.- A node with no
hrefand no children renders as an unclickable label, which looks broken. - The toolbar is hidden entirely for users who turned it off in their profile, and on screens where
show_admin_baris filtered off. - Adding many nodes pushes the right hand items off a narrow screen; the toolbar does not wrap.
Compatibility
admin_bar_menu and WP_Admin_Bar::add_node() have been stable since WordPress 3.3, when add_menu() was deprecated in favour of add_node(). The meta array supports target, rel, title, class and onclick. Dashicons are available in the admin and, since 3.8, on the front end whenever the toolbar shows. The generated code targets PHP 7.0 and up, and the tool runs entirely in your browser.
Frequently asked questions
Why does my submenu item not appear?
Where should a plugin’s node go?
Can I show it only in the admin?
is_admin() check. The generated code includes it when you choose admin only.How do I remove a core toolbar item?
$wp_admin_bar->remove_node( 'comments' ) on the same hook, at a later priority.