Make WordPress Core

Opened 8 weeks ago

Last modified 5 days ago

#65937 accepted defect (bug)

Emails have an empty '[]' or hanging sentences where site title is supposed to be, when site title is empty,

Reported by: r1k0 Owned by: audrasjb
Priority: normal Milestone: 7.2
Component: Mail Version:
Severity: normal Keywords: has-patch changes-requested reporter-feedback needs-unit-tests close
Cc: Focuses: administration

Description (last modified by r1k0)

Bug Report

Description

Since this issue affects multiple emails, you can try checking any email, i.e, "Password Reset", "New User Registration" "Delete My Site" etc. I will be using the "Joining Confirmation" email in a Multisite.
The site title in the email body sent to an existing user is empty, instead of falling back to the hostname as expected.

Environment

  • WordPress: 7.2-alpha-63166-src
  • Subdirectory: Yes
  • PHP: 8.3.33
  • Server: nginx/1.31.3
  • Database: mysqli (Server: 9.7.2 / Client: mysqlnd 8.3.33)
  • Browser: Chrome 151.0.0.0
  • OS: Windows 10/11
  • Theme: Twenty Twenty-Five 1.5
  • MU Plugins: None activated
  • Plugins:
    • PHPMailer 1.0.0
    • Test Reports 1.3.1

Steps to Reproduce

  1. Ensure you can capture emails; use this guide to set this up. ​https://make.wordpress.org/test/handbook/get-setup-for-testing/email-testing/
  2. On the network level, add a new user.
  3. Head over to the dashboard of any of the sites in your network.
  4. On the dashboard, go to Settings > General .
  5. Clear the Site Title field, then save changes.
  6. Now go to Users > Add User
  7. Add the existing user added in step 1. (Do not check the "Skip Confirmation Email" checkbox)
  8. Check the "Joining Confirmation" email; in the body, you will notice an empty pair of single quotes.
  9. 🐞 Bug occurs.

Expected Results

  1. ✅ The pair of quotes should contain the hostname of the site in the case of an empty site title.

Actual Results

  1. ❌ An empty pair of single quotes appears where the site title should be.

Additional Notes

  • None

Screenshot

https://i.ibb.co/S4CzyBnZ/Screenshot-2026-08-22-071625.png

Change History (19)

This ticket was mentioned in ​PR #13230 on ​WordPress/wordpress-develop by ​@r1k0.


8 weeks ago
#1

  • Keywords has-patch added

Ensures the mail body gets the site_title variable, which in turn falls back to hostname in the case of an empty site title in options-general.php.

Trac ticket: #65937

## Use of AI Tools
None

​@r1k0 commented on ​PR #13230:


8 weeks ago
#2

Before:
https://github.com/user-attachments/assets/5617852a-848e-478d-90a2-ee23664a858a

After:
https://github.com/user-attachments/assets/3dee3b99-fc19-4b4f-937f-9d98f8d1015c

#3 follow-up: @sabernhardt
8 weeks ago

  • Version trunk

#54760 replaced empty site titles in the subject of multiple emails. Would any of the other emails need a similar change in the body?

#4 @audrasjb
8 weeks ago

  • Milestone Awaiting Review → 7.2
  • Owner set to audrasjb
  • Status new → accepted

#5 in reply to: ↑ 3 @r1k0
8 weeks ago

Replying to sabernhardt:

#54760 replaced empty site titles in the subject of multiple emails. Would any of the other emails need a similar change in the body?

Upon further investigation, yes, multiple emails' subjects and bodies will need the fixes applied by #54760. In my initial PR, I only wanted to fix a small part that #54760 missed, but now I see the issue is also present in other emails.

I will update the PR to cover the other emails.

Other emails:
New User Registration & Login Detail
https://i.ibb.co/kVKQTyLg/Screenshot-2026-08-24-025717.png

Password Reset
https://i.ibb.co/Lz8FmXzZ/Screenshot-2026-08-24-030007.png

#6 @r1k0
7 weeks ago

  • Description modified (diff)
  • Summary Multisite: While site title is empty, site title doesn't fallback to the site hostname in the emails sent to an existing user → Emails have an empty '[]' or hanging sentences where site title is supposed to be, when site title is empty,

#7 @r1k0
7 weeks ago

  • Description modified (diff)

#8 @r1k0
7 weeks ago

  • Focuses administration added; multisite removed

Related: #54760

#9 @SirLouen
10 days ago

  • Keywords changes-requested needs-testing added

Hey @r1k0 I proposed you ​a couple fixes ideas.

Moreover, ideally, I would add a couple of unit tests, specially if you consider extracting the function (just for the function, if you would not like to extend the patch too much)

Last edited 10 days ago by SirLouen (previous) (diff)

#10 @SirLouen
10 days ago

  • Keywords needs-unit-tests added; needs-testing removed

This ticket was mentioned in ​PR #14134 on ​WordPress/wordpress-develop by ​@shewa.


8 days ago
#11

  • Keywords has-unit-tests added; needs-unit-tests removed

General: Introduce wp_resolve_site_title() helper to resolve site title fallback and eliminate code duplication

---

Description

In WordPress Core, notification emails and administrative messages resolve the site title by reading the blogname option and decoding special characters (wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES )), falling back to the host name (wp_parse_url( home_url(), PHP_URL_HOST )) when the option is empty.

Previously, this conditional logic was copy-pasted across multiple core files and functions, creating unnecessary duplication and maintenance overhead.

