Ever noticed the messages WordPress displays when you activate a plugin, or save settings? Or the messages that some plugins show in the dashboard, perhaps notifying you of a missing requirement? These are called Admin Notices and I’m going to show you how to add your own in your plugin or theme. They’re really quite easy to add.

To display an admin notice, we’re going to write one function, and it can be placed just about anywhere. If you’re trying this with a theme, then I recommend you place this in your functions.php. If you’re trying this with a plugin you’ve just started, then I’d recommend placing this in your main plugin file. The function does nothing more than echo out the message we’d like displayed. The message is wrapped in a little bit of HTML that will style it the same as the built-in admin notices.

1
2
3
function pippin_admin_notices() {
	echo '<div class="error"><p><strong>Error</strong>: this is my message</p></div>';
}

Now we hook this function into the “admin_notices” hook so that it gets displayed correctly:

1
add_action('admin_notices', 'pippin_admin_notices');

This function will display an “error” message, but what if you want to display a “success” message? All you need to do is change the class of the DIV tag from “error” to “updated”. Like this:

1
2
3
4
function pippin_admin_notices() {
	echo '<div class="updated"><p><strong>Updated</strong>: this is my message</p></div>';
}
add_action('admin_notices', 'pippin_admin_notices');

As described in the video, you can also greatly improve the function above to make it a lot cleaner and easier to work with. In order to do this, I like to use the output buffer function, like so:

1
2
3
4
5
6
7
8
9
function pippin_admin_notices() {
	ob_start(); ?>
	<div class="error">
		<p><strong>Error</strong>: this is my message</p>
	</div>
	<?php
	echo ob_get_clean();
}
add_action('admin_notices', 'pippin_admin_notices');

Using the output buffer makes things a lot cleaner and easier to work with. Rather than putting all of your HTML into a string that is then echoed out, you can simply write your HTML as normal, then echo to contents of the output buffer at the end.

  1. GreggFranklin

    Thanks for the tutorial! I am not sure how to conditionally pick a specific page to add this to. For example I have a page that is using a custom template (Testimonials) and I want to let the user know. In the video you mentioned you looked at the url for the slug, I don’t see that.

    • Pippin

      @Gregg – It sounds like you’re trying to display notices on the front end of the site, is that correct? If so, then this will not do that. This code is just for displaying notices in the admin section.

  2. manifestphil

    Hi Pippin,

    I’m having some trouble logging in to view this article. Entering my username and password on the sidebar returns me to this article, but the “Members Only” content is not displayed. I reset my password, and am able to login via the wp-login.php file to my profile.

    Using Safari 5.0.6, Mac OSX 10.5

    • manifestphil

      Odd. After submitting my comment, I’m now logged in. Refreshing the page didn’t help, but perhaps this loaded the appropriate cookie.

    • Pippin

      Interesting. Let me know if it happens again.

  3. Bryce

    Hey Pippin. How would you set it to only display once after a theme’s activation? Is there a better way than:

    // show admin notice after theme activation
    function spiritualized_admin_notices() {
    if(isset( $_GET['activated'] )) {
    ob_start(); ?>

    Thank you for using Spiritualized! First thing you should do is <a href="/wp-admin/nav-menus.php">add your custom header and footer menus. You should then check out the Theme Options.

    <?php
    echo ob_get_clean();
    }
    else {
    }
    }
    add_action('admin_notices', 'spiritualized_admin_notices');

    • Pippin

      That method should work fine, except that it will show any time a plugin or theme is activated. You need to add in another check to make sure it’s only your theme.

    • Bryce

      I’m assuming it won’t show when another theme (not mine) is activated as the code shouldn’t run without the theme active, so what would be the easiest way to limit it to JUST theme activations? 🙂

    • Pippin

      It should work to just add this:

      1
      2
      3
      4
      
      global $pagenow;
      if( isset( $_GET['activated'] ) && 'themes.php' == $pagenow ) {
          // show notice
      }
  4. bryceadams

    Perfect, thank you Pippin

  5. Marko

    Hi Pippin. I am doing messages, not a strange stuff for me, but I noticed interesting behavior lately which can’t resolve myself still!

    The thing is that ONLY on Permalink Settings page (you know the wp-admin/options-permalink.php page) notices show twice! Could you check that out please, and let us know if you found a fix?

    FYI, I have WordPress multi-site installed, didn’t try on single installation. On any other page notice is shown only once (of course). I’m doing it from plugin, not from functions.php for example.

    • Pippin

      Can you please show me the code you’re using?

    • Marko

      I noticed that this is behavior on WordPress running on Nginx server. I was only checking current screen and is POST set inside admin_notices action, like:

      add_action(‘admin_notices’, ‘cool_function’);
      function cool_function() {

      if (‘options-permalink’ == $current_screen->base) {
      if (isset($_POST[‘submit’])) {
      … some logic and echo here …
      }
      }

      As I mentioned it’s running on Nginx, so found this page:
      http://codex.wordpress.org/Nginx

      And added this:
      add_filter( ‘got_rewrite’, ‘__return_true’ );
      before actions. Now works 🙂 if you have any thoughts about this let me(us) know.. anyway it’s one more information about this.

  6. Travis Arnold

    What’s the reason for checking both

    isset($_GET[‘page’]) && $_GET[‘page’] == ‘page-name’

    Couldn’t you just check that

    $_GET[‘page’] == ‘page-name’

    • Travis Arnold

      Please delete. I understand why now.

Comments are closed.