Skip to content

Toolbar: move greeting to inside user dropdown to free up horizontal space - #13681

Closed
fushar wants to merge 12 commits into
WordPress:trunkfrom
fushar:increase-top-right-admin-bar
Closed

fushar wants to merge 12 commits into
WordPress:trunkfrom
fushar:increase-top-right-admin-bar

Conversation

@fushar

@fushar fushar commented Sep 23, 2026 •

Copy link
Copy Markdown

Trac ticket: https://core.trac.wordpress.org/ticket/66157

Summary

As discussed in the ticket, the top-right side of the admin bar can be crowded with plugin nodes. This PR attempts to free up some horizontal space by relocating the "Howdy," greeting into the user dropdown.

Please check the linked Trac ticket above for more rationale behind this change.

Display name is username:

Before After
image image

Display name is different from username:

Before After
image image

Testing

  1. Log in and view any admin or front-end page.
  2. Verify that the top-right of the admin bar shows just the display name and avatar.
  3. Hover to open the user dropdown, and confirm it shows "Howdy, {name}" beside the large avatar.
  4. Try to test the different cases above (display name equals and does not equal the username).

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Opus 5.5
Used for: Code generation. Verified and tested by me.


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@fushar
fushar marked this pull request as ready for review September 23, 2026 14:36
@github-actions

github-actions Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props fushar, tyxla, mcsf, joen.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@fushar
fushar force-pushed the increase-top-right-admin-bar branch from b17ecc3 to b2dd37b Compare September 30, 2026 07:19
Comment thread src/js/_enqueues/admin/user-profile.js Outdated
select = $( '#display_name' ),
current_name = select.val(),
greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name' );
greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name' ).not( '.edit-profile' );

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems https://core.trac.wordpress.org/ticket/43633 broke live update. It added the same display-name class to the Edit Profile link, so if we update the display name (without saving), the dropdown will be live-updated but the Edit Profile text is also replaced with the new display name mistakenly.

I fixed that here because it's a small change.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK :not is faster than .not(), should we merge into a single selector? Like this (untested):

Suggested change
greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name' ).not( '.edit-profile' );
greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name:not( .edit-profile )' );

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's superseded by 6478eb8.

Comment thread src/js/_enqueues/admin/user-profile.js Outdated
select = $( '#display_name' ),
current_name = select.val(),
greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name' );
greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name' ).not( '.edit-profile' );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK :not is faster than .not(), should we merge into a single selector? Like this (untested):

Suggested change
greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name' ).not( '.edit-profile' );
greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name:not( .edit-profile )' );

'id' => 'my-account',
'parent' => 'top-secondary',
'title' => $howdy . $avatar,
'title' => '<span class="display-name">' . $display_name . '</span>' . $avatar,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We strip tags of $display_name below, but not here, any good reason for that inconsistency?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're right. I was just following the existing code, but the stripping was necessary because it contained Howdy, <span. Now that it's just the display name from DB, I think it's no longer necessary. Dropping: 6557e56.

Comment thread src/wp-includes/admin-bar.php Outdated
);

/* translators: %s: Current user's display name. */
$howdy = sprintf( __( 'Howdy, %s' ), "<span class='display-name'>{$current_user->display_name}</span>" );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid the string interpolation, it's deprecated in PHP 8.2:

Suggested change
$howdy = sprintf( __( 'Howdy, %s' ), "<span class='display-name'>{$current_user->display_name}</span>" );
$howdy = sprintf( __( 'Howdy, %s' ), '<span class="display-name">' . $current_user->display_name . '</span>' );

Note I've changed the quotes back to how they were, in case someone does direct string replacement to customize the Howdy string, so that continues to work the same way.

@fushar fushar Sep 30, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL about the deprecation. Thanks. Fixed in 02ea21e.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in case someone does direct string replacement to customize the Howdy string, so that continues to work the same way.

Hmm but then the other fix 6478eb8 could break this, what do you think 😂

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid the string interpolation, it's deprecated in PHP 8.2:

