web analytics

Hook WordPress: Azioni e Filter per Plugin Professionali

21/03/2026

Contenuto articolo

Hook WordPress: Azioni e Filter per Plugin Professionali

Guida Completa 2026 per Sviluppatori WordPress


🎯 Introduzione

Gli hook sono il cuore pulsante di WordPress. Se vuoi sviluppare plugin professionali, temi child avanzati o semplicemente personalizzare il tuo sito senza modificare i file core, devi padroneggiare questo sistema.

In questa guida scoprirai:

  • ✅ La differenza tra Actions e Filters
  • 30+ esempi pratici pronti all'uso
  • ✅ Le best practice per hook sicuri ed efficienti
  • ✅ Come intercettare eventi e modificare contenuti dinamicamente
  • ✅ Gli hook essenziali che ogni sviluppatore deve conoscere

Prerequisiti: Conoscenza base di PHP e WordPress

Tempo di lettura: 15-20 minuti


📚 Cosa Sono gli Hook WordPress?

Definizione

Un hook è un punto di aggancio nel codice di WordPress che ti permette di eseguire il tuo codice personalizzato in momenti specifici del ciclo di vita di WordPress.

Perché Sono Importanti?

Vantaggio Descrizione
Non Invasivo Non modifichi mai i file core di WordPress
Aggiornamenti Sicuri Puoi aggiornare WordPress senza perdere le tue modifiche
Modulare Ogni funzionalità è isolata e indipendente
Estensibile Altri sviluppatori possono estendere il tuo lavoro

I Due Tipi di Hook

// 1. ACTIONS - Eseguono codice in un momento specifico
do_action('nome_hook', $param1, $param2);
add_action('nome_hook', 'tua_funzione', $priority, $accepted_args);

// 2. FILTERS - Modificano e restituiscono dati
apply_filters('nome_hook', $value, $param1);
add_filter('nome_hook', 'tua_funzione', $priority, $accepted_args);

⚡ Actions vs Filters: La Differenza Chiave

Actions (Azioni)

Cosa fanno: Eseguono codice quando succede qualcosa.

Quando usarle:

  • Inviare email
  • Scrivere nel database
  • Inviare notifiche
  • Caricare script e stili
  • Registrare custom post type

Esempio:

// Esegue una funzione quando un post viene pubblicato
add_action('publish_post', 'invia_notifica_social', 10, 2);

function invia_notifica_social($ID, $post) {
    // Codice per inviare notifica ai social
    error_log('Post pubblicato: ' . $post->post_title);
}

Filters (Filtri)

Cosa fanno: Modificano dati e restituiscono il valore modificato.

Quando usarli:

  • Modificare contenuti prima del display
  • Cambiare titoli dinamicamente
  • Alterare query del database
  • Personalizzare excerpt

Esempio:

// Aggiunge testo alla fine di ogni contenuto
add_filter('the_content', 'aggiungi_firma_articolo');

function aggiungi_firma_articolo($content) {
    if (is_single()) {
        $content .= '<p class="firma">📝 Articolo scritto da Mario Rossi</p>';
    }
    return $content; // ⚠️ IMPORTANTE: devi restituire il valore!
}

Tabella Comparativa

Caratteristica Actions Filters
Scopo Eseguire azioni Modificare dati
Return Non necessario OBBLIGATORIO
Funzione do_action() apply_filters()
Registrazione add_action() add_filter()
Esempio Invio email Modifica titolo

🔥 30+ Esempi Pratici di Hook Essenziali

📌 Hook per Plugin Development

1. Inizializzazione Plugin

// Eseguito dopo che WordPress è caricato
add_action('init', 'mio_plugin_init');

function mio_plugin_init() {
    // Carica traduzioni
    load_plugin_textdomain('mio-plugin', false, dirname(plugin_basename(__FILE__)) . '/languages');

    // Registra custom post type
    register_post_type('progetto', array(
        'public' => true,
        'label' => 'Progetti'
    ));
}

2. Attivazione Plugin

