¿Por qué se dispara la acción save_post al crear una nueva entrada?
Me sorprende el hecho de que mi función, que he enganchado a la acción save_post
, se ejecuta cuando hago clic en el enlace "Nueva entrada" en el Escritorio de WordPress. Nota - esto es antes de presionar Guardar o Actualizar, y se dispara inmediatamente, no después de un tiempo o una actualización automática.
Por otro lado, cuando escribo algo y presiono los botones Publicar, Actualizar o Guardar borrador, la declaración echo que he puesto dentro de mi manejador de acción no se muestra, por lo que parece que la acción NO se dispara en ningún otro momento. Esto puede estar relacionado.
Aquí está mi código:
add_action('save_post', 'MyNS\save_event_metabox', 10, 2);
function save_event_metabox($post_id, $post){
echo "<h1>¡SÍ!</h1>";
}
Este ¡SÍ! se muestra (en la parte superior de la página) cuando presiono el enlace "Nueva entrada", pero NO se muestra cuando escribo algo y luego presiono Actualizar, Publicar o Guardar borrador. Esto parece contradecir la documentación sobre la acción save_post
y la función wp_insert_post()
.
¿Alguien puede aclararme esto?

Cuando haces clic en 'Nueva entrada', simplemente estás cargando la página wp-admin/post-new.php
.
Al hacer esto, WordPress siempre creará una nueva entrada (un 'Borrador automático') para garantizar que todas las demás características (como las subidas de medios) y los plugins funcionen con normalidad, incluso antes de que tú guardes un borrador o publiques la entrada.
Y esto, a su vez, activa save_post
. De ahí tu eco.
Vale, entonces ¿por qué no obtengo un eco al actualizar o publicar?
Entre el guardado y la siguiente carga de página, WordPress en realidad está enviando una redirección GET
de vuelta a la misma página, que parece transparente (puedes presenciar esto con un monitor HTTP, como HttpFox).
En otras palabras;
- Haces clic en
Actualizar
oPublicar
- El navegador envía los datos al servidor
- WordPress los maneja, y en el proceso activa
save_post
- WordPress envía de vuelta una cabecera de redirección, y sale, antes de que ocurra cualquier salida al navegador (incluyendo tu eco)*
- El navegador sigue la redirección y carga la página de 'editar entrada'.
La redirección podría parecer innecesaria (ya que podrías simplemente hacer un POST
a la misma página), pero es parte de una técnica conocida como Post/Redirect/Get para evitar envíos de formularios duplicados.
Si estás intentando imprimir mensajes personalizados basados en el resultado de una función enganchada a save_post
, echa un vistazo a estas preguntas/respuestas.
*No es estrictamente cierto, tu eco de hecho ocurrirá antes de que se envíe la cabecera de redirección, pero el navegador lo descartará, o las cosas sucederán tan rápido que nunca se renderizará.

Excelente. ¡Gracias por una respuesta tan completa y detallada! Con el interés de aprender más, ¿cómo encontraste este conocimiento en primer lugar?

A través de la misma frustración que estabas experimentando ;) Consigue un buen IDE (yo uso phpDesigner) y simplemente sumérgete en los archivos de administración relevantes.

Increíble pieza de información. Me estaba volviendo loco porque en mi servidor local parecía funcionar "bien", pero no en mi servidor de producción... parece que en mi servidor local no estaba aplicando correctamente la técnica post/redirect/get porque no enviaba la cabecera de redirección (aunque no sé por qué).

Gracias por la respuesta, esperaba aprovechar el parámetro $update para determinar si el evento de guardado era el primer evento de guardado o un evento de actualización, pero he aprendido que todos los eventos de guardado manual tendrán $update como verdadero. ¿Es ese el caso? Me pregunto si hay una solución elegante sin comparar estados de publicación que podrían ser dinámicos. (Hasta ahora esta es mi respuesta favorita: https://wordpress.stackexchange.com/a/365727/2798)
