问题描述

我有一个简单的元框来更新帖子自定义字段 (使用 update_post_meta()) 。

在用户发布/更新帖子之后,如何发送错误或警告消息,并且不填写其中一个元框字段 (或填写无效数据)?

最佳解决方案

你可以手动执行,但 WP 本身就是这样设置错误:

  1. add_settings_error()创建消息。

  2. 然后 set_transient('settings_errors', get_settings_errors(), 30);

  3. settings_errors()admin_notices 挂钩显示 (需要挂钩 non-settings 屏幕) 。

次佳解决方案

您可以使用 admin_notices

首先定义通知功能:

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');
}

你可以根据需要添加 metabox 保存功能:

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

Update

像我在这里答应的一个例子,我如何添加我的 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);
  }

}

现在,当找到这个代码时,我发现我的旧方式使用 post_updated_messages 过滤器钩子,大致相同的方式,所以我也添加:

<?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;
}

第三种解决方案

来自 WP Tavern 的 Otto 的 This answer [mirror] 实际上通过执行 WordPress 本身来克服重定向问题来解决瞬态问题。完全为我工作

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.

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。