// Eseguito quando il plugin viene attivato
register_activation_hook(__FILE__, 'mio_plugin_attiva');

function mio_plugin_attiva() {
    // Crea tabelle database
    global $wpdb;
    $table_name = $wpdb->prefix . 'mio_plugin_dati';

    $charset_collate = $wpdb->get_charset_collate();

    $sql = "CREATE TABLE $table_name (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        data datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
        PRIMARY KEY  (id)
    ) $charset_collate;";

    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($sql);

    // Imposta opzioni default
    add_option('mio_plugin_version', '1.0.0');
}

3. Disattivazione Plugin

// Eseguito quando il plugin viene disattivato
register_deactivation_hook(__FILE__, 'mio_plugin_disattiva');

function mio_plugin_disattiva() {
    // Pulisci cron jobs
    wp_clear_scheduled_hook('mio_plugin_evento_giornaliero');

    // NON cancellare i dati! Lascia all'utente la scelta
}

4. Aggiunta Menu Admin

add_action('admin_menu', 'mio_plugin_menu_admin');

function mio_plugin_menu_admin() {
    add_menu_page(
        'Mio Plugin',           // Titolo pagina
        'Mio Plugin',           // Titolo menu
        'manage_options',       // Capacità richiesta
        'mio-plugin',           // Slug
        'mio_plugin_pagina',    // Funzione callback
        'dashicons-admin-settings', // Icona
        30                      // Posizione
    );
}

5. Caricamento Script e Stili

add_action('wp_enqueue_scripts', 'mio_plugin_carica_risorse');

function mio_plugin_carica_risorse() {
    // Carica CSS
    wp_enqueue_style(
        'mio-plugin-style',
        plugin_dir_url(__FILE__) . 'css/style.css',
        array(),
        '1.0.0'
    );

    // Carica JavaScript
    wp_enqueue_script(
        'mio-plugin-script',
        plugin_dir_url(__FILE__) . 'js/script.js',
        array('jquery'),
        '1.0.0',
        true // Carica nel footer
    );

    // Passa dati a JavaScript
    wp_localize_script('mio-plugin-script', 'mioPluginData', array(
        'ajaxUrl' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('mio_plugin_nonce')
    ));
}

📌 Hook per Modificare Contenuti

6. Modifica Titolo Post

add_filter('the_title', 'mio_prefix_titolo', 10, 2);

function mio_prefix_titolo($title, $post_id) {
    if (is_single() && !is_admin()) {
        $title = '🔥 ' . $title;
    }
    return $title;
}

7. Aggiungi Contenuto Dopo il Post

add_filter('the_content', 'aggiungi_contenuto_dopo_post');

function aggiungi_contenuto_dopo_post($content) {
    if (is_single() && in_the_loop() && is_main_query()) {
        $content .= '
        <div class="post-footer">
            <p>📧 Iscriviti alla newsletter per altri articoli come questo!</p>
            [newsletter-form]
        </div>';
    }
    return $content;
}

8. Modifica Excerpt

add_filter('excerpt_length', 'mio_excerpt_lunghezza');

function mio_excerpt_lunghezza($length) {
    return 30; // Default è 55
}

add_filter('excerpt_more', 'mio_excerpt_piu');

function mio_excerpt_piu($more) {
    return '... <a href="' . get_permalink() . '">Leggi tutto →</a>';
}

9. Personalizza URL Autore

add_filter('author_link', 'mio_custom_author_link', 10, 3);

function mio_custom_author_link($link, $author_id, $author_nicename) {
    return home_url('/team/' . $author_nicename . '/');
}

10. Filtra Query Principale

add_action('pre_get_posts', 'mio_filtra_query_homepage');

function mio_filtra_query_homepage($query) {
    if ($query->is_main_query() && $query->is_home()) {
        $query->set('posts_per_page', 10);
        $query->set('orderby', 'date');
        $query->set('order', 'DESC');
    }
}

📌 Hook per WooCommerce

11. Modifica Prezzo Prodotto

add_filter('woocommerce_product_get_price', 'mio_modifica_prezzo', 10, 2);

function mio_modifica_prezzo($price, $product) {
    // Applica sconto del 10% ai prodotti sopra 100€
    if ($price > 100) {
        $price = $price * 0.9;
    }
    return $price;
}

12. Aggiungi Campo Checkout

add_action('woocommerce_after_order_notes', 'mio_campo_checkout');

function mio_campo_checkout($checkout) {
    echo '<div id="mio_campo_extra">';

    woocommerce_form_field('codice_fiscale', array(
        'type' => 'text',
        'class' => array('form-row-wide'),
        'label' => __('Codice Fiscale'),
        'placeholder' => __('Inserisci il tuo CF'),
        'required' => true,
    ), $checkout->get_value('codice_fiscale'));

    echo '</div>';
}

13. Email Personalizzata Ordine

add_filter('woocommerce_email_subject_customer_completed_order', 'mio_oggetto_email', 10, 2);

function mio_oggetto_email($subject, $order) {
    return '🎉 Il tuo ordine #' . $order->get_id() . ' è stato completato!';
}

14. Azione Dopo Acquisto

add_action('woocommerce_checkout_order_processed', 'mio_dopo_acquisto', 10, 3);

function mio_dopo_acquisto($order_id, $posted_data, $order) {
    // Invia notifica Slack
    // Aggiorna CRM
    // Invia SMS
    error_log('Ordine processato: ' . $order_id);
}

📌 Hook per Sicurezza

15. Sanitizzazione Input

// MAI fidarsi degli input utente!
add_action('admin_post_mio_form', 'mio_elabora_form');

function mio_elabora_form() {
    // Verifica nonce
    check_admin_referer('mio_form_action', 'mio_nonce');

    // Sanitizza input
    $nome = sanitize_text_field($_POST['nome']);
    $email = sanitize_email($_POST['email']);
    $url = esc_url_raw($_POST['website']);

    // Salva dati
    // ...
}

16. Escape Output

// SEMPRE fare escape dell'output!
function mio_display_dati() {
    echo '<h2>' . esc_html($titolo) . '</h2>';
    echo '<a href="' . esc_url($url) . '">Link</a>';
    echo '<div>' . esc_attr($attributo) . '</div>';
}

17. Verifica Permessi

add_action('admin_init', 'mio_verifica_permessi');

function mio_verifica_permessi() {
    if (!current_user_can('manage_options')) {
        wp_die('Non hai i permessi per accedere a questa pagina.');
    }
}

📌 Hook per Performance

18. Disabilita Emoji (Risparmio Query)

remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('admin_print_scripts', 'print_emoji_detection_script');
remove_action('wp_print_styles', 'print_emoji_styles');
remove_action('admin_print_styles', 'print_emoji_styles');

19. Disabilita Embed OEmbed

add_action('init', 'mio_disabilita_embed', 1);

function mio_disabilita_embed() {
    remove_action('rest_api_init', 'wp_oembed_register_route');
    remove_filter('rest_pre_serve_request', 'wp_oembed_send_header');
    remove_action('wp_head', 'wp_oembed_add_discovery_links');
    remove_action('wp_head', 'wp_oembed_add_host_js');
}

20. Limit Heartbeat API

add_filter('heartbeat_settings', 'mio_limit_heartbeat');

function mio_limit_heartbeat($settings) {
    $settings['interval'] = 60; // Default è 15 secondi
    return $settings;
}

📌 Hook per SEO

21. Aggiungi Meta Tag

add_action('wp_head', 'mio_meta_tag_custom');

function mio_meta_tag_custom() {
    if (is_single()) {
        echo '<meta name="author" content="Mario Rossi" />';
        echo '<meta property="article:published_time" content="' . get_the_date('c') . '" />';
    }
}

22. Modifica Title Tag

add_filter('document_title_parts', 'mio_custom_title');

