Come estendere i plugin WordPress con apply_filters e do_action

Quando sviluppiamo un plugin WordPress uno dei nostri obiettivi dovrebbe essere quello di renderlo flessibile ed estensibile da altri sviluppatori.

Come?

Usando gli hook (ganci) che WordPress ci offre: Filter e Action.

Questi hook permettono agli sviluppatori di modificare parti del plugin senza toccare il codice core del plugin stesso.

In questo articolo proveremo a capire come usare gli hooks di WordPress apply_filters e do_action.

Differenza tra Action e Filter

Per prima cosa, qual è la differenza tra action e filter?

Action (do_action) serve a dire agli sviluppatori che possono aggiungere codice personalizzato o fare qualche altra azione in quel punto usando add_action().

La funzione do_action( $hook_name ) invoca tutte le funzioni collegate all’action hook $hook_name.

Filter (apply_filters) serve a modificare un valore prima che venga usato o mostrato.

Altri sviluppatori possono modificare quel valore tramite add_filter() e il filtro restituirà un risultato modificato.

Come usare do_action

Supponiamo di avere un plugin che invia una notifica quando viene creato un nuovo ordine.

Possiamo inserire un hook di tipo Action:

function riaco_crea_ordine( $ordine_id ) {
    // Logica per creare l'ordine
    // ...

    // Eseguiamo l'action per permettere estensioni
    do_action( 'riaco_ordine_creato', $ordine_id );
}

In questo modo, altri sviluppatori potranno agganciarsi così:

add_action( 'riaco_ordine_creato', 'invia_email_cliente', 10, 1 );

function invia_email_cliente( $ordine_id ) {
    // Codice per inviare una email di conferma
}

Con questa semplice riga do_action, abbiamo aperto il nostro plugin a nuove funzionalità senza modificare il core del codice.

Come usare apply_filters

Ora immaginiamo che il nostro plugin mostri un messaggio di conferma ordine.

Se vogliamo permettere ad altri di modificare il messaggio, possiamo usare apply_filters:

function riaco_messaggio_conferma( $ordine_id ) {
    $messaggio = "Il tuo ordine #$ordine_id è stato ricevuto!";
    
    // Applichiamo il filtro
    $messaggio = apply_filters( 'riaco_messaggio_conferma', $messaggio, $ordine_id );

    return $messaggio;
}

Ora, un altro sviluppatore può fare:

add_filter( 'riaco_messaggio_conferma', 'personalizza_messaggio', 10, 2 );

function personalizza_messaggio( $messaggio, $ordine_id ) {
    return "Grazie per aver acquistato con noi! Il tuo ordine #$ordine_id è confermato.";
}

Con questo approccio, abbiamo permesso la personalizzazione del testo senza che l’utente debba modificare direttamente il nostro plugin.

Nominare gli hooks

È buona norma seguire alcune buone pratiche per garantire chiarezza, evitare conflitti e rendere il tuo plugin facilmente estendibile quando dobbiamo creare i nomi per gli hooks.

Scrivi in inglese

Ad oggi la lingua ufficiale per parlare con tutto il mondo è l’inglese.

Scrivi in inglese.

Prefissi unici

Usa un prefisso unico basato sullo slug del tuo plugin o sul namespace del progetto.

Ad esempio per un plugin My Cool Plugin, il prefisso potrebbe essere mcp (ma 3 lettere sono troppe poche, meglio partire da 5) oppure my_cool_plugin.

Ecco il nome di possibili hook adattandoli al codice che abbiamo visto poco fa:

  • do_action( 'mcp_order_created', $order_id );
  • apply_filters( 'mcp_confirmation_message', $message, $order_id );

Struttura dei Nomi

Gli hook dovrebbero seguire una struttura gerarchica e leggibile, spesso in snake_case:

<prefix>_<contesto>_<evento_o_oggetto>

Action

Siccome le action sono usate normalmente quando qualcosa cambia, usa verbi che descrivono quell’evento:

created, updated, deleted, sent, rendered.

Esempi:

  • mcp_cart_item_added: un elemento è stato aggiunto al carrello
  • mcp_order_status_changed: lo stato dell’ordine è cambiato
  • mcp_email_message: filtro sul messaggio email

Se vuoi aggiungere un’azione prima di un evento, aggiungi il prefisso pre_:

do_action( 'mcp_pre_cart_item_added' );

Se vuoi aggiungere un’azione dopo di un evento, usa il verbo al passato:

do_action( 'mcp_cart_item_added' );

Filter

Usa nomi che descrivono un valore che può essere modificato:

message, content, html, subject, url

Esempi:

  • mcp_email_subject
  • mcp_order_total
  • mcp_checkout_redirect_url

    Valida l’output dei filtri

    Quando usi un filtro, non sai mai cosa può tornarti indietro.

    Magari ti aspetti una stringa e ti ritorna un array di stringhe.

    Per questo motivo è molto importante controllare il tipo di risultato ottenuto dal filtro.

    Ad esempio se ti aspetti una stringa, controlla se la variabile è una stringa con is_string().

    function riaco_messaggio_conferma( $ordine_id ) {
        $messaggio = "Il tuo ordine #$ordine_id è stato ricevuto!";
        
        // Applichiamo il filtro
        $messaggio = apply_filters( 'riaco_messaggio_conferma', $messaggio, $ordine_id );
    
        if ( ! is_string( $messaggio ) ) {
          // reimposta il valore o genera un errore
        }
    
        return $messaggio;
    }

    Non abusare degli hook

    Non abusare degli hook: inseriscili solo dove ha senso estendere o modificare.

    Ogni hook (do_action o apply_filters) viene eseguito in runtime, anche se nessuno sviluppatore esterno vi si aggancia.

    Più hook inutili > più chiamate di funzione > maggiore consumo di risorse.

    Gli hook dovrebbero esistere solo dove ha senso dare libertà ad altri sviluppatori di modificare il comportamento.

    • Se un hook non serve a nessuna estensione logica prevedibile, diventa rumore.
    • Mantenere pochi hook significativi rende il plugin chiaro e semplice da leggere.

    Documenta i tuoi hook

    Documenta i tuoi hook così che altri sviluppatori sappiano come usarli.

    Ogni hook dovrebbe essere documentato con PHPDoc, in modo che altri sviluppatori sappiano come usarlo:

    /**
     * Fires when a new order is created.
     *
     * @param int $order_id ID of the created order.
     */
    do_action( 'mcp_order_created', $order_id );
    /**
     * Filters the order confirmation message.
     *
     * @param string $message  Original confirmation message.
     * @param int    $order_id Order ID.
     */
    $message = apply_filters( 'mcp_confirmation_message', $message, $order_id );

    Errori comuni da evitare

    • Non usare nomi generici come order_created o custom_message.
    • Non mischiare CamelCase e snake_case: in WordPress lo standard è snake_case.
    • Non cambiare nomi degli hook tra versioni senza necessità, perché rompe la compatibilità.

    Riassumendo

    L’uso combinato di do_action e apply_filters è fondamentale per creare plugin WordPress modulari ed estendibili.

    • Usa Action per permettere ad altri di aggiungere funzionalità.
    • Usa Filter per permettere di modificare valori senza toccare il codice principale.

    Seguendo queste linee guida, i tuoi plugin saranno più flessibili, aggiornabili e compatibili con l’ecosistema WordPress.

    E chissà, magari un giorno pubblicherai il tuo plugin su wordpress.org.

    Sponsor

    Vhosting
    themeforest