Fix Admin Notices not showing on the Dashboard (v2.4.2)

admin_notices fires everywhere, but prints inside #wpbody, which
DashboardTakeover hides entirely on the Dashboard (to hide the *native*
dashboard, not ours) — notices went down with it as collateral damage.
Notices::render_for_dashboard() now renders directly inside the visible
dashboard frame instead, called from DashboardTakeover::render_mount();
the normal admin_notices path bails on the Dashboard so it isn't
rendered twice.

Second, independent bug found along the way: wp-admin/js/common.js
unconditionally relocates every .notice element on the page to right
after the page's <h1>, regardless of where it was placed server-side —
without opting out, it would've silently moved our notice right back
into the hidden #wpbody. Used core's own documented `below-h2` class to
opt out, only for the dashboard render path.

Verified live: notice now shows correctly inside the dashboard frame
with proper dark styling, and dismisses correctly.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
nixpanel
2026-07-04 10:27:58 -05:00
co-authored by Claude Sonnet 5
parent 03c3c4fc89
commit d8bf1ae049
8 changed files with 110 additions and 4 deletions
+46
View File
@@ -1,6 +1,8 @@
<?php
namespace AuroraAdmin\Notices;
use AuroraAdmin\Pages\DashboardTakeover;
defined("ABSPATH") || exit();
/**
@@ -57,7 +59,48 @@ class Notices
update_option(self::DB_OPTION, self::DB_VERSION);
}
/**
* Hooked to admin_notices, which fires everywhere EXCEPT it doesn't
* actually reach the user on the Dashboard: admin_notices normally
* prints inside #wpbody, and DashboardTakeover hides #wpbody entirely
* there to hide the *native* dashboard widgets, taking custom notices
* down with it as collateral damage. render_for_dashboard() (called
* directly by DashboardTakeover, inside its own visible mount point) is
* the fix for that one case — skip the normal path here so it isn't
* rendered (invisibly) twice.
*/
public static function render()
{
if (DashboardTakeover::is_dashboard()) {
return;
}
self::render_notices(false);
}
/**
* Called directly by DashboardTakeover::render_mount(), inside the
* visible dashboard frame, since the normal admin_notices hook never
* reaches the user there (see render()).
*/
public static function render_for_dashboard()
{
self::render_notices(true);
}
/**
* $keep_in_place matters because of a WP core behavior, not a bug of
* ours: wp-admin/js/common.js unconditionally relocates every
* `.notice`/`.updated`/`.error` element on the page to right after the
* page's <h1> ($('div.notice').not('.inline, .below-h2').insertAfter(...)),
* regardless of where it was originally placed in the DOM. On every
* other page that's harmless (it's already heading there anyway); on
* the Dashboard it silently moves our notice into the native #wpbody,
* which is hidden entirely by DashboardTakeover — invisible, not gone.
* `below-h2` is core's own documented opt-out class for exactly this
* "leave this notice exactly where I put it" case.
*/
private static function render_notices($keep_in_place)
{
global $wpdb;
$user = wp_get_current_user();
@@ -83,6 +126,9 @@ class Notices
$type = in_array($row->type, ["success", "warning", "error", "info"], true) ? $row->type : "info";
$classes = "notice notice-{$type} aurora-native-notice";
if ($keep_in_place) {
$classes .= " below-h2";
}
if ($row->dismissible) {
$classes .= " is-dismissible";
}
+4
View File
@@ -3,6 +3,7 @@ namespace AuroraAdmin\Pages;
use AuroraAdmin\Utility\Assets;
use AuroraAdmin\Options\Settings;
use AuroraAdmin\Notices\Notices;
defined("ABSPATH") || exit();
@@ -80,6 +81,9 @@ class DashboardTakeover
"settings" => Settings::get_safe(),
];
?>
<div id="aurora-admin-dashboard-notices">
<?php Notices::render_for_dashboard(); ?>
</div>
<div
id="aurora-admin-dashboard-root"
data-aurora-admin="<?php echo esc_attr(wp_json_encode($data)); ?>"