15%

Ahorra 15%<\/span> en todos los servicios de hosting

Pon a prueba tus habilidades y obtén Descuento<\/span> en cualquier plan de hosting

Usa el código:

Skills
Comenzar
22.10.2024

Acciones de WordPress Explicadas: La Guía Completa del Desarrollador para la API de Hooks

Las Acciones de WordPress son un componente central de la API de Hooks que permite a los desarrolladores ejecutar funciones personalizadas en puntos precisamente definidos durante el ciclo de vida de la solicitud de WordPress — sin tocar nunca los archivos del núcleo. Cuando se activa un hook de acción, cada función registrada en ese hook se ejecuta en orden de prioridad, lo que permite una personalización modular, mantenible y segura ante actualizaciones.

Si estás creando un plugin, desarrollando un tema o gestionando una instalación de WordPress autoalojada en un entorno de VPS Hosting, dominar las Acciones no es negociable. Son el mecanismo principal mediante el cual el propio WordPress está arquitecturado — no solo una herramienta de extensión para terceros.

Cómo Funcionan Realmente las Acciones de WordPress por Dentro

WordPress mantiene un registro global llamado $wp_filter, que almacena todos los hooks registrados — tanto acciones como filtros. Cuando se llama a do_action(), WordPress busca la entrada de ese hook en $wp_filter, ordena los callbacks registrados por prioridad y los ejecuta secuencialmente.

La distinción crítica que muchos tutoriales pasan por alto: Las Acciones son de tipo “disparar y olvidar”. Ejecutan callbacks pero descartan cualquier valor de retorno. Si necesitas interceptar y modificar datos, ese es el trabajo de los Filtros, no de las Acciones. Confundir ambos es uno de los errores arquitectónicos más comunes en el desarrollo de plugins de WordPress.

El flujo de ejecución es el siguiente:

  1. El núcleo de WordPress (o un plugin/tema) llama a do_action( 'hook_name', ...$args ).
  2. WordPress resuelve todos los callbacks registrados en hook_name desde $wp_filter.
  3. Los callbacks se ordenan por su valor $priority (ascendente — los números más bajos se ejecutan primero).
  4. Cada callback se invoca con los argumentos proporcionados.
  5. Los valores de retorno se ignoran silenciosamente.
  6. La ejecución continúa en el código de origen después de que do_action() retorna.

Esta arquitectura significa que un callback mal escrito registrado en un hook temprano como init puede bloquear toda la solicitud. Siempre perfila los callbacks de hooks en staging antes de desplegarlos en producción.

Registrar Acciones con add_action()

La función add_action() registra un callable de PHP en un hook de acción con nombre. Su firma completa es:

add_action( string $hook_name, callable $callback, int $priority = 10, int $accepted_args = 1 ): true

