{"id":1935,"date":"2026-07-16T10:13:55","date_gmt":"2026-07-16T08:13:55","guid":{"rendered":"https:\/\/studioimmens.com\/creare-un-plugin-wordpress-da-zero\/"},"modified":"2026-07-16T10:13:55","modified_gmt":"2026-07-16T08:13:55","slug":"creare-un-plugin-wordpress-da-zero","status":"publish","type":"post","link":"https:\/\/studioimmens.com\/en\/creare-un-plugin-wordpress-da-zero\/","title":{"rendered":"Creare un plugin WordPress da zero"},"content":{"rendered":"<h2>Struttura di un plugin WordPress<\/h2>\n<p>Un plugin WordPress \u00e8 fondamentalmente una directory contenente file PHP che estendono le funzionalit\u00e0 del CMS. La struttura minima richiede un file principale con un&#8217;intestazione specifica riconosciuta da WordPress. Puoi posizionare la directory del plugin in wp-content\/plugins\/ o in wp-content\/mu-plugins\/ per i must-use plugin.<\/p>\n<p>La struttura consigliata per un plugin ben organizzato include:<\/p>\n<ul>\n<li>plugin-name.php (file principale con header comment)<\/li>\n<li>README.txt (informazioni per il repository WordPress.org)<\/li>\n<li>admin\/ (file per il backend)<\/li>\n<li>includes\/ (classi e funzioni condivise)<\/li>\n<li>public\/ (file per il front-end)<\/li>\n<li>languages\/ (file di traduzione .po\/.mo)<\/li>\n<li>assets\/ (CSS, JS, immagini)<\/li>\n<\/ul>\n<h2>Il file principale e l&#8217;header comment<\/h2>\n<p>Il file principale del plugin deve iniziare con un header comment che WordPress utilizza per identificare e visualizzare il plugin nella schermata di amministrazione. Ecco la struttura obbligatoria:<\/p>\n<p>L&#8217;header include: Plugin Name, Plugin URI, Description, Version, Requires at least, Requires PHP, Author, Author URI, License e License URI. Campi aggiuntivi come Text Domain e Domain Path sono necessari per l&#8217;internazionalizzazione.<\/p>\n<p>Dopo l&#8217;header, usa un controllore di accesso diretto per impedire l&#8217;esecuzione del file se chiamato direttamente via URL: <code>if (!defined('ABSPATH')) exit;<\/code>. Questo \u00e8 uno standard di sicurezza fondamentale.<\/p>\n<h2>Attivazione, disattivazione e disinstallazione<\/h2>\n<p>WordPress fornisce hook specifici per gestire il ciclo di vita del plugin. register_activation_hook() esegue codice all&#8217;attivazione: creazione di tabelle personalizzate, impostazione di opzioni predefinite, controllo dei requisiti di sistema.<\/p>\n<p>register_deactivation_hook() esegue codice alla disattivazione: pulizia di cache temporanee, disattivazione di cron job, ma non deve mai eliminare dati utente. Questo \u00e8 importante: l&#8217;utente potrebbe riattivare il plugin in futuro e ritrovare i propri dati intatti.<\/p>\n<p>Per la disinstallazione, il metodo migliore \u00e8 usare un file uninstall.php nella root del plugin. Viene eseguito solo quando l&#8217;utente elimina il plugin, non alla semplice disattivazione. Qui puoi rimuovere definitivamente tutte le opzioni, tabelle e dati creati dal plugin.<\/p>\n<h2>Aggiungere una pagina di impostazioni<\/h2>\n<p>La maggior parte dei plugin offre una pagina di impostazioni nel backend. Puoi aggiungerla usando le WordPress Settings API, che gestiscono automaticamente validazione e salvataggio dei dati. Le funzioni principali sono:<\/p>\n<ul>\n<li>add_options_page() o add_menu_page() per registrare la pagina<\/li>\n<li>register_setting() per registrare le opzioni<\/li>\n<li>add_settings_section() e add_settings_field() per strutturare il form<\/li>\n<li>do_settings_sections() e settings_fields() per renderizzare il form<\/li>\n<\/ul>\n<p>Le Settings API seguono il principio di separazione tra presentazione e logica. Definisci i campi in una funzione e renderizzali in un template. Questo rende il codice manutenibile e facile da estendere.<\/p>\n<h2>Creare custom post type e tassonomie<\/h2>\n<p>I custom post type (CPT) permettono di aggiungere tipi di contenuto personalizzati oltre a post e pagine. Si registrano con register_post_type(), specificando label, supporti (thumbnail, editor, excerpt), rewrite rules e capacit\u00e0. Per portfolio, testimonianze, eventi, prodotti (se non usi WooCommerce), i CPT sono la soluzione ideale.<\/p>\n<p>Le tassonomie personalizzate (register_taxonomy()) aggiungono sistemi di categorizzazione specifici per i tuoi CPT. Se crei un CPT &#8220;Libri&#8221;, puoi registrare una tassonomia &#8220;Genere&#8221; per classificarli. Le tassonomie supportano gerarchia (come le categorie) o piatta (come i tag).<\/p>\n<p>Dopo aver registrato CPT e tassonomie, flusha le rewrite rule con flush_rewrite_rules() durante l&#8217;attivazione del plugin, mai a ogni caricamento della pagina.<\/p>\n<h2>Shortcode e widget<\/h2>\n<p>Gli shortcode permettono agli utenti di inserire funzionalit\u00e0 complesse nei contenuti con una semplice sintassi [mioshortcode]. Si registrano con add_shortcode() e accettano attributi e contenuto racchiuso. Un esempio classico \u00e8 uno shortcode che mostra un pulsante personalizzato: [pulsante colore=&#8221;rosso&#8221; url=&#8221;https:\/\/esempio.com&#8221;]Clicca qui[\/pulsante].<\/p>\n<p>I widget sono blocchi riutilizzabili posizionabili nelle sidebar. La vecchia API (WP_Widget) \u00e8 ancora supportata, ma dal 2024 il futuro sono i Block Widget basati su Gutenberg. Per nuovi plugin, sviluppa widget come blocchi Gutenberg: sono pi\u00f9 flessibili e compatibili con il Full Site Editing.<\/p>\n<h2>Esporre API REST endpoints<\/h2>\n<p>WordPress REST API \u00e8 il modo moderno per interagire con i dati del sito via HTTP. Puoi registrare endpoint personalizzati usando register_rest_route(). Ogni endpoint specifica namespace, route, metodi (GET, POST, PUT, DELETE) e callback di autorizzazione.<\/p>\n<p>Esempio pratico: un endpoint \/mioplugin\/v1\/dati che restituisce dati in formato JSON a chiamate AJAX dal front-end. La REST API gestisce automaticamente serializzazione, validazione e permessi. Usa sempre permission_callback per verificare che l&#8217;utente abbia i diritti necessari.<\/p>\n<p>Per la sicurezza degli endpoint, implementa nonce verification per le richieste provenienti dal front-end e verifica le capability per le richieste amministrative.<\/p>\n<h2>Best practice di sicurezza<\/h2>\n<p>Scrivere plugin sicuri \u00e8 fondamentale. WordPress fornisce numerose API per proteggere il codice:<\/p>\n<ul>\n<li><strong>Nonce:<\/strong> usa wp_create_nonce() e wp_verify_nonce() per proteggere form e URL da CSRF<\/li>\n<li><strong>Sanitizzazione:<\/strong> usa sanitize_text_field(), sanitize_email(), sanitize_html_class() per pulire i dati in ingresso<\/li>\n<li><strong>Validazione:<\/strong> verifica che i dati siano del tipo e formato attesi prima di processarli<\/li>\n<li><strong>Capability check:<\/strong> usa current_user_can() per verificare i permessi utente prima di eseguire operazioni sensibili<\/li>\n<li><strong>Preparazione query:<\/strong> usa $wpdb->prepare() per tutte le query SQL che includono variabili<\/li>\n<li><strong>Escaping output:<\/strong> usa esc_html(), esc_attr(), esc_url() per proteggere l&#8217;output verso il browser<\/li>\n<\/ul>\n<p>Non fidarti mai dell&#8217;input utente. Anche gli amministratori possono essere ingannati da attacchi XSS. Ogni dato che arriva da $_GET, $_POST, $_REQUEST o dal database deve essere trattato come potenzialmente pericoloso fino a prova contraria.<\/p>\n<h2>Internazionalizzazione<\/h2>\n<p>Per rendere il tuo plugin traducibile, usa le funzioni di WordPress: __() e _e() per stringhe semplici, _n() per plurali, _x() e _ex() per stringhe con contesto. Il text domain deve corrispondere al nome della directory del plugin, come dichiarato nell&#8217;header comment.<\/p>\n<p>Genera il file .pot con strumenti come Poedit o WP-CLI, poi traduci in .po e compila in .mo. Per caricare le traduzioni, usa load_plugin_textdomain() all&#8217;inizio del plugin. Se distribuisci su WordPress.org, le traduzioni vengono caricate automaticamente dal translate.wordpress.org.<\/p>\n<h2>Distribuzione su WordPress.org<\/h2>\n<p>Pubblicare un plugin sul repository ufficiale di WordPress.org lo rende disponibile a milioni di utenti. Il processo richiede:<\/p>\n<ol>\n<li>Sviluppare il plugin seguendo tutte le best practice WordPress<\/li>\n<li>Creare un README.txt ben formattato con descrizione, installazione, FAQ e changelog<\/li>\n<li>Eliminare codice offensivo, backlink nascosti, eval, base64_decode e qualsiasi altra pratica scorretta<\/li>\n<li>Sottoporre il plugin per la revisione tramite la pagina Plugin Developer di WordPress.org<\/li>\n<li>Il team di revisione controlla il codice per sicurezza, standard e qualit\u00e0. Il processo pu\u00f2 richiedere da pochi giorni a settimane.<\/li>\n<\/ol>\n<p>Una volta approvato, il plugin avr\u00e0 una pagina su WordPress.org, statistiche di download, valutazioni degli utenti e aggiornamenti automatici per gli installati. Mantieni il plugin aggiornato, rispondi ai ticket di supporto e aggiorna la compatibilit\u00e0 con le ultime versioni di WordPress.<\/p>\n<h2>Conclusione<\/h2>\n<p>Creare un plugin WordPress da zero \u00e8 pi\u00f9 accessibile di quanto sembri. Seguendo la struttura standard, utilizzando le API ufficiali e applicando le best practice di sicurezza, puoi sviluppare plugin robusti e professionali. Inizia con un plugin semplice (uno shortcode, una pagina di impostazioni) e gradualmente aggiungi complessit\u00e0. La documentazione ufficiale WordPress Developer Resources \u00e8 il tuo miglior alleato: \u00e8 completa, aggiornata e ricca di esempi pratici.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Struttura di un plugin WordPress Un plugin WordPress \u00e8 fondamentalmente una directory contenente file PHP che estendono le funzionalit\u00e0 del CMS. La struttura minima richiede un file principale con un&#8217;intestazione specifica riconosciuta da WordPress. Puoi posizionare la directory del plugin in wp-content\/plugins\/ o in wp-content\/mu-plugins\/ per i must-use plugin. La struttura consigliata per un plugin [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2053,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_gspb_post_css":"","ai_primary_source":"Studio Immens Blog","visibility_scope":"both","ai_summary":"Struttura di un plugin WordPress Un plugin WordPress \u00e8 fondamentalmente una directory contenente file PHP che estendono le funzionalit\u00e0 del CMS. La struttura minima richiede un file principale con un'intestazione specifica riconosciuta da WordPress. Puoi posizionare la directory del plugin in wp-...","ai_intent":"informative","ai_related_resources":"","ai_priority":5,"ai_entity_type":"Article","ai_is_based_on":"https:\/\/blog.studioimmens.com\/creare-un-plugin-wordpress-da-zero\/","ai_citations":"","ai_mentions":"","ai_speakable_selector":"","ai_chunk_hints":"Creare, un, plugin, WordPress","footnotes":""},"categories":[133],"tags":[],"ai_visibility":[],"class_list":["post-1935","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-wordpress"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/studioimmens.com\/en\/wp-json\/wp\/v2\/posts\/1935","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/studioimmens.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/studioimmens.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/studioimmens.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/studioimmens.com\/en\/wp-json\/wp\/v2\/comments?post=1935"}],"version-history":[{"count":0,"href":"https:\/\/studioimmens.com\/en\/wp-json\/wp\/v2\/posts\/1935\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/studioimmens.com\/en\/wp-json\/wp\/v2\/media\/2053"}],"wp:attachment":[{"href":"https:\/\/studioimmens.com\/en\/wp-json\/wp\/v2\/media?parent=1935"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/studioimmens.com\/en\/wp-json\/wp\/v2\/categories?post=1935"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/studioimmens.com\/en\/wp-json\/wp\/v2\/tags?post=1935"},{"taxonomy":"ai_visibility","embeddable":true,"href":"https:\/\/studioimmens.com\/en\/wp-json\/wp\/v2\/ai_visibility?post=1935"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}