Si alguna vez te has preguntado cómo es posible que un plugin modifique el comportamiento de WordPress sin tocar ni una línea de su código fuente, la respuesta está en los hooks de WordPress. Los hooks (ganchos, en español) son el mecanismo de extensión sobre el que se construye todo el ecosistema: temas, plugins y hasta el propio núcleo los usan constantemente para insertar funcionalidad o alterar datos en puntos concretos de la ejecución. Entenderlos es la frontera que separa a quien copia y pega fragmentos de código de quien realmente sabe qué está haciendo con su web. En esta guía vamos a ver qué son exactamente los actions y los filters, en qué se diferencian, cómo usarlos con ejemplos reales y funcionales, cómo controlar prioridades y argumentos, y cómo crear tus propios hooks para que tu código también sea extensible. Todo con código PHP probado que puedes adaptar a tu proyecto hoy mismo.
Qué son los hooks de WordPress y por qué existen
WordPress se diseñó desde el principio con una regla de oro: nunca modificar el núcleo. Si cada desarrollador editase los archivos de wp-includes para cambiar un comportamiento, cada actualización borraría esos cambios y mantener una web sería una pesadilla. La solución fue sembrar el código del núcleo con miles de puntos de enganche: momentos concretos de la ejecución en los que WordPress se detiene un instante y pregunta «¿alguien quiere hacer algo aquí?».
Eso es un hook: un punto de extensión con nombre propio. Cuando WordPress carga una página ejecuta, en orden, hooks como init, wp_loaded, template_redirect o wp_head. Tu código puede «engancharse» a cualquiera de ellos registrando una función de callback, y WordPress la ejecutará en ese momento exacto sin que tengas que tocar nada más.
El sistema descansa sobre dos familias:
- Actions (acciones): eseguono codice in un dato momento. Non restituiscono nulla; servono per fare cose (inviare un'email, mettere in coda uno script, registrare un tipo di post).
- Filtri: ricevono un dato, lo modificano e lo restituiscono. Servono per transformar informazioni (cambiare il testo di un estratto, alterare un titolo, modificare una query).
Questa distinzione è la prima domanda che dovresti farti di fronte a qualsiasi hook: sto facendo qualcosa o sto modificando qualcosa?
Azioni: eseguire codice al momento giusto
Un'azione si registra con add_action(), che necessita di almeno due parametri: il nome dell'hook e la funzione che vuoi eseguire. Vediamo l'esempio classico, caricare un foglio di stile nel modo corretto:
<?php
function biblioweb_cargar_estilos() {
wp_enqueue_style(
'biblioweb-personalizado',
get_stylesheet_directory_uri() . '/css/personalizado.css',
array(),
'1.0.0'
);
}
add_action( 'wp_enqueue_scripts', 'biblioweb_cargar_estilos' );
Qui diciamo a WordPress: «quando arriva il momento di mettere in coda script e stili del frontend (wp_enqueue_scripts), esegui la mia funzione». Un altro esempio molto comune è reagire a un evento, come inviare un avviso quando viene pubblicato un articolo:
<?php
function biblioweb_avisar_publicacion( $post_id, $post ) {
// Evitamos revisiones y autoguardados.
if ( wp_is_post_revision( $post_id ) ) {
return;
}
$asunto = 'Nueva entrada publicada: ' . $post->post_title;
$mensaje = 'Se ha publicado una entrada. Revísala aquí: ' . get_permalink( $post_id );
wp_mail( 'editor@tudominio.com', $asunto, $mensaje );
}
add_action( 'publish_post', 'biblioweb_avisar_publicacion', 10, 2 );
Osserva gli ultimi due parametri di add_action(): il 10 è la priorità e il 2 indica quanti argomenti accetta la nostra funzione. Li vedremo in dettaglio più avanti, perché sono la causa del 90% degli errori con gli hook.
Azioni indispensabili da conoscere
init: WordPress è già caricato; qui si registrano custom post types, tassonomie e shortcode.wp_enqueue_scripts: punto corretto per mettere in coda CSS e JS del frontend.admin_inityadmin_menu: equivalenti per l'area di amministrazione.wp_headywp_footer: stampano contenuto nel<head>e prima di chiudere il<body>.save_post: si attiva al salvataggio di qualsiasi articolo; ideale per elaborare metadati.wp_loginyuser_register: reagiscono all'inizio della sessione e alla registrazione degli utenti.
Filtri: modificare i dati prima che vengano usati
Un filtro funziona come un'azione con una differenza cruciale: la tua funzione riceve un valore e deve restituirlo, modificato o meno. Se dimentichi il return, il dato arriva vuoto a destinazione e romperai qualcosa (estratti vuoti, titoli scomparsi…). È l'errore più comune quando si inizia con gli hook di WordPress.
Esempio reale: cambiare la lunghezza dell'estratto e il testo di «leggi di più»:
<?php
function biblioweb_longitud_extracto( $longitud ) {
return 30; // palabras
}
add_filter( 'excerpt_length', 'biblioweb_longitud_extracto' );
function biblioweb_leer_mas( $more ) {
return '… <a href="' . esc_url( get_permalink() ) . '">Seguir leyendo</a>';
}
add_filter( 'excerpt_more', 'biblioweb_leer_mas' );
Un altro caso molto utile: aggiungere automaticamente un avviso alla fine del contenuto di ogni articolo, solo nel frontend:
<?php
function biblioweb_nota_final( $content ) {
if ( is_singular( 'post' ) && in_the_loop() && is_main_query() ) {
$nota = '<p class="nota-final">¿Te ha resultado útil? Compártelo o déjanos un comentario.</p>';
return $content . $nota;
}
return $content;
}
add_filter( 'the_content', 'biblioweb_nota_final' );
Osserva i controlli condizionali: the_content si applica in molti contesti (feed, widget, pagine), e filtrare senza condizioni finisce per mostrare la tua nota dove non dovrebbe. Restituire sempre $content alla fine, anche se non lo modifichi, è obbligatorio.
Filtri che userai più e più volte
the_contentythe_title: il corpo e il titolo degli articoli.excerpt_lengthyexcerpt_more: controllo dell'estratto.body_class: aggiunge classi CSS a<body>.upload_mimes: permette (o blocca) tipi di file nella libreria media.wp_mail_fromywp_mail_from_name: mittente delle email di WordPress.login_errors: messaggio di errore del login (utile per non dare indizi agli attaccanti).
Priorità e argomenti: i due numeri che cambiano tutto
Tanto add_action() come add_filter() accettano quattro parametri:
add_filter( 'nombre_del_hook', 'mi_funcion', $prioridad, $num_argumentos );
| Parametro | Valore predefinito | Cosa controlla |
|---|---|---|
| Priorità | 10 | L'ordine di esecuzione: numero più basso, viene eseguito prima. Con la stessa priorità, vince quello che è stato registrato per primo. |
| N. di argomenti | 1 | Quanti parametri dell'hook riceve la tua callback. Se l'hook ne passa 3 e tu ne dichiari 1, riceverai solo il primo. |
La priorità conta quando più plugin toccano lo stesso dato. Se il tuo filtro su the_content deve essere eseguita dopo che un altro plugin ha fatto il suo, usa una priorità alta (per esempio 99). Se hai bisogno di anticipare tutti, usa 1. Il numero di argomenti, d'altra parte, deve coincidere con ciò che dichiari nella firma della tua funzione: se metti 10, 3 ma la tua funzione accetta un solo parametro, PHP lancerà un errore fatale.
Per sganciare una funzione esiste remove_action() y remove_filter(), con una condizione stretta: bisogna passare esattamente lo stesso nome di funzione e la stessa priorità con cui è stata registrata:
<?php
// Quitar el generador de versión del head (lo añade el core con prioridad por defecto).
remove_action( 'wp_head', 'wp_generator' );
Come creare i tuoi hook personalizzati
Qui c'è il salto di livello: oltre a consumare hook, puoi crearli. Se sviluppi un tema o un plugin, seminare il tuo codice con do_action() y apply_filters() permette ad altri (o a te stesso, in futuro) di estenderlo senza toccarlo. Così funziona WooCommerce, ed è per questo che il suo ecosistema è gigante.
Un'action propria si crea con do_action():
<?php
// En tu plugin, tras procesar un pedido de ejemplo:
function biblioweb_procesar_solicitud( $solicitud_id ) {
// ... lógica principal ...
// Punto de extensión: cualquiera puede engancharse aquí.
do_action( 'biblioweb_solicitud_procesada', $solicitud_id );
}
// Otro desarrollador (u otro archivo) se engancha:
add_action( 'biblioweb_solicitud_procesada', function ( $solicitud_id ) {
error_log( 'Solicitud procesada: ' . $solicitud_id );
} );
E un filter proprio, con apply_filters(), che definisce il valore predefinito e lo offre a chiunque voglia cambiarlo:
<?php
function biblioweb_obtener_limite() {
$limite = 25;
// Nombre del filtro, valor por defecto y argumentos extra opcionales.
return apply_filters( 'biblioweb_limite_resultados', $limite );
}
// Cualquier otro código puede ajustarlo sin tocar tu función:
add_filter( 'biblioweb_limite_resultados', function ( $limite ) {
return 50;
} );
Due buone pratiche: prefissa sempre i tuoi hook con il nome del tuo progetto per evitare collisioni, e documenta quali argomenti passa ciascuno. Un hook non documentato è un hook che nessuno userà.
Dove posizionare il codice dei tuoi hook
Hai tre opzioni ragionevoli, dalla meno alla più raccomandabile a seconda del caso:
- Il functions.php di un tema figlio: valido per impostazioni legate al design (estratti, classi del body). Se cambi tema, li perdi.
- Un plugin di snippet: l'opzione più comoda per la maggior parte. Strumenti come WPCode, il gestore di snippet che analizziamo a fondo, ti permettono di attivare e disattivare ogni frammento separatamente, con validazione della sintassi che evita di far cadere il sito per un punto e virgola.
- Un plugin proprio: la cosa giusta per funzionalità che devono sopravvivere al tema: custom post types, integrazioni, logica di business.
Ciò che non devi mai fare è modificare il functions.php del tema padre né, ovviamente, i file del core. Se stai iniziando e non controlli ancora i plugin essenziali per iniziare con WordPress, inizia da lì prima di metterti con il codice.
Errori comuni quando si lavora con gli hook
- Dimenticare il return in un filter. Il sintomo tipico: contenuti o titoli che scompaiono. Ogni filter restituisce sempre un valore.
- Agganciarsi troppo presto. Se chiami funzioni utente prima di
inito a funzioni di template prima diwp, otterrai errori o valori vuoti. Ogni hook ha il suo momento nel ciclo di caricamento. - Non dichiarare gli argomenti. Registrare
add_action( 'save_post', 'mi_funcion', 10, 3 )con una funzione che accetta un solo parametro provoca un errore fatale in PHP 8. - Loop infiniti. Chiamare
wp_update_post()all'interno di un callback disave_postriattivasave_post. Si evita rimuovendo l'hook prima di aggiornare e riaggiungendolo dopo. - Callback anonimi che poi non puoi rimuovere. Le funzioni anonime sono comode, ma
remove_filter()non può rimuoverle facilmente. Per codice che altri devono poter disattivare, usa funzioni con nome.
Per esplorare quali hook esistono e quali argomenti passano, la referenza ufficiale di developer.wordpress.org sugli hook è la mappa definitiva: include l'elenco completo di actions e filters del core con la loro documentazione.
Preguntas frecuentes
Qual è la differenza reale tra un'action e un filter?
Un'action esegue codice in un punto del flusso e non restituisce nulla: serve per fare cose. Un filter riceve un dato, può modificarlo ed è obbligato a restituirlo: serve per trasformare informazioni. Internamente entrambi usano lo stesso sistema (infatti add_action() chiama add_filter()), ma concettualmente conviene trattarli come strumenti distinti.
Posso usare gli hook senza saper programmare?
Puoi usare frammenti già scritti copiandoli in un plugin di snippet come WPCode, che valida la sintassi prima di salvare. Tuttavia, capire almeno cosa fa ogni riga ti eviterà di incollare codice dannoso o obsoleto. Gli hook di WordPress sono PHP: una base minima ti darà molta autonomia.
Quanti hook ha WordPress?
Il core supera i 3.000 tra actions e filters, e il numero cresce ad ogni versione. A questi si aggiungono quelli registrati dai tuoi plugin e dal tuo tema: WooCommerce, per esempio, ne aggiunge centinaia propri. Non è necessario memorizzarli: basta conoscere la dozzina abituale e saper cercare il resto nella documentazione ufficiale.
Gli hook influiscono sulle prestazioni del mio sito web?
Il sistema in sé è molto efficiente; ciò che penalizza è ciò che fai all'interno del callback. Una query pesante collegata a init verrà eseguito ad ogni caricamento di pagina. Collega il tuo codice all'hook più specifico possibile e usa condizionali per uscire presto quando non è il momento di agire.
Conclusión
Gli hook di WordPress sono il linguaggio con cui comunicano il core, i temi e i plugin. Dominare la coppia actions e filters ti permette di personalizzare praticamente qualsiasi comportamento senza toccare il codice sorgente e senza paura degli aggiornamenti: mettere in coda risorse, reagire a eventi, trasformare contenuti e, quando farai il salto allo sviluppo, offrire i tuoi punti di estensione con do_action() y apply_filters(). Inizia riproducendo gli esempi di questa guida in un ambiente di test o tramite un gestore di snippet, presta attenzione alle priorità e al return dei filtri, e consulta la documentazione ufficiale quando hai dubbi su quali argomenti passi un hook. Da lì in poi, ogni problema di personalizzazione che incontrerai in WordPress avrà quasi sempre la stessa risposta: c'è un hook per questo.