Is it easily possible to edit links in the WP_Admin_Bar global $wp_admin_bar instance?


Yes I recently ran into the situation where I wanted to change the profile link in the user-info section of the admin bar. The problem is that you can only get all nodes, add and remove them. Not edit. And you also cannot modify the $wp_admin_bar->nodes property due it is private.

When easily removing and adding them, you'll lose your order and the whole thing looks horrible. Now here is my solution:

// void jw_edit_admin_bar ( mixed $id , string $property , string $value )

if(!function_exists('jw_edit_admin_bar')) {
    function jw_edit_admin_bar($id, $property, $value) {
        global $wp_admin_bar;

        if(!is_array($id)) {
            $id = array($id);

        $all_nodes = $wp_admin_bar->get_nodes();

        foreach($all_nodes as $key => $val) {
            $current_node = $all_nodes[$key];

            if(in_array($key, $id)) {
                $current_node->$property = $value;


add_action('admin_bar_menu', function() { jw_edit_admin_bar(array('user-info', 'my-account'), 'href', 'http://www.nyan.cat'); });
| improve this answer | |

Ok, so I recently ran into an issue trying to create a custom Holiday/Time of Day Greeting for the Wordpress Admin Toolbar and ran across this answer, which led me down a path of hours of wasted time since it is actually completely unnecessary. You don't need to destroy and rebuild the admin toolbar to edit a node.

The simple solution for Julien's issue is a 5 line addition to your functions.php file that replaces the desired url:

/* change location of user profile page in admin toolbar */
add_filter( 'edit_profile_url', 'update_admin_bar_user_profile_url', 10, 3 );
function update_admin_bar_user_profile_url( $url, $user_id, $scheme ) {
    $url = site_url( '/edit-user-profile/' );
    return $url;

Now if you want to get a bit deeper into editing/manipulating the the Admin Toolbar - you can do something like this, which adds the website url of the user, if they entered one in their profile page, as a node to the Users Profile Panel (aka a link in the "sub-menu"):

    /* --- add the user website link node in the admin toolbar --- */
add_action( 'admin_bar_menu', 'update_admin_bar_user_node', 250 );
function update_admin_bar_user_node( $wp_admin_bar ) {
    $user_id = get_current_user_id();
    $current_user = wp_get_current_user();
    $profile_url = get_edit_profile_url( $user_id );

    if ( ! $user_id )

    if ( current_user_can( 'read' ) ) {
        $profile_url = get_edit_profile_url( $user_id );
    } elseif ( is_multisite() ) {
        $profile_url = get_dashboard_url( $user_id, 'profile.php' );
    } else {
        $profile_url = false;

    // Add the users website/link to the user-actions sub-menu if they have one 
    $my_account = $wp_admin_bar->get_node( 'my-account' );
    if( ! empty( $current_user->user_url ) && $my_account ){
        $wp_admin_bar->add_node( array(
            'parent'    => 'user-actions',
            'id'        => 'user-url',
            'title'     => '<span class="user-url">' . __( 'My Website' ) . '</span>',
            'href'      => esc_url( $current_user->user_url )
        ) );

Here is a screenshot of how that change looks in the "my-account" "user-actions" menu: enter image description here

| improve this answer | |
  • That looks interesting. Do you know if this hook was added after I originally posted? WP dev often feels like a rabbit hole IMHO. They have thought of almost everything and it's hard from time to time to find the best approach. Also I often feel like there must be a hook or filter (this thread is a good example) and it takes forever to find, if you're lucky at all ;) – Julian F. Weinert Jul 11 '17 at 12:30
  • I agree, it is extremely difficult at times to find what you are looking for in their resources. That said, I think when I started I searched for wp_admin_bar and found some references. Something else that I wanted to post here was a complete list of default nodes and their priorities (positions) within the toolbar. If you notice, the priority I set for this change was 250 - which was based on that list. – Obewan Jul 12 '17 at 16:51
  • Sorry, I hate how Stack controls its posting, I frequently have to edit to make things look legible - especially for new folks like myself. – Obewan Jul 12 '17 at 17:04
  • I omitted the part of the code that dealt with replacing "Howdy" with the Time of Day Greeting because I thought it might be viewed as being beyond the scope of the question, but that hooks into the node "my-account" and can be replaced by a sprintf assignment using the following node method/array... ' $wp_admin_bar->add_node( array( 'id' => 'my-account', 'parent' => 'top-secondary', 'title' => $newtitle . $avatar, 'href' => $profile_url, 'meta' => array( 'class' => $class, ), ) ); ' – Obewan Jul 12 '17 at 17:05
  • The variables used in that method call are: $avatar = get_avatar( $user_id, 26); $greeting = tod_greeting_text(); $newtitle = sprintf( __( '%1$s, %2$s' ), $greeting, '<span class="display-name">' . $current_user->display_name . '</span>' ); $class = empty( $avatar ) ? '' : 'with-avatar'; ...of course tod_greeting_text() is a function call to a routine to parse and return the greeting message text string. – Obewan Jul 12 '17 at 17:09

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.