Jul 24

Adding Static/Dismissible Admin Notifications to WordPress

As a WordPress themes and plugins developer, I often need to provide additional information to my users after they activate my theme or plugin. For example, when a user installs & activates our Twitter Feed plugin, the plugin notifies them that they need to provide the Twitter API tokens in order for the plugin to work. Additionally, if their PHP version is too old, the plugin will ask the user to install a newer version of PHP. Notifying the user about these actions is a crucial part of a successful user experience.

To do that, I have been using the built-in admin_notices action hook to print a notification across all admin pages. However, these notifications tend to clutter and sometimes annoy the user and thus achieve the opposite of our intentions. Therefore it was important for me to allow the users to dismiss these notifications. The problem was that WordPress does not provide any interface for doing that.

Since version 4.2, WordPress supports dismissible admin notifications. Unfortunately, the dismissal is not persistent. A dismissed notification will appear again when the user reloads the page or navigates away to another admin page.

To that end, I have developed amarkal-admin-notifications – a simple script that lets you easily add static/dismissible admin notifications with a single line of code. The script also offers additional options to further customize the behavior of the notification.

The following tutorial walks you through how you can add static and dismissible notifications using amarkal-admin-notifications, and further explains what is the underlying mechanism behind it.

Adding a static notification

Adding a static admin notification to WordPress using amarkal-admin-notifications is as simple as making a single function call to amarkal_admin_notification(). At the minimum, this function accepts 3 parameters – $handle, $content and $type. The $handle is used to identify the notification (we’ll further discuss this in the context of dismissible notifications). The $content is used as the content of the notification, and accepts text and HTML. The $type refers to the notification’s type. It accepts one of the strings success, error, info or warning.

The following example will print a static error notification:

<?php
amarkal_admin_notification( 
    'my-error-notice', 
    __('Oh snap! This is an <strong>error</strong> message.','slug'), 
    'error' 
);
?>

WordPress admin notification added using amarkal_admin_notification

Adding a dismissible notification

The fourth argument allows you to turn a notification into a dismissible one. amarkal-admin-notifications makes the dismissal persistent across all admin pages by storing the notification’s handle in the database. When the user clicks on the dismissal button, an AJAX request is made asynchronously to store the notification’s handle.

The following example will print a dismissible warning notification:

<?php
amarkal_admin_notification( 
    'my-warning-notice', 
    __('Listen carefully, this is an <strong>warning</strong> message.','slug'), 
    'warning', 
    true 
);
?>

WordPress dismissible admin notification added using amarkal_admin_notification

But what if we want to show a dismissed notification again? For example, when the user uninstalls a plugin and reinstall it again, it makes sense to show the notification again even though the user has dismissed it previously. For that purpose, you can use the function wp_reset_admin_notification( $handle ), which resets a notification for a given handle. The call will remove the given handle from the database if the user has previously dismissed it.

For example, the following code will reset the notification that correspond to the handle 'my-warning-notice':

<?php
wp_reset_admin_notification( 'my-warning-notice' );
?>

It is a good practice to make a call to this function as part of the plugin/theme’s deactivation hook. This will remove any traces from the database (unless there is another plugin that is using it).

Adding network-wide notifications in a multisite

In a WordPress multisite environment, each site is its own separate entity with its own administration and database tables. Furthermore, there is an added shared network administration section, which requires hooking to a special action hook. amarkal-admin-notifications will print network-wide notifications if the 6th parameter is set to true. It does that by hooking to the network_admin_notices hook.

The following example will print a static error notification across all sites, including in the network administration:

<?php
amarkal_admin_notification( 
    'my-error-notice', 
    __('Oh snap! This is an <strong>error</strong> message.','slug'), 
    'error',
    false,
    '', // An additional CSS class
    true // Make this notification network-wide
);
?>

Customizing the notification’s appearance

The function’s 5th argument lets you add an additional CSS class to the notification. This allows you to further customize the notification’s appearance. You can also increase CSS specificity by using the notification’s ID. amarkal-admin-notifications uses the notification’s handle as the element’s ID attribute.

For example, to change the background of the following notification:

<?php
amarkal_admin_notification( 
    'my-error-notice', 
    __('Oh snap! This is an <strong>error</strong> message.','slug'), 
    'error',
    false,
    'my-notice', // An additional CSS class
);
?>

You can use the following CSS:

.my-notice {
    background-color: red;
}
/* Or use the id to increase specificity */
#my-error-notice {
    background-color: red;
}

Speed and performance

amarkal-admin-notifications only initiates if there is at least 1 registered notification. Therefore, the added performance impact is negligible. Additionally, if  wp_reset_admin_notification( $handle ) is used properly, the database will remain clear of any traces.

Conclusion

With amarkal-admin-notifications adding static/dismissible admin notifications becomes easy. If you find it useful, please share this article or star the project on github. If you have any additional questions/requests, please post them in the comment section. Thanks!

Yoav Kadosh | July 24, 2016

Leave a Reply