Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have a simple meta box that updates the post custom fields (using update_post_meta()).

How can I send a error or warning message to the next page after the user publishes/updates the post and doesn't fill one of the meta box fields (or fills them with invalid data) ?

share|improve this question

3 Answers 3

up vote 7 down vote accepted

You can do this by hand, but WP natively does it like this for settings errors:

  1. add_settings_error() to create message.
  2. Then set_transient('settings_errors', get_settings_errors(), 30);
  3. settings_errors() in admin_notices hook to display (will need to hook for non-settings screens).
share|improve this answer
    
it does what I want, but wouldn't this fill the database with tons of transients? –  onetrickpony Apr 22 '11 at 21:14
    
@One Trick Pony in native process transient is explicitly deleted (see get_settings_errors() source) . You might need to do that yourself if adapting logic for non-settings page. –  Rarst Apr 22 '11 at 21:20
1  
still I don't like the idea of storing temporary error messages in the db. I'll use ajax to warn the user on input change –  onetrickpony Apr 22 '11 at 21:23

you can use admin_notices hook

first define the notice function:

function my_admin_notice(){
    //print the message
    echo '<div id="message">
       <p>metabox as errors on save message here!!!</p>
    </div>';
    //make sure to remove notice after its displayed so its only displayed when needed.
    remove_action('admin_notices', 'my_admin_notice');
}

The you you metabox save function based on if needed add:

...
...
if($errors){
    add_action('admin_notices', 'my_admin_notice');
}
...
...

Update

Like I promised here is an example of a of how i add an error message form my metabox

<?php
/*
Plugin Name: one-trick-pony-notice
Plugin URI: http://en.bainternet.info
Description: Just to proof a point using admin notice form metabox
Version: 1.0
Author: Bainternet
Author URI: http://en.bainternet.info
*/

/*  admin notice */
function my_admin_notice(){
    //print the message
    global $post;
    $notice = get_option('otp_notice');
    if (empty($notice)) return '';
    foreach($notice as $pid => $m){
        if ($post->ID == $pid ){
            echo '<div id="message" class="error"><p>'.$m.'</p></div>';
            //make sure to remove notice after its displayed so its only displayed when needed.
            unset($notice[$pid]);
            update_option('otp_notice',$notice);
            break;
        }
    }
}

//hooks

add_action('add_meta_boxes', 'OT_mt_add');
add_action('save_post', 'OT_mt_save');
add_action('admin_notices', 'my_admin_notice',0);

//add metabox
function OT_mt_add() {
    add_meta_box('OT_mt_sectionid', __( 'One Trick Meta Box notice', 'textdomain' ),'OT_mt_display','post');
}

//display metabox
function OT_mt_display() {

  // Use nonce for verification
  wp_nonce_field( plugin_basename(__FILE__), 'myplugin_noncename' );

  // The actual fields for data entry
  echo '<label for="myplugin_new_field">';
       _e("leave blank to get a notice on publish or update", 'textdomain' );
  echo '</label> ';
  echo '<input type="text" id="ot_field" name="ot_field" value="" size="25" />';

}


//save metabox here is were i check the fields and if empty i display a message
function OT_mt_save( $post_id ) {

  // verify this came from the our screen and with proper authorization,
  // because save_post can be triggered at other times
    if (!isset($_POST['myplugin_noncename'])) return $post_id;
  if ( !wp_verify_nonce( $_POST['myplugin_noncename'], plugin_basename(__FILE__) ) )
      return $post_id;

  // verify if this is an auto save routine. 
  // If it is our form has not been submitted, so we dont want to do anything
  if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) 
      return $post_id;


  if(!isset($_POST['ot_field']) || empty($_POST['ot_field'])){
    //field left empty so we add a notice
    $notice = get_option('otp_notice');
    $notice[$post_id] = "You have left the field empty";
    update_option('otp_notice',$notice);
  }

}

Now when looking for this code i found my old way of doing it using post_updated_messages filter hook in about the same way so i'll add that too:

<?php
/*
Plugin Name: one-trick-pony-notice2
Plugin URI: http://en.bainternet.info
Description: just like the one above but this time using post_updated_messages hook
Version: 1.0
Author: Bainternet
Author URI: http://en.bainternet.info
*/

//hooks
add_filter('post_updated_messages','my_messages',0);
add_action('add_meta_boxes', 'OT_mt_add');
add_action('save_post', 'OT_mt_save');


//add metabox
function OT_mt_add() {
    add_meta_box('OT_mt_sectionid', __( 'One Trick Meta Box notice', 'textdomain' ),'OT_mt_display','post');
}

//display metabox
function OT_mt_display() {

  // Use nonce for verification
  wp_nonce_field( plugin_basename(__FILE__), 'myplugin_noncename' );

  // The actual fields for data entry
  echo '<label for="myplugin_new_field">';
       _e("leave blank to get a notice on publish or update", 'textdomain' );
  echo '</label> ';
  echo '<input type="text" id="ot_field" name="ot_field" value="" size="25" />';

}


//save metabox here is were i check the fields and if empty i display a message
function OT_mt_save( $post_id ) {

  // verify this came from the our screen and with proper authorization,
  // because save_post can be triggered at other times
    if (!isset($_POST['myplugin_noncename'])) return $post_id;
  if ( !wp_verify_nonce( $_POST['myplugin_noncename'], plugin_basename(__FILE__) ) )
      return $post_id;

  // verify if this is an auto save routine. 
  // If it is our form has not been submitted, so we dont want to do anything
  if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) 
      return $post_id;


  if(!isset($_POST['ot_field']) || empty($_POST['ot_field'])){
    //field left empty so we add a notice
    $notice = get_option('otp_notice');
    $notice[$post_id] = "You have left the field empty";
    update_option('otp_notice',$notice);
  }

}

//messages filter
function my_messages($m){
    global $post;
    $notice = get_option('otp_notice');
    if (empty($notice)) return $m;
    foreach($notice as $pid => $mm){
        if ($post->ID == $pid ){
            foreach ($m['post'] as $i => $message){
                $m['post'][$i] = $message.'<p>'.$mm.'</p>';

            }
            unset($notice[$pid]);
            update_option('otp_notice',$notice);
            break;
        }
    }
    return $m;
}
share|improve this answer
    
doesn't really work because after you save the post, you get redirected so that action never runs... –  onetrickpony Apr 22 '11 at 21:16
1  
Redirected where? And the code above is wha i use so i know it works. –  Bainternet Apr 22 '11 at 21:23
    
is your metabox save function hooked on save_post ? –  onetrickpony Apr 22 '11 at 21:31
    
Either save_post or wp_insert_post_data why? –  Bainternet Apr 22 '11 at 21:34
    
because it doesn't work :) After you hit the publish button the post is saved and then you get redirected back to the edit page. –  onetrickpony Apr 22 '11 at 21:43

This answer [mirror] from Otto in WP Tavern, actually solves the transient problem by doing what WordPress itself does to overcome the redirect problem. Totally worked for me.

The problem is that transients are there for everybody. If you have more than one user doing things at the same time, the error message can go to the wrong person. It's a race condition.

WordPress actually does this by passing a message parameter in the URL. The message number indicates which message to display.

You can do the same by hooking the redirect_post_location filter and then using add_query_arg to add your own parameter to the request. Like so:

add_filter('redirect_post_location','my_message');
function my_message($loc) {
 return add_query_arg( 'my_message', 123, $loc );
}

This adds my_message=123 to the query. Then, after the redirect, you can detect the my_message setting in the $_GET and display the proper message accordingly.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.