This PR introduces a dedicated helper function wp_resolve_site_title() in wp-includes/functions.php and replaces the repeated boilerplate logic across Core:

  • src/wp-admin/includes/class-wp-automatic-updater.php
  • src/wp-admin/includes/misc.php
  • src/wp-admin/includes/privacy-tools.php
  • src/wp-admin/ms-delete-site.php
  • src/wp-admin/user-new.php
  • src/wp-includes/class-wp-recovery-mode-email-service.php
  • src/wp-includes/comment.php
  • src/wp-includes/pluggable.php
  • src/wp-includes/user.php
  • src/wp-includes/functions.php

Testing Instructions

  1. Run PHPUnit test suite for the new function: `bash npm run test:php -- --filter Tests_Functions_WpResolveSiteTitle

Trac ticket:

Use of AI Tools

None

​@r1k0 commented on ​PR #13230:


7 days ago
#12

Thank you, @SirLouen. I did think of a function for the repetitive code but I wasn't sure if it was necessary.
Before I get started working on a fix, what do you think of, I create a helper function to get the site name. Something like this:

function wp_get_site_name() {
  $blogname = get_option( 'blogname' );

  if ( '' !== blogname ) {
       return wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
  }

  return false;
}

But, this time instead of returning the site host name (which makes the email read awkwardly and looks reduntant) I return a false if the blog name is empty. Then I would reword the email templates.
Eg.

$site_name = wp_get_site_name();

if ( $site_name ) {
        $subject = sprintf(
                /* translators: %s: Site title. */
                __( '[%s] Delete My Site' ),
                $site_name
        );
} else {
        $subject = __( 'Delete My Site' );
}

wp_mail(
        get_option( 'admin_email' ),
        $subject,
        $content
);

I would essentially use a similar approach on every email template that uses the site name.

  1. If I was to go with this approach, where would you suggest the helper function lives wp-includes/functions.php or wp-admin/includes/functions.php?
  2. Do you think removing site name (for sites without it) in the template text is an acceptable approach?

Let me know what you think.

#13 @shewa
7 days ago

  • Keywords reporter-feedback added

Hi @r1k0,

PR: ​https://github.com/WordPress/wordpress-develop/pull/14134

I have already created a helper method and reuse it everywhere to reduce the code duplication as mention by @SirLouen . I also agree with the idea that showing a site URL when title is empty would be redundant in some cases. In this case, @r1k0 you pass an argument to the helper function wp_resolve_site_title to return empty string when returning site or host seems unnecessary. @r1k0 can work on top my PR to save time.

I would also love to hear feedback from @SirLouen .

Thanks
Shewa

​@SirLouen commented on ​PR #13230:


7 days ago
#14

@3kori, wouldn't it be better to add conditionally to the template the part that is relevant to the site title?

For example, in your snippet:

$site_name = wp_get_site_name();
$subject   = __( 'Delete My Site' );

if ( $site_name ) {
        $subject = sprintf(
                /* translators: 1: Site title, 2: Email subject. */
                __( '[%1$s] %2$s' ),
                $site_name,
                $subject
        );
}

wp_mail(
        get_option( 'admin_email' ),
        $subject,
        $content
);

#15 @SirLouen
7 days ago

  • Keywords needs-unit-tests added; has-unit-tests removed

@shewa since the @r1k0 PR is live, I would prefer to focus on his PR than dividing the attention into two PR

Note here the PRs are not merged, so here it is as useful to provide code reviews as being the PR creator. A different thing would be if the PR was 6 months old and we had certainty that we needed a new one to revive the ticket. It's not the case here.

So ideally, simply step into @r1k0 PR and add your code review and close your PR to avoid duplication.

PS: @r1k0 also you could maybe edit or create unit tests for the scenario without (at least 1, just for the record)

#16 @shewa
6 days ago

@SirLouen PR closed :)

#17 @peterwilsoncc
5 days ago

I was surprised the site title could be set to an empty value, that seems like the heart of issue here and would best be resolved by ensuring the blogname isn't empty within sanitize_option().

  • src/wp-includes/formatting.php

    diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php
    index 552c5f17c2..68d432a0c9 100644
    a b function sanitize_option( $option, $value ) {  
    50635063
    50645064                        if ( is_wp_error( $value ) ) {
    50655065                                $error = $value->get_error_message();
     5066                        } elseif ( 'blogname' === $option && '' === trim( $value ) ) {
     5067                                $error = __( 'The site title is reuired' );
    50665068                        } else {
    50675069                                $value = esc_html( $value );
    50685070                        }

#18 follow-up: @r1k0
5 days ago

@peterwilsoncc This is something I noted in another ticket https://core.trac.wordpress.org/ticket/65718#comment:12.

With the fix you propose, the email templates won't have to worry about empty blogname fallbacks and I think this will only work for future edits to the site title. For existing sites that currently have a blank site title field (not a common scenario, but it can happen), blogname will still return an empty string in emails.

Last edited 5 days ago by r1k0 (previous) (diff)

#19 in reply to: ↑ 18 @peterwilsoncc
5 days ago

  • Keywords close added

Replying to r1k0:

With the fix you propose, the email templates won't have to worry about empty blogname fallbacks and I think this will only work for future edits to the site title. For existing sites that currently have a blank site title field (not a common scenario, but it can happen), blogname will still return an empty string in emails.

You're right, it will only fix future issues rather than existing sites without a title.

I'm fine with that because, as you say, it's an uncommon scenario so modifying all the email templates (and adding the fallback to new templates) will add a bunch of code for a very small number of sites.

An associated fix would be required to throw an error for an empty site title during installation (see ​code reference).

My inclination is to close this ticket without a fix and focus on #65718.

Note: See TracTickets for help on using tickets.