Introducción
En este tutorial detallado aprenderás a crear admin notices personalizados y descartables (dismissible) en WordPress usando PHP y JavaScript. Veremos cómo hacer que el aviso sea persistente por usuario (almacenado en user meta), cómo protegerlo con nonces y permisos, cómo ofrecer un comportamiento sin JavaScript (fallback) y cómo gestionar varios avisos identificables. El objetivo es que puedas reutilizar el patrón en plugins o themes con buenas prácticas de seguridad y compatibilidad.
Decisiones de diseño y consideraciones
- Alcance: por usuario (user meta) o global (option). En el tutorial cubrimos ambos.
- Persistencia: persistente hasta que el usuario lo descarta también mostraremos cómo usar expiración temporal con transients.
- Accesibilidad y fallback: operará con JavaScript y tendrá un fallback que use un parámetro en la URL para entornos sin JS.
- Seguridad: comprobación de capacidades, nonces, sanitización y escaping.
Esquema de implementación
- Registrar la función que imprime el aviso (hook admin_notices).
- Comprobar si el aviso ya está descartado para el usuario (user meta) o globalmente (option).
- Encolar un script que envíe la petición AJAX para marcar el aviso como descartado y esconda el DOM del aviso.
- Crear el handler AJAX (acción wp_ajax_…) que valide el nonce y actualice user meta / option.
- Agregar un fallback sin JavaScript que use un parámetro en la URL y actualice el mismo dato.
Ejemplo completo paso a paso
1) Mostrar el aviso (por usuario) y comprobar si ya fue descartado
En este ejemplo usamos un notice_id que identifica el aviso (p.ej. welcome2025). Consultamos user meta myplugin_dismissed_notices que será un array de ids descartados.
echo Bienvenido a MyPlugin: Explora las nuevas funciones disponibles.
// Botón alternativo para usuarios sin JS (fallback)
dismiss_url = add_query_arg( array(
myplugin_dismiss_notice => notice_id,
myplugin_dismiss_nonce => nonce,
), wp_get_referer() ? wp_get_referer() : admin_url() )
echo Descartar este aviso
echo
}
?>
2) Encolar script y pasar variables (nonce y action)
El script escucha el clic en el botón de cerrar (la X del notice), llama vía AJAX a admin-ajax.php y, si todo va bien, solo oculta el aviso del DOM. La persistencia se gestiona en el lado servidor.
admin_url( admin-ajax.php ),
action => myplugin_dismiss_notice,
// No enviamos nonce aquí por cada notice se generará por notice en el HTML y lo leeremos desde dataset o atributo data
)
)
}
?>
3) Script JavaScript que maneja el clic de cerrar y envía la petición AJAX
Este script detecta clicks en avisos que tengan la clase myplugin-notice. Busca el notice-id y el nonce (si lo pusimos como atributo data-nonce o lo derivamos desde el enlace de fallback).
(function(){
(document).on(click, .myplugin-notice .notice-dismiss, .myplugin-notice .notice-dismiss-button, .myplugin-notice .button-dismiss, function(e){
// Modo genérico: buscar el contenedor .myplugin-notice más cercano
var notice = (this).closest(.myplugin-notice)
var noticeId = notice.data(notice-id)
// Intentar obtener nonce desde un atributo data-nonce (si lo has impreso)
var nonce = notice.data(nonce) null
// Si no hay nonce en el elemento, intentar tomarlo del enlace de fallback
if (!nonce) {
var href = notice.find(a[href=myplugin_dismiss_nonce]).attr(href)
if (href) {
var match = href.match(/myplugin_dismiss_nonce=([^] )/)
if (match) nonce = decodeURIComponent(match[1])
}
}
// Petición AJAX para marcar como descartado
if (noticeId) {
.post(MyPluginNotice.ajax_url, {
action: MyPluginNotice.action,
notice_id: noticeId,
nonce: nonce
}, function(response){
// En caso de éxito o fallo, ocultar el aviso en la interfaz
notice.slideUp(200, function(){ notice.remove() })
})
} else {
// Si no hay notice id, ocultar igualmente
notice.slideUp(200, function(){ notice.remove() })
}
})
// Alternativamente, escuchar el evento click en la X generada por WP (is-dismissible)
(document).on(click, .myplugin-notice.is-dismissible .notice-dismiss, function(){
(this).trigger(click) // reenviar al handler anterior
})
})(jQuery)
4) Handler AJAX en PHP para marcar el aviso descartado
Validamos el nonce (si hay), y actualizamos user meta agregando el notice_id al array de avisos descartados.
5) Fallback sin JavaScript (parámetro en la URL)
Si el usuario hace clic en el enlace Descartar este aviso, llegamos con dos parámetros: myplugin_dismiss_notice y myplugin_dismiss_nonce. Procesamos eso en un hook temprano en admin init para marcarlo descartado y redirigir para limpiar la URL.
6) Modelo para avisos globales (descartar para todos los usuarios)
En lugar de user meta, puedes usar una option para almacenar avisos descartados globalmente. Ten en cuenta que esto requiere permisos adecuados (sólo admins) y potencialmente protección adicional si varios admins intervienen.
Buenas prácticas de seguridad y rendimiento
- Nonces: generan protección contra CSRF valídalos siempre que los recibas.
- Escapado: usa esc_html, esc_attr, esc_url para cualquier salida en HTML.
- Capacidades: sólo mostrar avisos y aceptar peticiones de usuarios con las capacidades apropiadas.
- Evitar llamadas en exceso: cachear comprobaciones costosas (transients / opciones) si necesitas chequear datos remotos.
- Concurrencia: al escribir opciones/globales, piensa en concurrencia para user meta normalmente no hay problema.
Tabla comparativa: user meta vs option
Alcance |
Persistencia |
Uso recomendado |
user meta |
Por usuario |
Notices que cada usuario puede descartar individualmente (preferido para mensajes UX) |
option |
Global |
Mensajes globales que se deben remover para todos (p.ej. notif. de mantenimiento) |
Consejos adicionales y personalización
- Usa distintos estilos CSS (clases adicionales) para distinguir tipos de aviso: notice-success, notice-warning, notice-error y notice-info.
- Permite que los avisos expiren usando transients: guarda la fecha de expiración y no muestres avisos caducados.
- Si necesitas múltiples avisos, mantén una estructura de datos: array asociativo con keys = notice_id y valores con metadatos (fecha, nivel, mensaje).
- Registrar logs de quién descartó qué aviso puede ser útil en entornos multi-admin. Considera almacenar un registro en option o custom table.
Comprobación y pruebas
- Probar con varios usuarios para verificar que la persistencia por usuario funciona.
- Probar el flujo sin JavaScript (usar navegador con JS desactivado) y verificar el fallback.
- Comprobar que nonces inválidos retornan error y que no se graba nada.
- Verificar compatibilidad con otros plugins que también usen admin_notices para evitar colisiones de clases CSS/JS.
Resumen
Crear admin notices descartables en WordPress implica mostrar el HTML del aviso, almacenar la preferencia del usuario (o globalmente), encolar JavaScript para disparar la petición AJAX y tener un fallback sin JS. Protege siempre las acciones con nonces y revisa capacidades antes de permitir que alguien descarte un aviso global. Con el patrón mostrado puedes crear avisos reutilizables, multi-id y seguros para tu plugin o theme.
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂
|
¡Si te ha servido el artículo ayúdame compartiendolo en algún sitio! Pero si no te ha sido útil o tienes dudas déjame un comentario! 🙂
Relacionado