Como crear admin notices personalizados y descartables en PHP en WordPress

Contents

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

  1. Registrar la función que imprime el aviso (hook admin_notices).
  2. Comprobar si el aviso ya está descartado para el usuario (user meta) o globalmente (option).
  3. Encolar un script que envíe la petición AJAX para marcar el aviso como descartado y esconda el DOM del aviso.
  4. Crear el handler AJAX (acción wp_ajax_…) que valide el nonce y actualice user meta / option.
  5. 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

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

Comprobación y pruebas

  1. Probar con varios usuarios para verificar que la persistencia por usuario funciona.
  2. Probar el flujo sin JavaScript (usar navegador con JS desactivado) y verificar el fallback.
  3. Comprobar que nonces inválidos retornan error y que no se graba nada.
  4. 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 🙂



Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *