Contenuto articolo
- Hook WordPress: Azioni e Filter per Plugin Professionali
- 🎯 Introduzione
- 📚 Cosa Sono gli Hook WordPress?
- ⚡ Actions vs Filters: La Differenza Chiave
- 🔥 30+ Esempi Pratici di Hook Essenziali
- 🎯 Best Practice per Hook Professionali
- 📋 Checklist Sviluppo Plugin con Hook
- 🐛 Troubleshooting Comune
- 📚 Risorse Utili
- 🎓 Conclusione
- 💬 Hai Domande?
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>';
}
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:
- Verifica che l'hook esista:
do_action_deprecated()nei log - Controlla la priority: potrebbe essere eseguito troppo tardi
- Verifica i permessi:
current_user_can() - Controlla condizioni:
is_admin(),is_single(), etc.
Filter Non Modifica Nulla
Problema: Il filter non altera il valore.
Soluzioni:
- Assicurati di RETURN:
return $value; - Verifica la priority: altri filter potrebbero sovrascrivere
- Controlla il tipo di dato restituito
Conflitti tra Plugin
Problema: Due plugin usano lo stesso hook name.
Soluzioni:
- Usa prefix unici nei nomi delle funzioni
- Specifica priority diverse
- 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:
- Sperimenta con gli esempi in questa guida
- Crea un plugin di test per praticare
- Esplora il WordPress Hook Reference
- 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+




Lascia un commento