Contents
Cómo requerir imagen destacada antes de publicar en WordPress — Tutorial con JS y PHP
Este artículo explica, con todo lujo de detalles, una solución completa y segura para obligar a que las entradas (o tipos de contenido personalizados) tengan una imagen destacada antes de permitir su publicación. La solución contempla dos capas: una comprobación en el cliente (JavaScript) para una experiencia inmediata en el editor (tanto Classic como Gutenberg) y una comprobación en el servidor (PHP) para evitar que cualquier bypass (peticiones REST, APIs externas, plugins, etc.) publique una entrada sin imagen destacada.
Por qué usar las dos capas
- Cliente (JS): proporciona feedback inmediato al usuario y evita acciones repetidas.
- Servidor (PHP): garantiza integridad y seguridad: protege contra publicaciones hechas fuera del editor (REST API, scripts, imports).
Requisitos y consideraciones
- WordPress 5.x (Gutenberg) o editores clásicos el código incluye detección para ambos.
- Acceso para añadir código al tema (functions.php) o crear un pequeño plugin.
- Se mostrará un aviso en el administrador si el servidor cancela la publicación.
- Soporta posts y puede extenderse a cualquier post_type.
Implementación cliente (JavaScript)
La lógica cliente detecta si el editor es Gutenberg o el editor clásico y evita la acción de publicar mostrando un aviso. Para Gutenberg usamos la API de wp.data para detectar intentos de guardado/publicación y crear una notificación. Para el editor clásico interceptamos el envío del formulario o el clic en el botón Publicar.
Código JavaScript (enfilébralo con wp_enqueue_script en admin):
(function() { // Código que funciona tanto en Gutenberg como en Classic if ( typeof wp !== undefined wp.data wp.data.select ) { // Gutenberg var select = wp.data.select var dispatch = wp.data.dispatch var lastIsSaving = select(core/editor).isSavingPost() wp.data.subscribe(function() { try { var isSaving = select(core/editor).isSavingPost() // detecta el inicio de guardado/publicación if (isSaving !lastIsSaving) { var featured = select(core/editor).getEditedPostAttribute(featured_media) if (!featured featured === 0) { // evitar que quede publicado: forzamos a draft y mostramos aviso dispatch(core/editor).editPost({ status: draft }) if (wp.data.dispatch(core/notices)) { wp.data.dispatch(core/notices).createNotice( error, Debe añadir una imagen destacada antes de publicar., { isDismissible: true } ) } else { alert(Debe añadir una imagen destacada antes de publicar.) } } } lastIsSaving = isSaving } catch (e) { // no bloquear ejecuciones si algo falla console.error(Error checking featured image:, e) } }) return } // Editor clásico (fallback) document.addEventListener(DOMContentLoaded, function() { var form = document.getElementById(post) var publishButton = document.getElementById(publish) function hasThumbnailClassic() { // En editor clásico existe un input oculto con id _thumbnail_id var thumbInput = document.getElementById(_thumbnail_id) if (thumbInput) { return thumbInput.value thumbInput.value !== 0 } // fallback: buscar imagen en metabox var img = document.querySelector(#postimagediv .inside img) return !!img } if (form) { form.addEventListener(submit, function(e) { var isPublishing = (publishButton publishButton.value publishButton.value.toLowerCase().indexOf(publish) !== -1) (document.activeElement === publishButton) // Si el usuario está intentando publicar if (isPublishing !hasThumbnailClassic()) { e.preventDefault() alert(Debe añadir una imagen destacada antes de publicar.) // Para mejorar UX, desplazamos hasta el metabox var metabox = document.getElementById(postimagediv) if (metabox) metabox.scrollIntoView({ behavior: smooth }) return false } }, true) } if (publishButton) { publishButton.addEventListener(click, function(e) { if (!hasThumbnailClassic()) { e.preventDefault() alert(Debe añadir una imagen destacada antes de publicar.) var metabox = document.getElementById(postimagediv) if (metabox) metabox.scrollIntoView({ behavior: smooth }) return false } }) } }) })()
Notas prácticas sobre el script:
- Para Gutenberg se usan los paquetes de datos de WP: wp.data.select y wp.data.dispatch. El script crea un aviso con core/notices.
- Para Classic se comprueba el input oculto _thumbnail_id y la presencia de imagen en el metabox.
- El script no impide guardados a borrador ni autosaves sólo evita la publicación final si no hay imagen destacada.
Implementación servidor (PHP)
La comprobación en servidor intercepta el intento de publicar (hook wp_insert_post_data) y, si detecta que el estado pedido es publish y no existe imagen destacada, cambia el estado a draft y añade un parámetro a la URL para mostrar un aviso en el panel.
Código PHP (puedes colocarlo en functions.php o en un plugin):
Publicación cancelada: Es obligatorio establecer una imagen destacada antes de publicar.