Parámetros explicados:

    $hook_name — El identificador de cadena exacto del hook de acción (p. ej., wp_login, save_post).
    $callback — Cualquier callable válido de PHP: una función con nombre, una función anónima, un método estático array( 'MyClass', 'method' ), o un método de objeto array( $object, 'method' ).
    $priority — Orden de ejecución relativo a otros callbacks en el mismo hook. Por defecto 10. Los callbacks con la misma prioridad se ejecutan en orden de registro.
    $accepted_args — Cuántos argumentos de do_action() pasar a tu callback. Por defecto 1. Debes configurar esto correctamente o tu callback recibirá listas de argumentos truncadas.
    
    Ejemplo Básico: Engancharse en wp_login
    function notify_admin_on_login( string $user_login, WP_User $user ): void {
        $admin_email = get_option( 'admin_email' );
        $subject     = 'Login Alert: ' . $user_login;
        $message     = sprintf(
            'User "%s" (ID: %d) logged in at %s.',
            $user_login,
            $user->ID,
            current_time( 'mysql' )
        );
        wp_mail( $admin_email, $subject, $message );
    }
    
    // wp_login passes two arguments: $user_login (string) and $user (WP_User object)
    add_action( 'wp_login', 'notify_admin_on_login', 10, 2 );
    Observa que accepted_args está configurado en 2. Omitir esto y dejar el valor predeterminado 1 significa que tu callback recibe solo $user_login y nunca ve el objeto WP_User — un error silencioso que es notoriamente difícil de rastrear.
    Usar Métodos de Objeto y Closures
    El desarrollo moderno de WordPress favorece encapsular la lógica dentro de clases:
    class My_Plugin {
    
        public function __construct() {
            add_action( 'init', array( $this, 'register_post_types' ) );
            add_action( 'save_post', array( $this, 'handle_save' ), 20, 3 );
        }
    
        public function register_post_types(): void {
            register_post_type( 'product', array( /* args */ ) );
        }
    
        public function handle_save( int $post_id, WP_Post $post, bool $update ): void {
            if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
                return;
            }
            // Custom save logic here
        }
    }
    
    new My_Plugin();
    Los closures anónimos también funcionan, pero no pueden eliminarse con remove_action() posteriormente porque PHP no puede comparar de forma fiable referencias a funciones anónimas. Usa métodos con nombre cuando necesites la capacidad de desregistrar.
    Eliminar Acciones con remove_action()
    Puedes desregistrar cualquier callback — incluidos los añadidos por otros plugins o temas — usando remove_action(). La prioridad debe coincidir exactamente con la que se usó en add_action():
    remove_action( 'wp_head', 'wp_generator' ); // Removes WordPress version meta tag
    Para métodos de objeto, necesitas una referencia a la misma instancia del objeto:
    // Inside a plugin that exposes its instance
    global $my_plugin_instance;
    remove_action( 'save_post', array( $my_plugin_instance, 'handle_save' ), 20 );
    Un error común: llamar a remove_action() antes de que el add_action() original haya ejecutado. Siempre engancha tu eliminación en una acción que se active después de que el plugin objetivo se cargue — típicamente plugins_loaded o after_setup_theme.
    Referencia de Hooks de Acción Principales de WordPress
    La siguiente tabla cubre los hooks de acción más significativos operacionalmente, su contexto de activación y sus casos de uso prácticos.
    
    
    
    
    Nombre del Hook
    Se Activa Cuando
    Casos de Uso Típicos
    Args Pasados
    
    
    
    
    muplugins_loaded
    Plugins de uso obligatorio cargados
    Bootstrapping temprano, constantes
    0
    
    
    plugins_loaded
    Todos los plugins cargados
    Verificaciones de compatibilidad entre plugins
    0
    
    
    init
    Después de que WP carga, antes de las cabeceras
    Registrar CPTs, taxonomías, reglas de reescritura
    0
    
    
    wp_loaded
    Después de init, todo cargado
    Registro de REST API, tareas de inicio tardío
    0
    
    
    wp_enqueue_scripts
    Carga de recursos del front-end
    Encolar CSS/JS para temas y plugins
    0
    
    
    wp_head
    Dentro de la etiqueta <head>
    Meta etiquetas, estilos en línea, fragmentos de analítica
    0
    
    
    wp_footer
    Antes de </body>
    Scripts diferidos, píxeles de seguimiento
    0
    
    
    admin_init
    Cargas de páginas de administración
    Registro de Settings API, verificaciones de capacidad
    0
    
    
    admin_enqueue_scripts
    Carga de recursos de administración
    Encolar CSS/JS solo para administración
    1 ($hook_suffix)
    
    
    save_post
    Post guardado o actualizado
    Actualizaciones de meta, sincronización con API externa, notificaciones
    3
    
    
    wp_login
    Usuario se autentica
    Registro de auditoría, gestión de sesiones
    2
    
    
    user_register
    Nuevo usuario creado
    Correos de bienvenida, sincronización con CRM, asignación de roles
    1 ($user_id)
    
    
    wp_logout
    Usuario cierra sesión
    Limpieza de sesión, eventos de analítica
    1 ($user_id)
    
    
    switch_theme
    Cambio de tema activo
    Purga de caché, migración de opciones
    2
    
    
    wp_trash_post
    Post movido a la papelera
    Limpieza de datos relacionados, sincronización externa
    1 ($post_id)
    
    
    rest_api_init
    REST API se inicializa
    Registrar rutas REST personalizadas
    0
    
    
    template_redirect
    Antes de que cargue la plantilla
    Redirecciones, control de acceso
    0
    
    
    
    
    do_action() vs do_action_ref_array(): Cuándo Aplica Cada Uno
    Ambas funciones activan un hook de acción, pero difieren en cómo se pasan los argumentos.
    do_action()
    La función estándar. Los argumentos se pasan por valor — los callbacks reciben copias.
    do_action( 'my_plugin_after_import', $import_id, $result_count, $errors );
    do_action_ref_array()
    Los argumentos se pasan como un array, y los objetos dentro de ese array se pasan por referencia (los objetos PHP siempre son similares a referencias por defecto desde PHP 5). Esto es principalmente útil para compatibilidad con código heredado o cuando necesitas explícitamente que los callbacks muten una estructura de datos compartida.
    $context = array(
        'post_id' => 42,
        'meta'    => array(),
    );
    
    do_action_ref_array( 'my_plugin_process_context', array( &$context ) );
    
    // $context['meta'] may now be populated by hooked callbacks
    Orientación práctica: En PHP moderno (7.4+), la diferencia de comportamiento entre los dos es mínima para objetos. Usa do_action() por defecto. Recurre a do_action_ref_array() solo cuando integres con código heredado que lo espera explícitamente, o cuando necesites que los callbacks muten un valor primitivo (como un entero) pasado por referencia.
    Crear y Documentar Hooks de Acción Personalizados
    Al crear un plugin o tema destinado a ser extendido por otros, debes definir tus propios hooks de acción. Así es como expones una superficie de API sin dar a terceros acceso directo a tus elementos internos.
    /**
     * Fires after a custom import process completes.
     *
     * @since 1.0.0
     *
     * @param int   $import_id    The ID of the completed import batch.
     * @param int   $record_count Total number of records processed.
     * @param array $errors       Array of WP_Error objects, empty on full success.
     */
    do_action( 'my_plugin_import_complete', $import_id, $record_count, $errors );
    Siempre documenta tus hooks con un DocBlock directamente encima de do_action(). Esto es lo que impulsa el generador de documentación para desarrolladores de WordPress y hace que tu plugin sea de nivel profesional. Los desarrolladores de terceros pueden entonces engancharse limpiamente:
    add_action( 'my_plugin_import_complete', function( int $import_id, int $count, array $errors ) {
        if ( ! empty( $errors ) ) {
            // Log errors to an external monitoring service
            error_log( "Import {$import_id} completed with " . count( $errors ) . ' errors.' );
        }
    }, 10, 3 );
    Acciones vs Filtros: Una Comparación Definitiva
    Esta es la distinción conceptual más importante en toda la API de Hooks de WordPress.
    
    
    
    
    Dimensión
    Acciones
    Filtros
    
    
    
    
    Propósito principal
    Ejecutar efectos secundarios en un punto del tiempo
    Interceptar y modificar datos
    
    
    Valor de retorno
    Ignorado completamente
    Debe retornar el valor (modificado)
    
    
    Función principal
    do_action()
    apply_filters()
    
    
    Registro
    add_action()
    add_filter()
    
    
    Uso típico
    Enviar correo, escribir en DB, encolar recursos
    Modificar contenido de posts, alterar argumentos de consulta
    
    
    ¿Puede cortocircuitar?
    No (todos los callbacks siempre se ejecutan)
    No (pero puede retornar anticipadamente dentro del callback)
    
    
    Mutación de datos
    No es el patrón previsto
    Propósito principal
    
    
    
    
    Regla arquitectónica clave: Si estás usando add_filter() pero no retornas un valor desde tu callback, has introducido un error — el valor filtrado se convertirá en null o false dependiendo del contexto. Por el contrario, si estás usando add_action() y dependes de un valor de retorno, estás haciendo un uso incorrecto de la API.
    Conflictos de Prioridad y Orden de Ejecución
    La gestión de prioridades se vuelve crítica en ecosistemas de plugins complejos. Considera un escenario donde WooCommerce, un plugin de caché y tu código personalizado se enganchan en save_post:
    // WooCommerce hooks at priority 10 (default)
    // Your inventory sync needs WooCommerce data to already be saved
    add_action( 'save_post_product', 'sync_inventory_to_erp', 99 );
    
    // A cache purge should happen last, after all data is written
    add_action( 'save_post', 'purge_varnish_cache', 9999 );
    Casos extremos que debes conocer:
    
    Las prioridades negativas son válidas en WordPress. add_action( 'init', 'my_func', -1 ) se activa antes que cualquier cosa en prioridad 0 o 10.
    Misma prioridad, múltiples callbacks — se ejecutan en el orden en que se llamó a add_action(). El orden de carga de plugins (determinado alfabéticamente por nombre de archivo, o plugins Plugin Order) por tanto afecta el comportamiento.
    Hooks recursivos — llamar a do_action() para el mismo hook dentro de un callback de ese hook es técnicamente posible pero crea bucles infinitos. WordPress no protege contra esto.
    Registro tardío de hooks — si llamas a add_action( 'init', ... ) después de que init ya se haya activado, tu callback nunca se ejecutará en esa solicitud. Esta es una fuente frecuente de errores en código que se ejecuta condicionalmente.
    
    Patrones de Producción del Mundo Real
    Patrón 1: Sistema de Eventos Desacoplado
    Usa acciones personalizadas para desacoplar componentes de plugins, evitando llamadas directas a funciones entre módulos:
    // In your order processing module
    do_action( 'my_shop_order_paid', $order_id, $payment_method, $amount );
    
    // In your email module (separate file, no direct dependency)
    add_action( 'my_shop_order_paid', 'send_payment_confirmation_email', 10, 3 );
    
    // In your analytics module (separate file, no direct dependency)
    add_action( 'my_shop_order_paid', 'track_conversion_event', 20, 3 );
    Este patrón significa que puedes deshabilitar el módulo de analítica completamente sin tocar el código de procesamiento de pedidos.
    Patrón 2: Registro Condicional de Hooks
    Evita registrar hooks incondicionalmente en el nivel superior. Limítalos al contexto donde son necesarios:
    add_action( 'admin_init', function() {
        // Only register these hooks in the admin context
        add_action( 'admin_enqueue_scripts', 'my_plugin_admin_assets' );
        add_action( 'save_post', 'my_plugin_validate_custom_fields', 10, 2 );
    } );
    Patrón 3: Acciones de Una Sola Vez con remove_action() Dentro del Callback
    function my_plugin_run_once(): void {
        // Do something that must only happen once per request
        update_option( 'my_plugin_initialized', true );
    
        // Deregister itself to prevent re-execution if the hook fires again
        remove_action( 'wp_loaded', 'my_plugin_run_once' );
    }
    
    add_action( 'wp_loaded', 'my_plugin_run_once' );
    Consideraciones de Rendimiento en Entornos Gestionados
    En instalaciones de WordPress con alto tráfico — ya sea ejecutándose en un plan de VPS Hosting o en un Servidor Dedicado — el costo acumulativo de hooks mal optimizados es medible.
    Herramientas de perfilado a usar:
    
    Plugin Query Monitor: Muestra cada hook que se activó, cada callback que se ejecutó y el tiempo de ejecución por callback.
    Xdebug + KCacheGrind: Para perfilado profundo de rutas de ejecución de callbacks.
    New Relic APM: Para monitoreo de rendimiento de hooks a nivel de producción.
    
    Principios de optimización:
    
    Mueve las operaciones costosas (consultas a base de datos, solicitudes HTTP, E/S de archivos) fuera de hooks que se activan en cada carga de página (init, wp_head) y hacia hooks que se activan solo cuando es necesario (save_post, user_register).
    Usa transients o caché de objetos para memoizar resultados de cálculos costosos dentro de callbacks de hooks.
    Evita registrar cientos de llamadas add_action() incondicionalmente en el momento de carga del plugin. Registra hooks de forma diferida solo cuando la página de administración o el contexto relevante esté activo.
    En servidores con OPcache habilitado (que todos los entornos PHP correctamente configurados deberían tener), la sobrecarga del registro de hooks en sí es insignificante — el costo está en lo que los callbacks *hacen*, no en el registro.
    
    Si gestionas tu propio stack de WordPress, asegurarte de que tu servidor ejecute PHP 8.1+ con OPcache, una caché de bytecode y una caché de objetos como Redis o Memcached tendrá un impacto en el rendimiento mucho mayor que micro-optimizar las prioridades de los hooks.
    Acciones de WordPress en el Contexto del Desarrollo de Plugins y Temas
    Al desarrollar un plugin destinado al repositorio de WordPress.org o distribución comercial, tu uso de la API de Hooks determina directamente la calidad del código y las calificaciones de compatibilidad.
    Mejores prácticas para el uso de hooks de nivel de producción:
    
    Siempre verifica DOING_AUTOSAVE dentro de los callbacks de save_post para evitar ejecutar lógica costosa en autoguardados.
    Verifica nonces y capacidades dentro de cualquier callback de hook que procese datos enviados por el usuario. Nunca confíes en que el hook en sí proporciona seguridad.
    Usa current_action() para determinar qué hook específico activó tu callback cuando la misma función está registrada en múltiples hooks.
    Usa espacios de nombres en tus nombres de hooks personalizados para evitar colisiones: my_plugin_event_name, no event_name.
    Versiona tus hooks en la documentación para que los desarrolladores sepan cuándo se introdujo un hook y cuándo puede quedar obsoleto.
    
    Para equipos que despliegan WordPress en infraestructura con Paneles de Control VPS, mantener entornos de staging que reflejen la producción es esencial para probar de forma segura las interacciones de hooks antes del despliegue.
    Asegurar tu Instalación de WordPress Junto con Acciones Personalizadas
    Los hooks de acción personalizados que procesan datos externos, gestionan eventos de autenticación o interactúan con el sistema de archivos introducen superficie de ataque de seguridad. Combina el desarrollo de tus hooks con un entorno de alojamiento correctamente asegurado.
    Asegúrate de que tu instalación de WordPress use HTTPS — un Certificado SSL es obligatorio para cualquier sitio que gestione autenticación de usuarios o envíos de formularios. Los callbacks de hooks que se activan en wp_login o user_register están procesando datos sensibles a través de la red; sin TLS, esos datos están expuestos independientemente de lo bien que esté escrito tu código PHP.
    Además, si tu plugin usa wp_mail() dentro de callbacks de acción (un patrón común para notificaciones), la configuración y reputación del correo de tu servidor afectan directamente la entregabilidad. Considera una solución dedicada de Alojamiento de Correo con registros SPF, DKIM y DMARC adecuados en lugar de depender del sendmail a nivel de servidor.
    Matriz de Decisión Técnica y Conclusiones Clave
    Usa esta lista de verificación al implementar Acciones de WordPress en cualquier proyecto:
    Registro de hooks:
    
    Establece $accepted_args explícitamente siempre que el hook pase más de un argumento
    Usa valores de prioridad deliberadamente — documenta por qué se eligen prioridades no predeterminadas
    Registra hooks dentro de constructores de clases o métodos register_hooks() dedicados, nunca en el ámbito global de un archivo de plugin
    Limita el registro de hooks al contexto donde es necesario (administración, front-end, REST API)
    
    Implementación de callbacks:
    
    Siempre verifica DOING_AUTOSAVE, DOING_CRON y wp_is_json_request() donde sea relevante
    Verifica nonces con check_admin_referer() o check_ajax_referer() antes de procesar cualquier entrada del usuario
    Nunca dependas de valores de retorno de do_action() — usa filtros si necesitas datos de vuelta
    Usa current_action() cuando un callback sirve a múltiples hooks
    
    Diseño de hooks personalizados:
    
    Usa espacios de nombres en todos los nombres de hooks personalizados con el prefijo de tu plugin/tema
    Documenta cada hook personalizado con un DocBlock completo encima de do_action()
  • Pasa suficientes argumentos para hacer útil el hook sin exponer innecesariamente el estado interno
  • Prefiere do_action() sobre do_action_ref_array() a menos que tengas una razón específica