function mio_custom_title($title) {
    if (is_home()) {
        $title['title'] = 'Blog - ' . get_bloginfo('name');
    }
    return $title;
}

23. Aggiungi Schema.org

add_action('wp_head', 'mio_schema_org');

function mio_schema_org() {
    if (is_single()) {
        ?>
        <script type="application/ld+json">
        {
            "@context": "https://schema.org",
            "@type": "Article",
            "headline": "<?php echo esc_js(get_the_title()); ?>",
            "author": {
                "@type": "Person",
                "name": "<?php echo esc_js(get_the_author()); ?>"
            }
        }
        </script>
        <?php
    }
}

📌 Hook per Custom Post Type

24. Registra Custom Post Type

add_action('init', 'mio_registra_cpt_progetto');

function mio_registra_cpt_progetto() {
    $labels = array(
        'name' => 'Progetti',
        'singular_name' => 'Progetto',
        'add_new' => 'Aggiungi Nuovo',
        'add_new_item' => 'Aggiungi Nuovo Progetto',
        'edit_item' => 'Modifica Progetto',
        'new_item' => 'Nuovo Progetto',
        'view_item' => 'Vedi Progetto',
        'search_items' => 'Cerca Progetti',
        'not_found' => 'Nessun progetto trovato',
        'menu_name' => 'Progetti'
    );

    $args = array(
        'labels' => $labels,
        'public' => true,
        'has_archive' => true,
        'show_in_rest' => true, // Abilita Gutenberg
        'supports' => array('title', 'editor', 'thumbnail', 'excerpt'),
        'menu_icon' => 'dashicons-portfolio',
        'rewrite' => array('slug' => 'progetti')
    );

    register_post_type('progetto', $args);
}

25. Registra Tassonomia Custom

add_action('init', 'mio_registra_tassonomia_cliente', 0);

function mio_registra_tassonomia_cliente() {
    $labels = array(
        'name' => 'Clienti',
        'singular_name' => 'Cliente',
        'search_items' => 'Cerca Clienti',
        'all_items' => 'Tutti i Clienti',
        'edit_item' => 'Modifica Cliente',
        'add_new_item' => 'Aggiungi Nuovo Cliente',
        'menu_name' => 'Clienti'
    );

    $args = array(
        'labels' => $labels,
        'public' => true,
        'hierarchical' => false,
        'show_in_rest' => true,
        'rewrite' => array('slug' => 'cliente')
    );

    register_taxonomy('cliente', 'progetto', $args);
}

26. Meta Box per CPT

add_action('add_meta_boxes', 'mio_aggiungi_meta_box');

function mio_aggiungi_meta_box() {
    add_meta_box(
        'mio_meta_box',
        'Dettagli Progetto',
        'mio_meta_box_callback',
        'progetto',
        'normal',
        'high'
    );
}

function mio_meta_box_callback($post) {
    wp_nonce_field('mio_meta_box_action', 'mio_meta_box_nonce');

    $valore = get_post_meta($post->ID, '_mio_metakey', true);

    echo '<label for="mio_field">Budget:</label>';
    echo '<input type="text" id="mio_field" name="mio_field" value="' . esc_attr($valore) . '" style="width:100%" />';
}

27. Salva Meta Box

add_action('save_post_progetto', 'mio_salva_meta_box', 10, 2);

function mio_salva_meta_box($post_id, $post) {
    // Verifica nonce
    if (!isset($_POST['mio_meta_box_nonce']) || 
        !wp_verify_nonce($_POST['mio_meta_box_nonce'], 'mio_meta_box_action')) {
        return;
    }

    // Verifica autosave
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }

    // Verifica permessi
    if (!current_user_can('edit_post', $post_id)) {
        return;
    }

    // Salva dato
    if (isset($_POST['mio_field'])) {
        update_post_meta($post_id, '_mio_metakey', sanitize_text_field($_POST['mio_field']));
    }
}

📌 Hook per Utility

28. Redirect Dopo Login

add_filter('login_redirect', 'mio_redirect_login', 10, 3);

function mio_redirect_login($redirect_to, $request, $user) {
    if (isset($user->roles) && is_array($user->roles)) {
        if (in_array('administrator', $user->roles)) {
            return admin_url();
        } else {
            return home_url('/dashboard/');
        }
    }
    return $redirect_to;
}

29. Nascondi Barra Admin

add_filter('show_admin_bar', '__return_false');

30. Cambia Logo Login

add_action('login_enqueue_scripts', 'mio_logo_login');

function mio_logo_login() {
    echo '<style>
        .login h1 a {
            background-image: url(' . get_stylesheet_directory_uri() . '/images/logo-login.png);
            width: 300px;
            height: 100px;
            background-size: contain;
        }
    </style>';
}

31. Footer Personalizzato Admin

add_filter('admin_footer_text', 'mio_footer_admin');

function mio_footer_admin($text) {
    return 'Sviluppato con ❤️ da <a href="https://mrtux.it" target="_blank">MrTux</a>';
}

32. Cron Job Personalizzato

// Registra evento cron all'attivazione plugin
register_activation_hook(__FILE__, 'mio_attiva_cron');

function mio_attiva_cron() {
    if (!wp_next_scheduled('mio_evento_giornaliero')) {
        wp_schedule_event(time(), 'daily', 'mio_evento_giornaliero');
    }
}

// Esegui azione
add_action('mio_evento_giornaliero', 'mio_esegui_task');

function mio_esegui_task() {
    // Invia report email
    // Pulisci database
    // Aggiorna cache
    error_log('Task giornaliero eseguito');
}

// Rimuovi cron alla disattivazione
register_deactivation_hook(__FILE__, 'mio_disattiva_cron');

function mio_disattiva_cron() {
    wp_clear_scheduled_hook('mio_evento_giornaliero');
}

🎯 Best Practice per Hook Professionali

1. Usa Priority Correttamente

// ❌ SBAGLIATO: Priority default (10) potrebbe confliggere
add_action('init', 'mia_funzione');

// ✅ CORRETTO: Specifica priority esplicita
add_action('init', 'mia_funzione', 20);  // Dopo i default
add_action('init', 'mia_funzione', 5);   // Prima dei default

2. Accetta Tutti gli Argomenti

// ❌ SBAGLIATO: Perdi dati
add_action('publish_post', 'mia_funzione');
function mia_funzione($ID) {
    // ...
}

// ✅ CORRETTO: Accetta tutti gli argomenti
add_action('publish_post', 'mia_funzione', 10, 2);
function mia_funzione($ID, $post) {
    // Ora hai accesso a $post completo
}

3. Namespacing per Evitare Conflitti

// ❌ SBAGLIATO: Nomi generici
add_action('init', 'init_function');

// ✅ CORRETTO: Prefix unico
add_action('init', 'mio_plugin_init_function');

// ✅ OTTIMO: Namespace PHP
namespace MioPlugin;

add_action('init', __NAMESPACE__ . '\init_function');

4. Documenta i Tuoi Hook

/**
 * Hook personalizzato per dopo la pubblicazione
 *
 * @since 1.0.0
 * @param int $post_id ID del post pubblicato
 * @param WP_Post $post Oggetto post completo
 */
do_action('mio_plugin_dopo_pubblicazione', $post_id, $post);

5. Usa Hook Removibili

// ✅ Permetti ad altri di rimuovere il tuo hook
add_action('wp_head', 'mio_funzione_removibile');

// Altri sviluppatori possono fare:
remove_action('wp_head', 'mio_funzione_removibile');

📋 Checklist Sviluppo Plugin con Hook

Prima di Pubblicare

  • [ ] Tutti gli hook hanno prefix unico?
  • [ ] Le funzioni restituiscono valori (per i filter)?
  • [ ] Gli input sono sanitizzati?
  • [ ] L'output è escaped?
  • [ ] I nonce sono verificati?
  • [ ] I permessi sono controllati?
  • [ ] Gli hook di attivazione/disattivazione sono presenti?
  • [ ] I cron job sono puliti alla disattivazione?