This was a TIL for me too, but after reading the documentation it seems that it's the " ${var} " that is deprecated, leaving both " $var " and " {$var} " intact, no?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in case someone does direct string replacement to customize the Howdy string, so that continues to work the same way.

Hmm but then the other fix 6478eb8 could break this, what do you think 😂

If we need to add a classname, we add it. But we could add a dev note to warn folks to update their extensions and integrations.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid the string interpolation, it's deprecated in PHP 8.2:

This was a TIL for me too, but after reading the documentation it seems that it's the " ${var} " that is deprecated, leaving both " $var " and " {$var} " intact, no?

I don't follow. There wasn't a good reason to keep interpolation here and that was my main motivation to suggest removng it; the 8.2 deprecation is just a side reason 😉

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I re-read, and I follow now 🙈 . But I still think there's no need for interpolation, so we're good here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, will add dev note later!

Comment thread src/wp-includes/admin-bar.php Outdated

$user_info = get_avatar( $user_id, 64 );
$user_info .= "<span class='display-name'>{$current_user->display_name}</span>";
$user_info .= "<span class='howdy'>{$howdy}</span>";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the string interpolation here as well:

Suggested change
$user_info .= "<span class='howdy'>{$howdy}</span>";
$user_info .= '<span class="howdy">' . $howdy . '</span>';

@fushar fushar Sep 30, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same fix: 02ea21e

Comment thread src/wp-includes/admin-bar.php Outdated

$user_info = get_avatar( $user_id, 64 );
$user_info .= "<span class='display-name'>{$current_user->display_name}</span>";
$user_info .= "<span class='howdy'>{$howdy}</span>";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the new .howdy class name absolutely necessary?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I don't see any better way. It's used to style the greeting text.

The alternatives:

  • Put it inside the <span class="display-name"> but then the JS that does the live-update would need to recreate the greeting and its translation in JS code.
  • Don't add any wrapper span, but then the raw string makes the line height taller than trunk's (trunk's is fully contained in a span).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Sounds good, thanks for confirming

Comment thread src/wp-includes/admin-bar.php Outdated
);

/* translators: %s: Current user's display name. */
$howdy = sprintf( __( 'Howdy, %s' ), "<span class='display-name'>{$current_user->display_name}</span>" );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW if someone does customization this way:

$node = $wp_admin_bar->get_node( 'my-account' );
$title = str_replace( 'Howdy,', 'Welcome,', $node->title );

it will no longer work. This may need a dev note.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Yep. Will add when it's time!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope no one is doing that, since that string is translated 🙈

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha yes, but that was just a simplified example FWIW. Obviously you can replace __( 'Howdy' ) with __( 'Hellooo' ).

'id' => 'my-account',
'parent' => 'top-secondary',
'title' => $howdy . $avatar,
'title' => '<span class="display-name">' . $display_name . '</span>' . $avatar,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the display name is empty, this link now has no text at all. Before, "Howdy, " was always there. Screen readers will get a menu item with no name, because the avatar has an empty alt. I wonder if we should consider adding a fallback, for example, the current user's username?

@fushar fushar Sep 30, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Added fallback: 3192622