Rendimiento y mantenimiento:

  • Perfila los callbacks de hooks con Query Monitor antes de desplegar en producción
  • Evita consultas a base de datos dentro de hooks que se activan en cada solicitud
  • Usa remove_action() para limpiar hooks de terceros que entren en conflicto con tu implementación
  • Prueba las interacciones de hooks en un entorno de staging que refleje la infraestructura de producción

Preguntas Frecuentes

¿Cuál es la diferencia entre add_action() y add_filter() en WordPress?

add_action() registra un callback para ejecutar efectos secundarios en un punto específico de la ejecución — el valor de retorno se descarta. add_filter() registra un callback para recibir, modificar y retornar un valor. Usar uno donde el otro es apropiado es un error funcional: un callback de filtro que no retorna un valor anulará los datos filtrados.

¿Por qué no se activa mi callback de add_action()?

Las causas más comunes son: (1) el nombre del hook está mal escrito, (2) add_action() se llama después de que el hook ya se ha activado en la solicitud actual, (3) $accepted_args es demasiado bajo y el callback recibe datos incorrectos causando un error silencioso de PHP, o (4) una verificación condicional dentro del callback está impidiendo la ejecución. Usa Query Monitor para verificar si el hook se activó y si tu callback fue registrado.

¿Puedo usar add_action() dentro de otro callback de acción?

