2026年5月20日
2026年5月20日
WordPress パスワードリセットメールの件名・本文を変える方法|retrieve_password のフィルター
WordPress のパスワードリセットメールは、コアのフィルターで件名・本文・ヘッダーを変えられます。この記事のコードは WordPress 6.9.4 のソース(wp-includes/user.php の retrieve_password())で引数と順序を確認したものです(2026年11月時点)。
コードは子テーマの functions.php か、wp-content/mu-plugins/ に置いた PHP ファイルに書きます。親テーマの functions.php に書くと、テーマの更新で消えます。
既定のメールの中身
ログイン画面の「パスワードをお忘れですか ?」から申し込むと、retrieve_password() が次の内容でメールを組み立てます。
| 項目 | 既定の内容 |
|---|---|
| 件名 | [サイト名] Password Reset(日本語のサイトでは翻訳された文言) |
| 本文 | サイト名、ユーザー名、心当たりがなければ無視してよいという案内、リセット用 URL、(ログアウト状態で申し込んだ場合)申し込み元の IP アドレス |
| 宛先 | そのユーザーのメールアドレス |
| 言語 | ユーザーごとの言語設定(無ければサイトの言語) |
| リンクの有効期限 | 1日(password_reset_expiration フィルターで変更可) |
本文はユーザーの言語に切り替えてから作られるので、サイトの言語が日本語なら文面も日本語になります。変えたいのは主に、言い回し・署名・問い合わせ先などです。
使えるフィルター
| フィルター | 変えられるもの | 引数 |
|---|---|---|
retrieve_password_title |
件名 | $title, $user_login, $user_data |
retrieve_password_message |
本文 | $message, $key, $user_login, $user_data |
retrieve_password_notification_email |
宛先・件名・本文・ヘッダーをまとめて(WordPress 6.0 以降) | $defaults(配列), $key, $user_login, $user_data |
password_reset_expiration |
リセット用リンクの有効期間(秒) | $expiration |
$user_data は WP_User オブジェクトです。引数を2つ以上受け取るときは、add_filter() の第4引数(受け取る引数の数)を指定します。指定しないと最初の1つしか渡されません。
手順 1: 件名を変える
<?php
// パスワードリセットメールの件名を変える
add_filter( 'retrieve_password_title', function ( $title, $user_login, $user_data ) {
$site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
return sprintf( '[%s] パスワード再設定のご案内', $site_name );
}, 10, 3 );
サイト名は get_option( 'blogname' ) で取ります。保存時に HTML エスケープされているため、コアと同じく wp_specialchars_decode() で戻してから使います。
手順 2: 本文を変える
本文を丸ごと作り直すときは、リセット用 URL を自分で組み立てます。コアと同じ形にしておくと、ログイン名の末尾がピリオドの場合などでも正しく動きます。
<?php
// パスワードリセットメールの本文を変える
add_filter( 'retrieve_password_message', function ( $message, $key, $user_login, $user_data ) {
$site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
// コアと同じ形のリセット URL(login を最後にしない)
$reset_url = network_site_url(
'wp-login.php?login=' . rawurlencode( $user_login ) . '&key=' . $key . '&action=rp',
'login'
);
$reset_url .= '&wp_lang=' . get_user_locale( $user_data );
$lines = array(
$user_data->display_name . ' 様',
'',
$site_name . ' のパスワード再設定のお申し込みを受け付けました。',
'次の URL を開き、新しいパスワードを設定してください。',
'',
$reset_url,
'',
'この URL の有効期限は 24 時間です。',
'お申し込みに心当たりがない場合は、このメールを破棄してください。パスワードは変わりません。',
'',
'--',
$site_name,
home_url( '/' ),
);
return implode( "\r\n", $lines );
}, 10, 4 );
注意点は次のとおりです。
- 本文に URL を入れ忘れると、ユーザーはパスワードを再設定できません。
- このフィルターが空文字を返すと、メールは送られません(コアの仕様)。
- 既定の本文にある申し込み元 IP アドレスは、上の例では省いています。残したい場合は、元の
$messageに文章を足す形にします。 - 有効期限を 24 時間以外にした場合は、本文の記載も合わせます(手順 4)。
既定の本文の前後に一言足すだけなら、作り直さずに連結します。
<?php
// 既定の本文の末尾に署名を足す
add_filter( 'retrieve_password_message', function ( $message ) {
return $message . "\r\n--\r\nお問い合わせ: support@example.com\r\n";
} );
手順 3: ヘッダーや宛先をまとめて変える(WordPress 6.0 以降)
retrieve_password_notification_email は、to・subject・message・headers の配列を受け取り、配列で返します。件名と本文のフィルターを通った後に呼ばれるので、ヘッダーの追加に向いています。
<?php
// 返信先を設定し、HTML メールとして送る
add_filter( 'retrieve_password_notification_email', function ( $email, $key, $user_login, $user_data ) {
$headers = array();
$headers[] = 'Reply-To: support@example.com';
$headers[] = 'Content-Type: text/html; charset=UTF-8';
$email['headers'] = $headers;
$email['message'] = nl2br( esc_html( $email['message'] ) );
return $email;
}, 10, 4 );
HTML メールにする場合は、本文全体を HTML として作り直す必要があります。上の例は、テキストの本文をエスケープして改行を <br /> にするだけの最小の形です。リセット URL はリンクにならず文字列のまま表示されるため、リンクにしたい場合は本文を組み立てる段階で esc_url() を使った a 要素を作ります。迷惑メール判定やメールソフトでの見え方を考えると、テキストのままにしておくのも一つの選択です。
手順 4: リンクの有効期限を変える
<?php
// パスワードリセット用リンクの有効期限を 2 時間にする
add_filter( 'password_reset_expiration', function () {
return 2 * HOUR_IN_SECONDS;
} );
期限を短くした場合は、手順 2 の本文の「24 時間」も直します。
手順 5: 新規ユーザー登録の管理者向け通知も変える場合
パスワードリセットとは別のメールですが、同じように文面を変えたいことが多いので載せておきます。管理者向けの通知は wp_new_user_notification_email_admin、登録したユーザー向けは wp_new_user_notification_email で変えます(どちらも引数は $email, $user, $blogname)。
<?php
// 新規ユーザー登録時の管理者向け通知の文面を変える
add_filter( 'wp_new_user_notification_email_admin', function ( $email, $user, $blogname ) {
// 件名はこの後コア側で sprintf( 件名, サイト名 ) されるので %s を残す
$email['subject'] = '[%s] 新規ユーザー登録: ' . $user->user_login;
$email['message'] = sprintf(
"新しいユーザーが登録しました。\r\n\r\nユーザー名: %s\r\nメール: %s\r\n\r\nユーザー一覧: %s\r\n",
$user->user_login,
$user->user_email,
admin_url( 'users.php' )
);
return $email;
}, 10, 3 );
管理者向け通知の件名は、コアがこのフィルターの後で sprintf( 件名, サイト名 ) に通します。件名に %s を書いておくと、そこにサイト名が入ります。
手順 6: 送信して確かめる
- ログアウトした状態(別のブラウザーかプライベートウィンドウ)で
wp-login.php?action=lostpasswordを開きます。 - テスト用ユーザーのユーザー名かメールアドレスを入れて送信します。
- 届いたメールの件名・本文を確かめ、URL を開いて新しいパスワードを設定できることを確かめます。
申し込むたびに新しいキーが作られ、前のメールの URL は使えなくなります。確かめるときは最後に届いたメールの URL を開きます。
メール自体が届かない場合は、文面の問題ではなく送信の問題です。サーバーからの送信設定や SMTP の設定を先に確認してください。
うまくいかないとき
| 症状 | 確かめること |
|---|---|
| 件名・本文が変わらない | コードを置いたファイルが読み込まれているか(有効なテーマが子テーマか、mu-plugins に置いたか)、同じフィルターを使うプラグインが後から上書きしていないか |
本文に $key などが空で入る |
add_filter() の第4引数(受け取る引数の数)を指定しているか |
| URL を開くと「無効なキー」と出る | 古いメールの URL を開いていないか、有効期限を過ぎていないか、メールソフトが URL を途中で折り返していないか |
| メールが送られなくなった | retrieve_password_message が空文字を返していないか |
まとめ
- 件名は
retrieve_password_title、本文はretrieve_password_message、ヘッダーや宛先はretrieve_password_notification_email(6.0 以降)で変えます。 - 本文を作り直すときは、リセット URL をコアと同じ形で組み立て、入れ忘れないようにします。
- 有効期限は
password_reset_expirationで変えられ、本文の記載も合わせます。