问题描述
我有一个函数定义一个 post 类型的自定义字段。说领域是”subhead” 。
保存帖子后,我想对输入进行一些验证,并在必要时在后编辑屏幕上显示错误消息。就像是:
// Handle post updating
function wpse_update_post_custom_values($post_id, $post) {
// Do some checking...
if($_POST['subhead'] != 'value i expect') {
// Add an error here
$errors->add('oops', 'There was an error.');
}
return $errors;
}
add_action('save_post','wpse_update_post_custom_values',1,2);
我试图将它挂钩到 save_post 操作,但我无法弄清楚如何处理错误。似乎没有错误的对象传递到该函数,如果我创建我自己的 WP_Error 对象并返回它,它不被任何机制抛出错误在后编辑页面被尊重。
我目前在我的自定义元框中有一个 on-page 错误消息,但这不太理想 – 我想要一个大的,红色的,up-at-the-top 错误,如 WP 通常显示。
有任何想法吗?
更新:
基于 @Denis 的答案,我尝试了几件不同的事情。将错误作为全局存储不起作用,因为 WordPress 在 save_post 进程中执行重定向,这会在显示之前杀死全局。
我最终把它们存储在一个元领域。这样做的问题是,您需要清除它们,或者当您导航到另一个页面时,它们不会消失,所以我不得不添加附加到 admin_footer 的另一个功能,只是清除错误。
我不会预料到这样常见的错误处理 (更新帖子) 将是这个笨重的。我缺少一些明显的东西,还是最好的方法?
// Handle post updating
function wpse_5102_update_post_custom_values($post_id, $post) {
// To keep the errors in
$errors = false;
// Do some validation...
if($_POST['subhead'] != 'value i expect') {
// Add an error here
$errors .= 'whoops...there was an error.';
}
update_option('my_admin_errors', $errors);
return;
}
add_action('save_post','wpse_5102_update_post_custom_values',1,2);
// Display any errors
function wpse_5102_admin_notice_handler() {
$errors = get_option('my_admin_errors');
if($errors) {
echo '<div class="error"><p>' . $errors . '</p></div>';
}
}
add_action( 'admin_notices', 'wpse_5102_admin_notice_handler' );
// Clear any errors
function wpse_5102__clear_errors() {
update_option('my_admin_errors', false);
}
add_action( 'admin_footer', 'wpse_5102_clear_errors' );
最佳解决方案
存储您的课程中的错误或作为全局的错误,可能是暂时的或元数据,并在 POST 请求的管理通知中显示。 WP 不具有任何 Flash 消息处理程序。
次佳解决方案
我建议使用会话,因为这两个用户在同一时间编辑时不会产生奇怪的影响。所以这就是我所做的:
会话不是由 wordpress 开始的。所以你需要在你的插件 start a session ,functions.php 甚至 wp-config.php:
if (!session_id())
session_start();
保存帖子时,会将错误和通知附加到会话中:
function my_save_post($post_id, $post) {
if($something_went_wrong) {
//Append error notice if something went wrong
$_SESSION['my_admin_notices'] .= '<div class="error"><p>This or that went wrong</p></div>';
return false; //might stop processing here
}
if($somthing_to_notice) { //i.e. successful saving
//Append notice if something went wrong
$_SESSION['my_admin_notices'] .= '<div class="updated"><p>Post updated</p></div>';
}
return true;
}
add_action('save_post','my_save_post');
打印通知和错误,然后清除会话中的消息:
function my_admin_notices(){
if(!empty($_SESSION['my_admin_notices'])) print $_SESSION['my_admin_notices'];
unset ($_SESSION['my_admin_notices']);
}
add_action( 'admin_notices', 'my_admin_notices' );
第三种解决方案
基于 pospi 的 suggestion 使用 transients,我想出了以下几点。唯一的问题是没有钩子将消息放在 h2
下面的其他消息去,所以我不得不做一个 jQuery 的黑客得到它在那里。
首先,保存 save_post
(或类似) 处理程序的错误消息。我给它一个短暂的 60 秒的生命周期,所以它只有足够长的重定向发生。
if($has_error)
{
set_transient( "acme_plugin_error_msg_$post_id", $error_msg, 60 );
}
然后,只需在下一页加载并检索该错误消息即可。我也删除它,所以它不会显示两次。
add_action('admin_notices', 'acme_plugin_show_messages');
function acme_plugin_show_messages()
{
global $post;
if ( false !== ( $msg = get_transient( "acme_plugin_error_msg_{$post->ID}" ) ) && $msg) {
delete_transient( "acme_plugin_error_msg_{$post->ID}" );
echo "<div id="acme-plugin-message" class="error below-h2"><p>$msg</p></div>";
}
}
由于 admin_notices
在主页内容生成之前触发,所以通知不在其他帖子编辑消息的位置,所以我不得不使用这个 jQuery 来移动它:
jQuery('h2').after(jQuery('#acme-plugin-message'));
由于帖子 ID 是临时名称的一部分,所以在大多数 multi-user 环境中都应该有效,除非多个用户同时编辑同一个帖子。
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。