Sí, y este es un patrón común. Por ejemplo, registrar hooks dentro de plugins_loaded o init para asegurar que las dependencias estén disponibles. Sin embargo, el hook interno debe activarse después del externo para que el registro surta efecto.

¿Qué controla realmente el parámetro $priority?

Controla el orden en que se ejecutan múltiples callbacks registrados en el mismo hook. Los números más bajos se activan primero. El valor predeterminado es 10. Los valores válidos incluyen enteros negativos. Cuando dos callbacks comparten la misma prioridad, se ejecutan en el orden en que fueron registrados mediante add_action().

¿Cómo elimino de forma segura una acción añadida por un plugin de terceros?

Engancha tu llamada a remove_action() en una acción que se active después de que el plugin se haya cargado — típicamente plugins_loaded con alta prioridad, o after_setup_theme. Debes coincidir exactamente con el nombre del hook, la referencia del callback y la prioridad usada en la llamada original a add_action(). Para métodos de objeto, necesitas acceso a la misma instancia del objeto, que los plugins de buena reputación exponen a través de una variable global o un método estático get_instance().

15%

Ahorra 15%<\/span> en todos los servicios de hosting

Pon a prueba tus habilidades y obtén Descuento<\/span> en cualquier plan de hosting

Usa el código:

Skills
Comenzar