Tengo una función que define un campo personalizado en un tipo de publicación. Digamos que el campo es "subtítulo".
Cuando se guarda la publicación, quiero hacer una validación en la entrada y mostrar un mensaje de error en la pantalla de edición de la publicación si es necesario. Algo como:
// 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);
Estoy tratando de conectar esto a la acción save_post, pero no puedo entender cómo manejar los errores. No parece haber un objeto de error pasado a la función, y si creo mi propio obj WP_Error y lo devuelvo, no se respeta por ningún mecanismo que escupe errores en la página de edición posterior.
Actualmente tengo un mensaje de error en la página dentro de mi metacuadro personalizado, pero esto es menos que ideal: prefiero tener un error grande, rojo y arriba como el que normalmente se muestra WP.
¿Algunas ideas?
ACTUALIZAR:
Según la respuesta de @Denis, probé algunas cosas diferentes. El almacenamiento de errores como global no funcionó, porque Wordpress realiza una redirección durante el proceso save_post, que mata al global antes de que pueda visualizarlo.
Terminé almacenándolos en un metacampo. El problema con esto es que debe eliminarlos, o no desaparecerán cuando navegue a otra página, por lo que tuve que agregar otra función adjunta al admin_footer que simplemente elimina los errores.
No hubiera esperado que el manejo de errores para algo tan común (actualizar publicaciones) fuera tan torpe. ¿Me estoy perdiendo algo obvio o este es el mejor enfoque?
// 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' );
fuente
admin_footer
enganche si elimina los errores al final de su función de controlador de notificaciones. Simplifica las cosas solo un poco.update_option('my_admin_errors', false);
inmediatamente después de la declaración if al final dewpse_5102_admin_notice_handler()
?Respuestas:
Almacene los errores en su clase o como global, posiblemente en un transitorio o meta, y muéstrelos en avisos de administrador en solicitudes POST. WP no cuenta con ningún controlador de mensajes flash.
fuente
Sugiero usar sesiones ya que esto no creará efectos extraños cuando dos usuarios editan al mismo tiempo. Entonces esto es lo que hago:
Las sesiones no se inician con WordPress. Por lo tanto, debe iniciar una sesión en su complemento, functions.php o incluso wp-config.php:
Al guardar la publicación, agregue errores y avisos a la sesión:
Imprima avisos y errores y luego limpie los mensajes en la sesión:
fuente
Basado en la sugerencia de pospi de usar transitorios , se me ocurrió lo siguiente. El único problema es que no hay gancho para poner el mensaje debajo de donde van otros mensajes, así que tuve que hacer un hack de jQuery para llegar allí.
h2
Primero, guarde el mensaje de error durante su
save_post
controlador (o similar) Le doy una corta vida útil de 60 segundos, por lo que está allí el tiempo suficiente para que ocurra la redirección.Luego, solo recupere ese mensaje de error en la siguiente página cargada y muéstrelo. También lo elimino para que no se muestre dos veces.
Dado que se
admin_notices
dispara antes de que se genere el contenido de la página principal, el aviso no es donde van los otros mensajes de edición de publicación, por lo que tuve que usar este jQuery para moverlo allí:Dado que la ID de la publicación es parte del nombre transitorio, esto debería funcionar en la mayoría de los entornos multiusuario, excepto cuando varios usuarios están editando simultáneamente la misma publicación.
fuente
acme_plugin_error_msg_POSTID
. Se podía añadir ID de usuario para que al igual queacme_plugin_error_msg_POSTID_USERID
.Cuando se
save_post
ejecuta, ya ha guardado la publicación en la base de datos.Mirando el código central de WordPress, más específicamente en la función de
wp-includes/post.php
's'update_post()
, no hay una forma integrada de interceptar una solicitud antes de que se guarde en la base de datos.Sin embargo, podemos conectar
pre_post_update
y usarheader()
yget_post_edit_link()
para evitar que se guarde la publicación.Si desea notificar al usuario qué salió mal, consulte esta información general: https://gist.github.com/Luc45/09f2f9d0c0e574c0285051b288a0f935
fuente
¿Por qué no valida su campo con la ayuda de algunos Javascript? Creo que este sería el mejor enfoque para esto.
fuente
Intentando usar el script anterior, me encontré con un extraño problema. Se muestran dos mensajes en la pantalla de edición, después de la actualización posterior. Uno muestra el estado del contenido de guardar anterior y otro del actual. Por ejemplo, si guardo la publicación correctamente y luego cometo un error, el primero es "error" y el segundo es "ok", aunque se generan al mismo tiempo. Si cambio la secuencia de comandos y agrego solo un mensaje (p. Ej., "Error"), inicie una actualización con "error" y después de esa otra con "ok", el mensaje "error" permanece (se muestra por segunda vez). Debo guardar con "ok" una vez más para deshacerme de él. Realmente no sé qué está mal, lo he probado en tres servidores locales diferentes y hay el mismo problema en cada uno de ellos.
fuente
He escrito un complemento que agrega un manejo rápido de errores para las pantallas de edición de publicaciones y evita que se publiquen publicaciones hasta que se completen los campos obligatorios:
https://github.com/interconnectit/required-fields
Le permite hacer obligatorios todos los campos de publicación, pero puede usar la API que proporciona para hacer que los campos personalizados también sean necesarios con un mensaje de error personalizable y una función de validación. El valor predeterminado es verificar si el campo está vacío o no.
fuente