'meta' => array(
'class' => empty( $avatar ) ? '' : 'with-avatar',
'menu_title' => wp_strip_all_tags( $howdy ),
'menu_title' => wp_strip_all_tags( $display_name ),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

menu_title is checked with empty() in WP_Admin_Bar::_render_item(). If the display name is '' or '0', the submenu is renderred without aria-label. Previously the "Howdy, " prefix helped keep the value non empty. The same fallback as in the comment above would fix this too.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same fallback: 3192622

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we handling '0' consistently though? Won't '0' lose the submenu label currently (check pre-existing code and how they handle '0').

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're right; I updated to use empty() so it's consistent with existing code:

if ( empty( $userdata['display_name'] ) ) {
if ( $update ) {
$display_name = $user_login;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're right; I updated to use empty() so it's consistent with existing code:

if ( empty( $userdata['display_name'] ) ) {
if ( $update ) {
$display_name = $user_login;

Comment thread src/js/_enqueues/admin/user-profile.js Outdated
select = $( '#display_name' ),
current_name = select.val(),
greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name' );
greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name' ).not( '.edit-profile' );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW .display-name is used for styling and also as the JS hook for the user's name. Any other element with this class will be overwritten too. A separate class for the two name spans could be a safer option

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried it: 6478eb8. But not sure if it makes it a bit confusing to read? (Well, the old :not(.edit-profile) is confusing, too 😅)


/**
* Replaces "Howdy, *" in the admin toolbar whenever the display name dropdown is updated for one's own profile.
* Updates the display name in the admin toolbar whenever the display name dropdown is updated for one's own profile.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we update the label too? This handler only updates the .display-name text. The aria-label of the submenu keeps the old name until the page is reloaded.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good idea. Check: d15c3e0

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still valid in a way? Won't we fall back to the saved display name instead of the login fallback that we do on the PHP side?

@fushar fushar Oct 5, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see... updated in the last commit so the logic matches between JS and PHP 😄 (but again, this is a very rare edge case)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see... updated in the last commit so the logic matches between JS and PHP 😄 (but again, this is a very rare edge case)

Comment thread src/wp-includes/admin-bar.php Outdated
);

/* translators: %s: Current user's display name. */
$howdy = sprintf( __( 'Howdy, %s' ), '<span class="display-name user-display-name">' . $current_user->display_name . '</span>' );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should apply the "no display name" fallback to username here too.

Comment thread src/js/_enqueues/admin/user-profile.js Outdated
greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name' );
select = $( '#display_name' ),
current_name = select.val(),
user_display_name = $( '#wp-admin-bar-my-account' ).find( '.user-display-name' ),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth double checking if there are plugins using the old classname and relying on it, particularly here.

Comment thread src/wp-includes/admin-bar.php Outdated
'meta' => array(
'class' => empty( $avatar ) ? '' : 'with-avatar',
'menu_title' => wp_strip_all_tags( $howdy ),
'menu_title' => $display_name,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

menu_title now uses the raw $display_name. Before, wp_strip_all_tags() removed tags and extra spaces. If a display name contains markup, the aria-label will now contain the tag characters as text, and screen readers will read them. I think we should rather keep it (in both places), unless we have a good reason to remove it.

Comment thread src/js/_enqueues/admin/user-profile.js Outdated

greeting.text( display_name );
user_display_name.text( display_name );
user_actions.attr( 'aria-label', display_name );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PHP adds the aria-label to every child group of my-account, but here we touch only #wp-admin-bar-user-actions. If a plugin adds another group (for example BuddyPress), that group keeps the old name. Maybe we should be updating all child groups of #wp-admin-bar-my-account.

Comment thread src/js/_enqueues/admin/user-profile.js Outdated
var display_name = this.value.trim() || current_name;

greeting.text( display_name );
user_display_name.text( display_name );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PHP shows the .username line only when display_name is different from user_login. The JS does not add or remove this line. If I select my login as the display name, the dropdown shows "Howdy, admin" and then "admin" again below it. Not a blocker, but it is more visible now that the greeting is in the dropdown.

color: variables.$menu-text;
}

#wpadminbar #wp-admin-bar-user-info a:hover .howdy,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new rule covers only a:hover. With a non-default color scheme, the greeting text does not change color on keyboard focus, but the other submenu items do. Sounds like we can add a focus rule too.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is fixed in the latest commit.

$display_name = $current_user->display_name;
if ( '' === $display_name ) {
$display_name = $current_user->user_login;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Is this fallback needed? I ask because I found it surprising that the preexisting code wouldn't consider it: was it possible to get a Howdy, rendered? I see this update-time code, so what would cause a display name to be empty (assuming we have a current user to begin with)? Someone messing with the pre_user_display_name filter?
  2. If it is needed, don't forget to add it to the values computed for the user-info node.

Comment thread src/wp-includes/admin-bar.php Outdated
Comment on lines +288 to +291
'menu_title' => wp_strip_all_tags( $howdy ),
'menu_title' => $display_name,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a strong opinion, but:

I understand that display_name is supposed to be sanitised, but the fact that it relies on a filter for it makes me uneasy. I wonder if it wouldn't be wise to keep wp_strip_all_tags() around the value.

@fushar
fushar force-pushed the increase-top-right-admin-bar branch from 2e82557 to da75e54 Compare October 1, 2026 03:12

@fushar fushar left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the detailed comments @tyxla @mcsf. I feel like we've been introducing and discussing more changes than necessary for the feature. I've trimmed the changes. Here's the summary.

About the display_name value:

  • It could be empty (though rare) e.g. with the pre_user_display_name filter.
  • So, I agree with adding fallback for display_name. Without that, the my-account node's text and menu_title will be empty, which would be an accessibility regression. (Previously, we at least still had Howdy, prefix).
    • I added the same fallback to the user-info node just for consistency.
  • I restored the wp_strip_all_tags() call.

About the changes around display name JS live update:

  • The bugs (incorrect JS updates to Edit Profile, aria-label, username) are already present on trunk and are not caused by this PR.
  • My agent actually already caught some of the issues raised in this PR. While they are technically correct, I think we were over-optimizing for scenarios that are unlikely to happen. I bet that 99% of users won't ever think to hover the my-account node in the middle of updating the display name. 😅
  • So, I don't think we should fix the issues in this PR. I also reverted the aria-label addition. Now I believe it's better for it to be a separate ticket. I just opened one here: https://core.trac.wordpress.org/ticket/66222.

Now, the PR is fully focused only on moving the Howdy,. What do you think?

color: variables.$menu-text;
}

#wpadminbar #wp-admin-bar-user-info a:hover .howdy,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is fixed in the latest commit.


$user_info = get_avatar( $user_id, 64 );
$user_info .= "<span class='display-name'>{$current_user->display_name}</span>";
$user_info .= '<span class="howdy">' . $howdy . '</span>';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a scan on https://veloria.dev/ and it seems like there are plugins that customize (practically hide) the "Howdy". That customization will stop working. Plugins that do this are:

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I did a quick test with the plugins:

  • "Howdy" removal feature will be a no-op for the admin bar, but the dropdown panel will still show Howdy.
  • "Howdy" text customization is a no-op for the admin bar and will fail to customize the Howdy in the dropdown panel, similarly.

It's worth being clear if we're going to handle this with just a dev note or we'll do a more proactive outreach to the plugin authors.

My gut feeling is that a dev note is enough, as this is not technically breaking user sites in a catastrophic way. @jasmussen, what do you think? Also, the fact that there are such plugins offering Howdy removal in the first place, kind of supports this PR 😄

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens to PRs that try to remove the howdy? If we've found two, can we look at the code and see HOW they handle it? Does that text get removed entirely or does the plugin just stop working? If it's bad, we can just drop them an email, or a note in the forum of the plugin page.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you meant plugins instead of PRs; I've tested both of them. They were no-op (nothing happens) as I noted above.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the user-info markup also changes (new .howdy wrapper, double quotes instead of single quotes). Plugins that replace <span class='display-name'> will stop working. Also, plugins that hide "Howdy" will now show it again in the dropdown.

Let's mention both in the dev note. Also ideally we reach out to the plugin authors so they can adjust the plugin logic accordingly.

'meta' => array(
'class' => empty( $avatar ) ? '' : 'with-avatar',
'menu_title' => wp_strip_all_tags( $howdy ),
'menu_title' => wp_strip_all_tags( $display_name ),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we handling '0' consistently though? Won't '0' lose the submenu label currently (check pre-existing code and how they handle '0').

height: auto;
font-size: 16px;
line-height: 1.5;
color: #f0f0f1;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have we tested the howdy contrast with light color schemes?

@fushar fushar Oct 5, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm each scheme will provide their own color for .display-name. This PR changes nothing about that. And the new .howdy wrapper will just reuse that color. Not sure what's special about Light?

Here's how it looks on Light:

Image


/**
* Replaces "Howdy, *" in the admin toolbar whenever the display name dropdown is updated for one's own profile.
* Updates the display name in the admin toolbar whenever the display name dropdown is updated for one's own profile.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still valid in a way? Won't we fall back to the saved display name instead of the login fallback that we do on the PHP side?

@fushar

fushar commented Oct 5, 2026

Copy link
Copy Markdown
Author

(Sorry if you received duplicated comments; I think GitHub is buggy, somehow it won't show my latest comments here? 🤔)

@tyxla tyxla left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to add a few tests, for example: an empty display_name falls back to the login, the my-account title has no "Howdy", menu_title is correct, and the .username line is hidden when we use the fallback

greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name' );
select = $( '#display_name' ),
username = $( '#user_login' ).val(),
greeting = $( '#wp-admin-bar-my-account' ).find( '.display-name' );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This selector also matches the "Edit Profile" span (class="display-name edit-profile"). When I change the display name, the "Edit Profile" label changes to the new name too. This was fixed earlier, but it looks like it was reverted? Maybe .find( '.display-name:not(.edit-profile)' ) could do the job?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you perhaps miss this comment about reverting the changes? #13681 (review)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, but I'm assessing this with a fresh take. Are you saying this behavior makes sense?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the behavior does not make sense. I'm saying that this PR does not introduce that behavior, and that should be fixed separately.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it @fushar. I'd suggest opening a ticket/issue so it doesn't block this PR further. Thank you!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I already opened a ticket as mentioned in the same comment #13681 (review) 😄

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, sorry for the back and forth!

}

var display_name = this.value.trim() || current_name;
var display_name = this.value.trim() || username;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: in JS, '0' is a valid value here, but in PHP empty( '0' ) is true, so we fall back to the login. If I select 0, the toolbar shows "Howdy, 0", but after saving it shows the login. Maybe check for '0' too, so JS and PHP match? Bit of an edge case and mostly an artifact of the language differences, but something to potentially handle consistently.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I need to object to this:

  • This is what I said in Toolbar: move greeting to inside user dropdown to free up horizontal space #13681 (review) about over-optimizing for edge cases.
  • In practice we can't save first / last / nick name with 0 in profile.php. The server will reject it. It can only come through the pre_user_display_name filter. I can't imagine why anyone wants to filter the display name to literal 0.
  • I feel that adding '0' check in JS will just add confusion rather than clarity in the logic.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me 👍 Wanted to go through it and to have it "in paper".

var display_name = this.value.trim() || current_name;
var display_name = this.value.trim() || username;

greeting.text( display_name );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things here:

  1. The aria-label update was added but then removed. Now the menu aria-label keeps the old name until reload. Was this on purpose?
  2. We didn't update .username. PHP shows it only when the display name is different from the login, but JS never adds or removes it. If we select the login as display name, we see the login twice in the dropdown.

/**
* Adds the "My Account" item.
*
* @since 3.3.0

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the output of this function changes (no "Howdy" in the title, fallback to login), can we add a @since changelog line? Same for wp_admin_bar_my_account_menu().

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in the latest commits!


$user_info = get_avatar( $user_id, 64 );
$user_info .= "<span class='display-name'>{$current_user->display_name}</span>";
$user_info .= '<span class="howdy">' . $howdy . '</span>';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the user-info markup also changes (new .howdy wrapper, double quotes instead of single quotes). Plugins that replace <span class='display-name'> will stop working. Also, plugins that hide "Howdy" will now show it again in the dropdown.

Let's mention both in the dev note. Also ideally we reach out to the plugin authors so they can adjust the plugin logic accordingly.

margin: 0;
}

#wpadminbar #wp-admin-bar-user-info .howdy,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On mobile, this line is 16px with white-space: nowrap. With "Howdy, " in front of the name, long names or long translations (e.g. Russian "Здравствуйте, ") can go outside the screen on small viewports. Not sure what's the ideal outcome here FWIW. Perhaps the pre-existing behavior wasn't ideal either.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm you're right.... I think it's better to just properly add wrapping instead, so it would fix long names even without Howdy (done in the latest commits):

image

@fushar fushar left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to add a few tests, for example

Done in the latest commits!

margin: 0;
}

#wpadminbar #wp-admin-bar-user-info .howdy,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm you're right.... I think it's better to just properly add wrapping instead, so it would fix long names even without Howdy (done in the latest commits):

image

/**
* Adds the "My Account" item.
*
* @since 3.3.0

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in the latest commits!

@tyxla tyxla left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking good from my perspective. I've added a few more nits, but it's minor stuff.

@mcsf curious if you have any other feedback before we move forward with this one.

}

#wpadminbar #wp-admin-bar-user-info .howdy {
white-space: normal;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will properly wrap at spaces, but a long name with no spaces still can't break. For example, on a screen under 600px with a name like jonathan.alexander.smith@example-company.com, the name will still overflow. This can also happen with the new user_login fallback.

Haven't tested, but I wonder if a overflow-wrap: anywhere will help?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, added that. Now it breaks at non-spaces as well

Image

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. Hopefully this is a rare edge case!

padding-top: 4px;
}

#wpadminbar #wp-admin-bar-user-info .username {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noting that the username might also benefit from the whitespace / overflow-wrap treatment. Not a blocker for this PR

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The line-height: 0.8 !important; below it makes it a bit complicated; I'd rather not do it in this PR since it does not touch the username line.

Comment on lines +333 to +335
if ( empty( $display_name ) ) {
$display_name = $current_user->user_login;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic is also above, should we move it to a small helper and reuse?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if it's worth it; the helper will need all the docblock ceremony and such. Also, both fallbacks are already covered in the new tests, so we should be fine.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a big deal in any case

$display_name = $current_user->user_login;
}

/* translators: %s: Current user's display name. */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

%s can practically also be the username, so maybe let's change this:

Suggested change
/* translators: %s: Current user's display name. */
/* translators: %s: Current user's display name, or username if empty. */

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree. This doesn't make any difference for translation. The surrounding code already uses "display name" (the span classname, the variable name). Adding that comment would just be confusing rather than helping.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No strong feelings either way, but I'd be curious to understand the pushback here. This isn't at all about the surrounding code - as a matter of fact, the translator comments are necessary specifically so translators don't have to dig into the code. It's a practical fact that this string may contain the user display name OR the username, so in any case, it's a more precise version of the original translator comment. How can you know that it doesn't make a difference in any language? In any case, feel free to leave it as-is, but I'd love to understand why you see it as confusing.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but I'd love to understand why you see it as confusing.

Ah, I was looking at this from the point of view of translators that might notice the change in translation notes. I could be wrong though, but will updating translator notes generate a new translation request?

In my opinion, this PR doesn't expect translators to update the existing translation, even though the behavior slightly changed. The semantic of this PR is to just "move the greeting prefix inside".

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, changing a translator comment won't generate a new translation request. This will only happen if this was a _x() and we changed the context string, or if we changed the string itself. The translation key does not change if we change the translator comment, so the existing translations will remain. Which also makes sense in this case IMO.

@tyxla

tyxla commented Oct 6, 2026

Copy link
Copy Markdown
Member

No further feedback from my end. Thank you for your perseverance, @fushar and for going above and beyond to keep the change contained!

Would appreciate another 👁️ from @mcsf before we 🚢 it.

@mcsf

mcsf commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

I missed this ping last week. LGTM!

(Also, I recommend marking GitHub review threads as Resolved so that it's easier for reviewers to catch up.)

@github-actions

Copy link
Copy Markdown

A commit was made that fixes the Trac ticket referenced in the description of this pull request.

SVN changeset: 64312
GitHub commit: e8a9e23

This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants