Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/js/_enqueues/admin/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,11 @@ $( function() {
if ( ! $headerEnd.length ) {
$headerEnd = $( '.wrap h1, .wrap h2' ).first();
}
$( 'div.updated, div.error, div.notice' ).not( '.inline, .below-h2' ).insertAfter( $headerEnd );
if ( $( '#wp-admin-notices' ).length ) {
$( '#wp-admin-notices' ).insertAfter( $headerEnd );
} else {
$( 'div.updated, div.error, div.notice' ).not( '.inline, .below-h2' ).insertAfter( $headerEnd );
}

/**
* Makes notices dismissible.
Expand Down
2 changes: 2 additions & 0 deletions src/js/_enqueues/wp/updates.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@
$notice.replaceWith( $adminNotice );
} else if ( $headerEnd.length ) {
$headerEnd.after( $adminNotice );
} else if ( $( '#wp-admin-notices' ).length ) {
$( '#wp-admin-notices' ).append( $adminNotice );
} else {
if ( 'customize' === pagenow ) {
$( '.customize-themes-notifications' ).append( $adminNotice );
Expand Down
32 changes: 3 additions & 29 deletions src/wp-admin/admin-header.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@
$admin_title = sprintf( __( 'Recovery Mode — %s' ), $admin_title );
}

wp_capture_admin_notices();

/**
* Filters the title tag content for an admin page.
*
Expand Down Expand Up @@ -290,35 +292,7 @@

$current_screen->render_screen_meta();

if ( is_network_admin() ) {
/**
* Prints network admin screen notices.
*
* @since 3.1.0
*/
do_action( 'network_admin_notices' );
} elseif ( is_user_admin() ) {
/**
* Prints user admin screen notices.
*
* @since 3.1.0
*/
do_action( 'user_admin_notices' );
} else {
/**
* Prints admin screen notices.
*
* @since 3.1.0
*/
do_action( 'admin_notices' );
}

/**
* Prints generic admin screen notices.
*
* @since 3.1.0
*/
do_action( 'all_admin_notices' );
wp_render_admin_notices();

if ( 'options-general.php' === $parent_file ) {
require ABSPATH . 'wp-admin/options-head.php';
Expand Down
3 changes: 3 additions & 0 deletions src/wp-admin/includes/admin-filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@
// Theme Install hooks.
add_action( 'install_themes_pre_theme-information', 'install_theme_information' );

// Admin notices hooks.
add_filter( 'admin_title', 'wp_prepend_admin_notices_count_to_admin_title' );

// User hooks.
add_action( 'admin_init', 'default_password_nag_handler' );

Expand Down
163 changes: 163 additions & 0 deletions src/wp-admin/includes/admin-notices.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<?php
/**
* Administration notices API.
*
* @package WordPress
* @subpackage Administration
* @since 7.1.0
*/

/**
* Captures admin notices output for the current screen.
*
* @since 7.1.0
*
* @return array {
* @type string $html The captured admin notices markup.
* @type int $count The number of non-inline admin notices.
* }
*/
function wp_capture_admin_notices() {
global $wp_captured_admin_notices;

if ( isset( $wp_captured_admin_notices ) ) {
return $wp_captured_admin_notices;
}

ob_start();

if ( is_network_admin() ) {
/**
* Prints network admin screen notices.
*
* @since 3.1.0
*/
do_action( 'network_admin_notices' );
} elseif ( is_user_admin() ) {
/**
* Prints user admin screen notices.
*
* @since 3.1.0
*/
do_action( 'user_admin_notices' );
} else {
/**
* Prints admin screen notices.
*
* @since 3.1.0
*/
do_action( 'admin_notices' );
}

/**
* Prints generic admin screen notices.
*
* @since 3.1.0
*/
do_action( 'all_admin_notices' );

$html = ob_get_clean();

$wp_captured_admin_notices = array(
'html' => $html,
'count' => wp_count_admin_notices_from_html( $html ),
);

return $wp_captured_admin_notices;
}

/**
* Determines whether admin notices are present for the current screen.
*
* @since 7.1.0
*
* @return bool Whether admin notices are present.
*/
function wp_has_admin_notices() {
$notices = wp_capture_admin_notices();

return $notices['count'] > 0;
}

/**
* Returns the number of admin notices for the current screen.
*
* @since 7.1.0
*
* @return int The number of admin notices.
*/
function wp_get_admin_notices_count() {
$notices = wp_capture_admin_notices();

return $notices['count'];
}

/**
* Counts non-inline admin notices in the given HTML markup.
*
* @since 7.1.0
*
* @param string $html Admin notices HTML markup.
* @return int The number of admin notices.
*/
function wp_count_admin_notices_from_html( $html ) {
if ( '' === trim( $html ) ) {
return 0;
}

$count = 0;

if ( preg_match_all( '/<div\s[^>]*\bclass=["\'][^"\']*\b(?:notice|updated|error)\b[^"\']*["\'][^>]*>/i', $html, $matches ) ) {
foreach ( $matches[0] as $opening_tag ) {
if ( preg_match( '/\b(?:inline|below-h2)\b/', $opening_tag ) ) {
continue;
}

++$count;
}
}

return $count;
}

/**
* Prepends the admin notices count to the admin page title.
*
* @since 7.1.0
*
* @param string $admin_title The page title, with extra context added.
* @return string The filtered page title.
*/
function wp_prepend_admin_notices_count_to_admin_title( $admin_title ) {
$count = wp_get_admin_notices_count();

if ( $count < 1 ) {
return $admin_title;
}

return sprintf(
/* translators: 1: Number of admin notices, 2: Admin page title. */
_n( '(%1$s notice) %2$s', '(%1$s notices) %2$s', $count ),
number_format_i18n( $count ),
$admin_title
);
}

/**
* Renders captured admin notices within an accessible landmark container.
*
* @since 7.1.0
*/
function wp_render_admin_notices() {
$notices = wp_capture_admin_notices();

if ( '' === trim( $notices['html'] ) ) {
return;
}

printf(
'<aside id="wp-admin-notices" class="wp-admin-notices" aria-label="%s">%s</aside>',
esc_attr__( 'Administrative notices' ),
$notices['html'] // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
);
}
3 changes: 3 additions & 0 deletions src/wp-admin/includes/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
/** WordPress Template Administration API */
require_once ABSPATH . 'wp-admin/includes/template.php';

/** WordPress Administration Notices API */
require_once ABSPATH . 'wp-admin/includes/admin-notices.php';

/** WordPress List Table Administration API and base class */
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table-compat.php';
Expand Down
4 changes: 2 additions & 2 deletions src/wp-admin/includes/update.php
Original file line number Diff line number Diff line change
Expand Up @@ -916,10 +916,10 @@ function maintenance_nag() {
function wp_print_admin_notice_templates() {
?>
<script id="tmpl-wp-updates-admin-notice" type="text/html">
<div <# if ( data.id ) { #>id="{{ data.id }}"<# } #> class="notice {{ data.className }}"><p>{{{ data.message }}}</p></div>
<div <# if ( data.id ) { #>id="{{ data.id }}"<# } #> class="notice {{ data.className }}" role="alert"><p>{{{ data.message }}}</p></div>
</script>
<script id="tmpl-wp-bulk-updates-admin-notice" type="text/html">
<div id="{{ data.id }}" class="{{ data.className }} notice <# if ( data.errorMessage ) { #>notice-error<# } else { #>notice-success<# } #>">
<div id="{{ data.id }}" class="{{ data.className }} notice <# if ( data.errorMessage ) { #>notice-error<# } else { #>notice-success<# } #>" role="<# if ( data.errorMessage ) { #>alert<# } else { #>status<# } #>">
<p>
<# if ( data.successMessage ) { #>
{{{ data.successMessage }}}
Expand Down
3 changes: 3 additions & 0 deletions src/wp-admin/menu-header.php
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,9 @@ function _wp_menu_output( $menu, $submenu, $submenu_as_parent = true ) {

<div id="adminmenumain" role="navigation" aria-label="<?php esc_attr_e( 'Main menu' ); ?>">
<a href="#wpbody-content" class="screen-reader-shortcut"><?php _e( 'Skip to main content' ); ?></a>
<?php if ( wp_has_admin_notices() ) : ?>
<a href="#wp-admin-notices" class="screen-reader-shortcut"><?php esc_html_e( 'Skip to notices' ); ?></a>
<?php endif; ?>
<a href="#wp-toolbar" class="screen-reader-shortcut"><?php _e( 'Skip to toolbar' ); ?></a>
<div id="adminmenuback"></div>
<div id="adminmenuwrap">
Expand Down
10 changes: 10 additions & 0 deletions src/wp-includes/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -9140,6 +9140,16 @@ function wp_get_admin_notice( $message, $args = array() ) {
$classes .= ' ' . implode( ' ', $args['additional_classes'] );
}

if ( is_array( $args['attributes'] ) && ! isset( $args['attributes']['role'] ) && is_string( $args['type'] ) ) {
$notice_type = trim( $args['type'] );

if ( 'error' === $notice_type ) {
$args['attributes']['role'] = 'alert';
} elseif ( in_array( $notice_type, array( 'success', 'warning', 'info' ), true ) ) {
$args['attributes']['role'] = 'status';
}
}

if ( is_array( $args['attributes'] ) && ! empty( $args['attributes'] ) ) {
$attributes = '';
foreach ( $args['attributes'] as $attr => $val ) {
Expand Down
Loading
Loading