Creare un plugin per Wordpress
Sviluppare un plugin per WordPress permette di estendere le funzionalità del CMS senza modificare il codice del core o dipendere necessariamente dal tema attivo. Un plugin può introdurre nuove funzionalità, integrare servizi esterni, gestire dati personalizzati e modificare il comportamento del sito attraverso le API messe a disposizione da WordPress.
In questa guida vedremo come creare un plugin da zero, come funzionano gli hook, come gestire le operazioni di attivazione e come aggiungere un Custom Post Type per organizzare le recensioni di prodotti o servizi.
Non è necessario conoscere ogni dettaglio dell'architettura di WordPress per iniziare, ma è importante avere familiarità con PHP e con la struttura di base di un sito WordPress.
Progettare il plugin
Prima di scrivere codice, conviene definire il problema che il plugin deve risolvere. Un'analisi preliminare aiuta a stabilire quali funzionalità siano necessarie, quali dati debbano essere gestiti e come gli utenti interagiranno con il sistema.
Per esempio, un plugin dedicato alle recensioni potrebbe dover consentire di:
- Inserire e modificare recensioni dal pannello di amministrazione.
- Associare un titolo, un testo e un'immagine a ogni recensione.
- Organizzare le recensioni in categorie.
- Visualizzare i contenuti sul sito pubblico.
- Aggiungere in futuro una valutazione numerica o altri campi personalizzati.
È utile distinguere fin dall'inizio le funzionalità indispensabili da quelle che potrebbero essere introdotte in una versione successiva. In questo modo il progetto rimane gestibile e più semplice da testare.
Se il plugin sarà pubblicato nella directory ufficiale di WordPress, occorrerà inoltre scegliere un nome riconoscibile, verificare che non sia già utilizzato e preparare una descrizione chiara. Nome, descrizione, versione, autore e licenza sono informazioni importanti per distribuire il progetto, ma non sostituiscono la qualità del codice, la documentazione e i controlli di sicurezza.
Creare la struttura del plugin
Un plugin può essere composto da un singolo file PHP oppure da più file organizzati in cartelle. Per un progetto semplice possiamo partire da questa struttura:
wp-content/
└── plugins/
└── wp-test/
└── wp-test.phpLa cartella wp-test contiene il plugin, mentre wp-test.php è il suo file principale. È consigliabile mantenere coerenti i nomi della cartella e del file per rendere il progetto più facile da riconoscere e gestire.
All'interno del file principale inseriamo l'intestazione che permette a WordPress di identificare il plugin.
<?php
/**
* Plugin Name: WP Test
* Description: Un esempio di plugin WordPress con un tipo di contenuto personalizzato.
* Version: 1.0.0
* Requires at least: 6.0
* Requires PHP: 8.0
* Author: Il tuo nome
* License: GPL-2.0-or-later
* Text Domain: wp-test
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}Le informazioni dell'intestazione vengono lette da WordPress per mostrare il plugin nella schermata di amministrazione. La versione e i requisiti indicati sono esemplificativi e devono essere adeguati alle effettive dipendenze del progetto.
La condizione ABSPATH impedisce l'esecuzione del file quando viene richiamato direttamente al di fuori del normale contesto di WordPress. È una misura difensiva utile, ma non sostituisce i controlli di autorizzazione, la validazione degli input o la protezione delle operazioni che modificano dati.
Cosa sono gli hook di WordPress
Gli hook sono uno dei meccanismi fondamentali che rendono WordPress estensibile. Permettono a plugin e temi di eseguire codice in determinati momenti oppure di modificare valori elaborati dal sistema, senza dover intervenire direttamente sui file del core.
Gli hook si dividono in due categorie: action e filter.
Action hook
Un'action hook consente di eseguire una funzione quando WordPress raggiunge un determinato punto del proprio ciclo di esecuzione. Può essere utilizzato, per esempio, per registrare un tipo di contenuto, aggiungere elementi al footer o inizializzare una funzionalità.
Ecco un esempio che aggiunge un testo al footer del sito:
function wp_test_custom_footer() {
echo '<p>Contenuto aggiunto dal plugin.</p>';
}
add_action( 'wp_footer', 'wp_test_custom_footer' );La funzione add_action() associa una callback a un hook. Quando WordPress esegue wp_footer, richiama la funzione registrata.
L'esempio è volutamente semplice: in un progetto reale, l'output HTML deve essere appropriato al contesto e, quando contiene dati variabili, questi devono essere sottoposti a escaping.
Filter hook
Un filter hook permette invece di ricevere un valore, modificarlo e restituirlo al codice che lo utilizza.
Per esempio, possiamo modificare il numero di parole utilizzato per generare gli estratti dei contenuti:
function wp_test_excerpt_length( $length ) {
return 25;
}
add_filter( 'excerpt_length', 'wp_test_excerpt_length', 20 );In questo caso, la callback restituisce il valore 25, che WordPress utilizza come lunghezza dell'estratto. Il parametro 20 indica la priorità della callback: un numero più basso corrisponde a un'esecuzione precedente rispetto alle callback registrate sullo stesso hook con priorità maggiore.
La differenza fondamentale è questa:
- Action: esegue un'operazione in un punto specifico del ciclo di WordPress.
- Filter: riceve un valore, lo elabora e restituisce il risultato modificato.
Un filter deve restituire il valore risultante, anche quando non è necessario modificarlo. Le action, invece, vengono normalmente utilizzate per eseguire operazioni e non per trasformare un valore restituito al chiamante.
Le funzioni add_action() e add_filter() sono quindi strumenti centrali nello sviluppo dei plugin. La documentazione ufficiale di WordPress contiene l'elenco degli hook disponibili e descrive i parametri accettati dalle relative callback.
Gestire l'attivazione e la disattivazione
WordPress mette a disposizione funzioni specifiche per eseguire operazioni quando un plugin viene attivato o disattivato.
La funzione register_activation_hook() registra una callback da eseguire durante l'attivazione. Può essere utile per inizializzare alcune opzioni, preparare strutture necessarie o aggiornare le regole di riscrittura degli URL.
Ecco un esempio:
function wp_test_activate() {
add_option( 'wp_test_version', '1.0.0' );
}
register_activation_hook( __FILE__, 'wp_test_activate' );Il parametro __FILE__ identifica il file principale del plugin, mentre add_option() crea un'opzione nel database senza sovrascrivere un'opzione già esistente con lo stesso nome.
La callback di attivazione non viene eseguita a ogni caricamento della pagina: viene richiamata durante l'attivazione del plugin. Le operazioni che devono essere eseguite regolarmente appartengono invece al normale ciclo di WordPress, attraverso gli hook appropriati.
Per la disattivazione è disponibile register_deactivation_hook(). Una callback di disattivazione può, per esempio, aggiornare le regole di riscrittura degli URL o interrompere attività temporanee.
È importante distinguere la disattivazione dalla disinstallazione: disattivare un plugin non significa necessariamente cancellarne i dati. La rimozione delle opzioni e delle tabelle personalizzate deve essere progettata con attenzione e, se prevista, gestita attraverso una procedura di disinstallazione esplicita.
Nel caso di un plugin che registra un Custom Post Type, le regole di riscrittura possono essere aggiornate durante l'attivazione e la disattivazione. Non è invece opportuno chiamare flush_rewrite_rules() a ogni richiesta, perché si tratta di un'operazione che non deve essere eseguita continuamente.
Aggiungere un Custom Post Type
Passiamo a un esempio concreto: un plugin che introduce un tipo di contenuto chiamato Recensioni.
WordPress include già i tipi di contenuto fondamentali, come articoli e pagine. Attraverso la funzione register_post_type() è possibile registrare altri tipi di contenuto, ciascuno con le proprie etichette, impostazioni e funzionalità.
Un Custom Post Type è utile quando i contenuti hanno una natura distinta da quella degli articoli tradizionali. Può essere impiegato, per esempio, per gestire prodotti, eventi, progetti, testimonianze o recensioni.
Definire il tipo di contenuto
Creiamo una funzione che descriva il nuovo tipo di contenuto:
function wp_test_register_reviews_cpt() {
$labels = array(
'name' => _x( 'Recensioni', 'Nome plurale', 'wp-test' ),
'singular_name' => _x( 'Recensione', 'Nome singolare', 'wp-test' ),
'menu_name' => __( 'Recensioni', 'wp-test' ),
'add_new' => __( 'Aggiungi nuova', 'wp-test' ),
'add_new_item' => __( 'Aggiungi una recensione', 'wp-test' ),
'edit_item' => __( 'Modifica recensione', 'wp-test' ),
'new_item' => __( 'Nuova recensione', 'wp-test' ),
'view_item' => __( 'Visualizza recensione', 'wp-test' ),
'search_items' => __( 'Cerca recensioni', 'wp-test' ),
'not_found' => __( 'Nessuna recensione trovata', 'wp-test' ),
'not_found_in_trash' => __( 'Nessuna recensione nel cestino', 'wp-test' ),
);
$args = array(
'labels' => $labels,
'public' => true,
'show_in_rest' => true,
'has_archive' => true,
'rewrite' => array(
'slug' => 'recensioni',
),
'supports' => array(
'title',
'editor',
'author',
'thumbnail',
'excerpt',
'comments',
),
);
register_post_type( 'wp_test_review', $args );
}Le opzioni principali sono:
- labels: definisce i testi mostrati nell'interfaccia amministrativa.
- public: rende il tipo di contenuto pubblico e generalmente disponibile nelle query appropriate.
- show_in_rest: espone il tipo di contenuto attraverso la REST API di WordPress, permettendone l'utilizzo anche con l'editor a blocchi.
- has_archive: abilita un archivio dedicato al tipo di contenuto.
- rewrite: definisce lo slug utilizzato negli URL.
- supports: stabilisce quali funzionalità standard sono disponibili, come titolo, editor, immagine in evidenza e commenti.
Il primo parametro di register_post_type() è l'identificatore interno del tipo di contenuto. È opportuno utilizzare un nome stabile, composto da caratteri validi e sufficientemente specifico da evitare conflitti con altri plugin.
Il testo wp-test utilizzato nelle funzioni di traduzione corrisponde al dominio di testo dichiarato nell'intestazione del plugin.
Registrare il Custom Post Type
Definire la funzione non basta: occorre collegarla all'hook init, che è il momento appropriato per registrare i tipi di contenuto.
add_action( 'init', 'wp_test_register_reviews_cpt' );Quando WordPress esegue l'hook init, richiama la funzione e registra il tipo di contenuto. Da quel momento il sistema può utilizzarlo nelle query e nell'interfaccia amministrativa.
Completare il file principale
Per rendere l'esempio immediatamente utilizzabile, possiamo inserire la registrazione del tipo di contenuto e le callback di attivazione e disattivazione nello stesso file wp-test.php.
<?php
/**
* Plugin Name: WP Test
* Description: Esempio di plugin con il tipo di contenuto Recensioni.
* Version: 1.0.0
* Requires at least: 6.0
* Requires PHP: 8.0
* Author: Il tuo nome
* License: GPL-2.0-or-later
* Text Domain: wp-test
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
function wp_test_register_reviews_cpt() {
$labels = array(
'name' => _x( 'Recensioni', 'Nome plurale', 'wp-test' ),
'singular_name' => _x( 'Recensione', 'Nome singolare', 'wp-test' ),
'menu_name' => __( 'Recensioni', 'wp-test' ),
'add_new_item' => __( 'Aggiungi una recensione', 'wp-test' ),
'edit_item' => __( 'Modifica recensione', 'wp-test' ),
);
$args = array(
'labels' => $labels,
'public' => true,
'show_in_rest' => true,
'has_archive' => true,
'rewrite' => array(
'slug' => 'recensioni',
),
'supports' => array(
'title',
'editor',
'author',
'thumbnail',
'excerpt',
'comments',
),
);
register_post_type( 'wp_test_review', $args );
}
add_action( 'init', 'wp_test_register_reviews_cpt' );
function wp_test_activate() {
wp_test_register_reviews_cpt();
flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'wp_test_activate' );
function wp_test_deactivate() {
flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, 'wp_test_deactivate' );Durante l'attivazione, la callback registra il tipo di contenuto e aggiorna le regole di riscrittura, così da rendere disponibili gli URL configurati dal plugin. Durante la normale esecuzione, la registrazione avviene invece tramite init.
Questo è un esempio didattico: in un plugin più articolato conviene separare le responsabilità in file distinti e verificare gli eventuali errori restituiti dalle API di WordPress.
Attivare e verificare il plugin
Dopo aver salvato il file:
- Accedi al pannello di amministrazione di WordPress.
- Apri la sezione Plugin.
- Attiva WP Test.
- Verifica che nel menu amministrativo sia comparsa la voce Recensioni.
- Crea una recensione con titolo e contenuto.
- Controlla l'URL pubblico del contenuto e quello dell'archivio, se disponibile.
Se gli URL restituiscono un errore 404, verifica le impostazioni dei permalink e aggiorna le regole di riscrittura dalla relativa schermata amministrativa. Evita di eseguire ripetutamente il flush delle regole a ogni richiesta.
Personalizzare e visualizzare le recensioni
A questo punto il plugin consente di gestire le recensioni dal pannello amministrativo. Tuttavia, registrare un Custom Post Type non significa che il contenuto avrà automaticamente il layout desiderato.
La visualizzazione dipende dalla configurazione del tema e dai template disponibili. In un tema classico, per esempio, possono essere utilizzati file come single-wp_test_review.php e archive-wp_test_review.php, seguendo le convenzioni di gerarchia dei template di WordPress. Nei temi a blocchi, invece, la personalizzazione può avvenire attraverso i template e gli strumenti dell'editor del sito.
Il progetto può essere esteso aggiungendo:
- Tassonomie personalizzate per classificare le recensioni.
- Campi aggiuntivi per la valutazione numerica, i pro e i contro.
- Shortcode o blocchi per inserire le recensioni in altre pagine.
- Funzionalità di ricerca e filtri.
- Integrazioni con servizi esterni.
Per gestire campi personalizzati è possibile utilizzare le API dei metadati di WordPress oppure strumenti dedicati, come Advanced Custom Fields. La scelta dipende dalla complessità del progetto e dal livello di controllo richiesto.
È preferibile mantenere nel plugin le funzionalità e la logica di gestione dei dati, lasciando al tema la responsabilità della presentazione. In questo modo i contenuti possono rimanere disponibili anche quando si cambia tema.
Sicurezza, test e manutenzione
Un plugin non dovrebbe essere considerato pronto soltanto perché funziona sul sito dello sviluppatore. Prima della distribuzione è necessario verificare che il codice sia affidabile e che il comportamento sia coerente nelle condizioni previste.
In particolare, è importante:
- Validare e sanificare gli input: i dati ricevuti dagli utenti devono essere controllati prima di essere elaborati o salvati.
- Applicare l'escaping all'output: utilizzare funzioni appropriate, come esc_html() per il testo HTML, esc_attr() per gli attributi e esc_url() per gli URL.
- Controllare le autorizzazioni: le operazioni sensibili devono verificare le capability dell'utente, per esempio tramite current_user_can().
- Proteggere le richieste che modificano dati: quando necessario, utilizzare nonce e controllarne la validità. Un nonce non sostituisce il controllo delle autorizzazioni.
- Gestire correttamente gli errori: evitare di esporre informazioni sensibili e registrare i dettagli tecnici utili durante lo sviluppo.
- Testare le versioni supportate: verificare il funzionamento con le versioni di WordPress e PHP dichiarate dal plugin.
- Mantenere aggiornate le dipendenze: correggere vulnerabilità e incompatibilità quando vengono individuate.
Se il plugin deve essere distribuito pubblicamente, conviene aggiungere una documentazione che spieghi installazione, configurazione, funzionalità, requisiti e limitazioni. Per la pubblicazione nella directory ufficiale è necessario rispettare anche le relative linee guida.
Conclusione
Sviluppare un plugin WordPress significa combinare la conoscenza di PHP con la comprensione delle API e del ciclo di esecuzione del CMS. La creazione del file principale è soltanto il punto di partenza: gli hook permettono di integrarsi nel sistema, le funzioni di attivazione e disattivazione gestiscono le operazioni legate al ciclo di vita del plugin e i Custom Post Type consentono di introdurre nuove tipologie di contenuto.
Partire da un esempio piccolo e funzionante, come il plugin per le recensioni, permette di comprendere questi meccanismi senza complicare subito l'architettura. Da lì è possibile aggiungere gradualmente campi personalizzati, tassonomie, interfacce e integrazioni, mantenendo il codice organizzato, sicuro e facile da mantenere.
Per approfondire, la risorsa di riferimento rimane la documentazione ufficiale per gli sviluppatori di WordPress: https://developer.wordpress.org/plugins/.
