diff --git a/src/wp-admin/css/login.css b/src/wp-admin/css/login.css
index 8f43504c1c..fe790f0b42 100644
--- a/src/wp-admin/css/login.css
+++ b/src/wp-admin/css/login.css
@@ -42,8 +42,8 @@ p {
}
.login .message,
-.login .success,
-.login #login_error {
+.login .notice,
+.login .success {
border-left: 4px solid #72aee6;
padding: 12px;
margin-left: 0;
@@ -57,10 +57,19 @@ p {
border-left-color: #00a32a;
}
-.login #login_error {
+/* Match border color from common.css */
+.login .notice-error {
border-left-color: #d63638;
}
+.login .login-error-list {
+ list-style: none;
+}
+
+.login .login-error-list li + li {
+ margin-top: 4px;
+}
+
#loginform p.submit,
.login-action-lostpassword p.submit {
border: none;
@@ -237,6 +246,11 @@ p {
margin-bottom: 0;
}
+#login form .indicator-hint,
+#login #reg_passmail {
+ margin-bottom: 16px;
+}
+
#login form p.submit {
margin: 0;
padding: 0;
@@ -342,9 +356,7 @@ p {
font-family: Consolas, Monaco, monospace;
}
-.js.login input.password-input,
-.js.login-action-rp form .input,
-.js.login-action-rp input[type="text"] {
+.js.login input.password-input {
padding-right: 2.5rem;
}
@@ -354,6 +366,8 @@ p {
background: #fff;
}
+.js.login-action-resetpass input[type="text"],
+.js.login-action-resetpass input[type="password"],
.js.login-action-rp input[type="text"],
.js.login-action-rp input[type="password"] {
margin-bottom: 0;
diff --git a/src/wp-admin/includes/misc.php b/src/wp-admin/includes/misc.php
index 8c4caa468d..090282062f 100644
--- a/src/wp-admin/includes/misc.php
+++ b/src/wp-admin/includes/misc.php
@@ -1642,147 +1642,3 @@ function wp_check_php_version() {
return $response;
}
-
-/**
- * Creates and returns the markup for an admin notice.
- *
- * @since 6.4.0
- *
- * @param string $message The message.
- * @param array $args {
- * Optional. An array of arguments for the admin notice. Default empty array.
- *
- * @type string $type Optional. The type of admin notice.
- * For example, 'error', 'success', 'warning', 'info'.
- * Default empty string.
- * @type bool $dismissible Optional. Whether the admin notice is dismissible. Default false.
- * @type string $id Optional. The value of the admin notice's ID attribute. Default empty string.
- * @type string[] $additional_classes Optional. A string array of class names. Default empty array.
- * @type string[] $attributes Optional. Additional attributes for the notice div. Default empty array.
- * @type bool $paragraph_wrap Optional. Whether to wrap the message in paragraph tags. Default true.
- * }
- * @return string The markup for an admin notice.
- */
-function wp_get_admin_notice( $message, $args = array() ) {
- $defaults = array(
- 'type' => '',
- 'dismissible' => false,
- 'id' => '',
- 'additional_classes' => array(),
- 'attributes' => array(),
- 'paragraph_wrap' => true,
- );
-
- $args = wp_parse_args( $args, $defaults );
-
- /**
- * Filters the arguments for an admin notice.
- *
- * @since 6.4.0
- *
- * @param array $args The arguments for the admin notice.
- * @param string $message The message for the admin notice.
- */
- $args = apply_filters( 'wp_admin_notice_args', $args, $message );
- $id = '';
- $classes = 'notice';
- $attributes = '';
-
- if ( is_string( $args['id'] ) ) {
- $trimmed_id = trim( $args['id'] );
-
- if ( '' !== $trimmed_id ) {
- $id = 'id="' . $trimmed_id . '" ';
- }
- }
-
- if ( is_string( $args['type'] ) ) {
- $type = trim( $args['type'] );
-
- if ( str_contains( $type, ' ' ) ) {
- _doing_it_wrong(
- __FUNCTION__,
- sprintf(
- /* translators: %s: The "type" key. */
- __( 'The %s key must be a string without spaces.' ),
- 'type'
- ),
- '6.4.0'
- );
- }
-
- if ( '' !== $type ) {
- $classes .= ' notice-' . $type;
- }
- }
-
- if ( true === $args['dismissible'] ) {
- $classes .= ' is-dismissible';
- }
-
- if ( is_array( $args['additional_classes'] ) && ! empty( $args['additional_classes'] ) ) {
- $classes .= ' ' . implode( ' ', $args['additional_classes'] );
- }
-
- if ( is_array( $args['attributes'] ) && ! empty( $args['attributes'] ) ) {
- $attributes = '';
- foreach ( $args['attributes'] as $attr => $val ) {
- if ( is_bool( $val ) ) {
- $attributes .= $val ? ' ' . $attr : '';
- } elseif ( is_int( $attr ) ) {
- $attributes .= ' ' . esc_attr( trim( $val ) );
- } elseif ( $val ) {
- $attributes .= ' ' . $attr . '="' . esc_attr( trim( $val ) ) . '"';
- }
- }
- }
-
- if ( false !== $args['paragraph_wrap'] ) {
- $message = "
$message
";
- }
-
- $markup = sprintf( '%4$s
', $id, $classes, $attributes, $message );
-
- /**
- * Filters the markup for an admin notice.
- *
- * @since 6.4.0
- *
- * @param string $markup The HTML markup for the admin notice.
- * @param string $message The message for the admin notice.
- * @param array $args The arguments for the admin notice.
- */
- return apply_filters( 'wp_admin_notice_markup', $markup, $message, $args );
-}
-
-/**
- * Outputs an admin notice.
- *
- * @since 6.4.0
- *
- * @param string $message The message to output.
- * @param array $args {
- * Optional. An array of arguments for the admin notice. Default empty array.
- *
- * @type string $type Optional. The type of admin notice.
- * For example, 'error', 'success', 'warning', 'info'.
- * Default empty string.
- * @type bool $dismissible Optional. Whether the admin notice is dismissible. Default false.
- * @type string $id Optional. The value of the admin notice's ID attribute. Default empty string.
- * @type string[] $additional_classes Optional. A string array of class names. Default empty array.
- * @type bool $paragraph_wrap Optional. Whether to wrap the message in paragraph tags. Default true.
- * }
- */
-function wp_admin_notice( $message, $args = array() ) {
- /**
- * Fires before an admin notice is output.
- *
- * @since 6.4.0
- *
- * @param string $message The message for the admin notice.
- * @param array $args The arguments for the admin notice.
- */
- do_action( 'wp_admin_notice', $message, $args );
-
- echo wp_kses_post( wp_get_admin_notice( $message, $args ) );
-}
diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php
index f3c4af1405..d2c02abedd 100644
--- a/src/wp-includes/functions.php
+++ b/src/wp-includes/functions.php
@@ -8762,3 +8762,147 @@ function is_php_version_compatible( $required ) {
function wp_fuzzy_number_match( $expected, $actual, $precision = 1 ) {
return abs( (float) $expected - (float) $actual ) <= $precision;
}
+
+/**
+ * Creates and returns the markup for an admin notice.
+ *
+ * @since 6.4.0
+ *
+ * @param string $message The message.
+ * @param array $args {
+ * Optional. An array of arguments for the admin notice. Default empty array.
+ *
+ * @type string $type Optional. The type of admin notice.
+ * For example, 'error', 'success', 'warning', 'info'.
+ * Default empty string.
+ * @type bool $dismissible Optional. Whether the admin notice is dismissible. Default false.
+ * @type string $id Optional. The value of the admin notice's ID attribute. Default empty string.
+ * @type string[] $additional_classes Optional. A string array of class names. Default empty array.
+ * @type string[] $attributes Optional. Additional attributes for the notice div. Default empty array.
+ * @type bool $paragraph_wrap Optional. Whether to wrap the message in paragraph tags. Default true.
+ * }
+ * @return string The markup for an admin notice.
+ */
+function wp_get_admin_notice( $message, $args = array() ) {
+ $defaults = array(
+ 'type' => '',
+ 'dismissible' => false,
+ 'id' => '',
+ 'additional_classes' => array(),
+ 'attributes' => array(),
+ 'paragraph_wrap' => true,
+ );
+
+ $args = wp_parse_args( $args, $defaults );
+
+ /**
+ * Filters the arguments for an admin notice.
+ *
+ * @since 6.4.0
+ *
+ * @param array $args The arguments for the admin notice.
+ * @param string $message The message for the admin notice.
+ */
+ $args = apply_filters( 'wp_admin_notice_args', $args, $message );
+ $id = '';
+ $classes = 'notice';
+ $attributes = '';
+
+ if ( is_string( $args['id'] ) ) {
+ $trimmed_id = trim( $args['id'] );
+
+ if ( '' !== $trimmed_id ) {
+ $id = 'id="' . $trimmed_id . '" ';
+ }
+ }
+
+ if ( is_string( $args['type'] ) ) {
+ $type = trim( $args['type'] );
+
+ if ( str_contains( $type, ' ' ) ) {
+ _doing_it_wrong(
+ __FUNCTION__,
+ sprintf(
+ /* translators: %s: The "type" key. */
+ __( 'The %s key must be a string without spaces.' ),
+ 'type'
+ ),
+ '6.4.0'
+ );
+ }
+
+ if ( '' !== $type ) {
+ $classes .= ' notice-' . $type;
+ }
+ }
+
+ if ( true === $args['dismissible'] ) {
+ $classes .= ' is-dismissible';
+ }
+
+ if ( is_array( $args['additional_classes'] ) && ! empty( $args['additional_classes'] ) ) {
+ $classes .= ' ' . implode( ' ', $args['additional_classes'] );
+ }
+
+ if ( is_array( $args['attributes'] ) && ! empty( $args['attributes'] ) ) {
+ $attributes = '';
+ foreach ( $args['attributes'] as $attr => $val ) {
+ if ( is_bool( $val ) ) {
+ $attributes .= $val ? ' ' . $attr : '';
+ } elseif ( is_int( $attr ) ) {
+ $attributes .= ' ' . esc_attr( trim( $val ) );
+ } elseif ( $val ) {
+ $attributes .= ' ' . $attr . '="' . esc_attr( trim( $val ) ) . '"';
+ }
+ }
+ }
+
+ if ( false !== $args['paragraph_wrap'] ) {
+ $message = "$message
";
+ }
+
+ $markup = sprintf( '%4$s
', $id, $classes, $attributes, $message );
+
+ /**
+ * Filters the markup for an admin notice.
+ *
+ * @since 6.4.0
+ *
+ * @param string $markup The HTML markup for the admin notice.
+ * @param string $message The message for the admin notice.
+ * @param array $args The arguments for the admin notice.
+ */
+ return apply_filters( 'wp_admin_notice_markup', $markup, $message, $args );
+}
+
+/**
+ * Outputs an admin notice.
+ *
+ * @since 6.4.0
+ *
+ * @param string $message The message to output.
+ * @param array $args {
+ * Optional. An array of arguments for the admin notice. Default empty array.
+ *
+ * @type string $type Optional. The type of admin notice.
+ * For example, 'error', 'success', 'warning', 'info'.
+ * Default empty string.
+ * @type bool $dismissible Optional. Whether the admin notice is dismissible. Default false.
+ * @type string $id Optional. The value of the admin notice's ID attribute. Default empty string.
+ * @type string[] $additional_classes Optional. A string array of class names. Default empty array.
+ * @type bool $paragraph_wrap Optional. Whether to wrap the message in paragraph tags. Default true.
+ * }
+ */
+function wp_admin_notice( $message, $args = array() ) {
+ /**
+ * Fires before an admin notice is output.
+ *
+ * @since 6.4.0
+ *
+ * @param string $message The message for the admin notice.
+ * @param array $args The arguments for the admin notice.
+ */
+ do_action( 'wp_admin_notice', $message, $args );
+
+ echo wp_kses_post( wp_get_admin_notice( $message, $args ) );
+}
diff --git a/src/wp-login.php b/src/wp-login.php
index de2ee486c7..60877bdb70 100644
--- a/src/wp-login.php
+++ b/src/wp-login.php
@@ -228,21 +228,35 @@ function login_header( $title = 'Log In', $message = '', $wp_error = null ) {
}
if ( $wp_error->has_errors() ) {
- $errors = '';
- $messages = '';
+ $error_list = array();
+ $messages = '';
foreach ( $wp_error->get_error_codes() as $code ) {
$severity = $wp_error->get_error_data( $code );
foreach ( $wp_error->get_error_messages( $code ) as $error_message ) {
if ( 'message' === $severity ) {
- $messages .= ' ' . $error_message . "
\n";
+ $messages .= '' . $error_message . '
';
} else {
- $errors .= ' ' . $error_message . "
\n";
+ $error_list[] = $error_message;
}
}
}
- if ( ! empty( $errors ) ) {
+ if ( ! empty( $error_list ) ) {
+ $errors = '';
+
+ if ( count( $error_list ) > 1 ) {
+ $errors .= '';
+
+ foreach ( $error_list as $item ) {
+ $errors .= '- ' . $item . '
';
+ }
+
+ $errors .= '
';
+ } else {
+ $errors .= '' . $error_message . '
';
+ }
+
/**
* Filters the error messages displayed above the login form.
*
@@ -250,7 +264,15 @@ function login_header( $title = 'Log In', $message = '', $wp_error = null ) {
*
* @param string $errors Login error message.
*/
- echo '' . apply_filters( 'login_errors', $errors ) . "
\n";
+ $errors = apply_filters( 'login_errors', $errors );
+ wp_admin_notice(
+ $errors,
+ array(
+ 'type' => 'error',
+ 'id' => 'login_error',
+ 'paragraph_wrap' => false,
+ )
+ );
}
if ( ! empty( $messages ) ) {
@@ -261,7 +283,16 @@ function login_header( $title = 'Log In', $message = '', $wp_error = null ) {
*
* @param string $messages Login messages.
*/
- echo '' . apply_filters( 'login_messages', $messages ) . "
\n";
+ $messages = apply_filters( 'login_messages', $messages );
+ wp_admin_notice(
+ $messages,
+ array(
+ 'type' => 'info',
+ 'id' => 'login-message',
+ 'additional_classes' => array( 'message' ),
+ 'paragraph_wrap' => false,
+ )
+ );
}
}
} // End of login_header().
@@ -399,7 +430,6 @@ function login_footer( $input_id = '' ) {
do_action( 'login_footer' );
?>
-