Performance

  • [ ] Gli hook sono registrati solo quando necessario?
  • [ ] Le query database sono minimizzate?
  • [ ] Gli script sono caricati solo nelle pagine necessarie?
  • [ ] La cache è utilizzata appropriatamente?

🐛 Troubleshooting Comune

Hook Non Funziona

Problema: Il tuo hook non viene eseguito.

Soluzioni:

  1. Verifica che l'hook esista: do_action_deprecated() nei log
  2. Controlla la priority: potrebbe essere eseguito troppo tardi
  3. Verifica i permessi: current_user_can()
  4. Controlla condizioni: is_admin(), is_single(), etc.

Filter Non Modifica Nulla

Problema: Il filter non altera il valore.

Soluzioni:

  1. Assicurati di RETURN: return $value;
  2. Verifica la priority: altri filter potrebbero sovrascrivere
  3. Controlla il tipo di dato restituito

Conflitti tra Plugin

Problema: Due plugin usano lo stesso hook name.

Soluzioni:

  1. Usa prefix unici nei nomi delle funzioni
  2. Specifica priority diverse
  3. Usa namespace PHP

📚 Risorse Utili

Documentazione Ufficiale

Strumenti di Debug

// Lista tutti gli hook registrati
global $wp_filter;
print_r(array_keys($wp_filter));

// Vedi chi è agganciato a un hook
print_r($wp_filter['init']);

// Debug hook execution
add_action('all', function($hook) {
    error_log('Hook eseguito: ' . $hook);
});

Plugin Utili

  • Query Monitor: Debug hook e query
  • Hook Sniffer: Vedi tutti gli hook eseguiti
  • What The File: Vedi quale template è caricato

🎓 Conclusione

Gli hook WordPress sono uno strumento potente che separa i developer principianti da quelli professionisti. Padroneggiandoli, potrai:

✅ Creare plugin modulari e mantenibili
✅ Personalizzare WordPress senza modificare il core
✅ Integrarti con qualsiasi tema o plugin
✅ Costruire soluzioni scalabili e sicure

Prossimi Passi:

  1. Sperimenta con gli esempi in questa guida
  2. Crea un plugin di test per praticare
  3. Esplora il WordPress Hook Reference
  4. Contribuisci alla community con i tuoi hook

💬 Hai Domande?

Lascia un commento o contattaci per consulenza sullo sviluppo di plugin WordPress professionali!

📧 Newsletter: Iscriviti per ricevere altri tutorial come questo!


Ultimo aggiornamento: Marzo 2026
Tempo di lettura: 20 minuti
Parole: 2.500+

Autore articolo: Emilio Petrozzi

🌐 Creazione siti web dinamici e di commercio elettronico 🛍 assistenza WordPress 🌐 Con oltre 20 anni di esperienza nel settore, esperto nella realizzazione di soluzioni digitali personalizzate per il tuo business. 🚀

🔧 Offro assistenza WordPress completa, garantendo che il tuo sito sia sempre aggiornato e funzionante al meglio. 📈 Inoltre mi occupo dell'ottimizzazione per motori di ricerca (SEO), assicurando che il tuo sito sia sempre facilmente rintracciabile dai tuoi clienti. 💻

📢 Le mie campagne pubblicitarie web sono progettate per aumentare la visibilità del tuo brand e generare traffico di qualità verso il tuo sito. 🔒 Inoltre la sicurezza informatica è una priorità in modo tale da garantire i tuoi dati e quelli dei tuoi clienti.

🤝 Affidati a mrtux.it per un servizio professionale e di qualità, e porta il tuo business al successo nel mondo digitale! 🎯

🔑 #CreazioneSitiWeb #Ecommerce #AssistenzaWordPress #OttimizzazioneSEO #SicurezzaInformatica

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *


Aricoli correlati

Emilio Petrozzi  P. I.V.A. IT03080230604 - Professionista ai sensi della Legge 4/2013