Creare un plugin WordPress

← ritorno a Plugin WordPress

fonti:

Struttura dei file e delle directory

La pratica comunemente seguita e raccomandata è quella di dare al file principale del plugin lo stesso nome della directory in cui sono contenuti i file del plugin. Quindi se la directory viene chiamata myplugin, il file principale del plugin verrà nominato myplugin.php. Tuttavia, come vedremo in seguito, questo non basta ancora affinché WordPress includa un plugin nell’elenco della sezione Plugin nel backend.

I plugin vanno inseriti nella directory wp-content/plugins. WordPress analizza il contenuto di questa directory ad ogni sua inizializzazione. Quindi il percorso del nostro ipotetico plugin sarà wp-content/plugins/myplugin/myplugin.php (come vedremo WordPress dispone di diverse funzioni e costanti per far riferimento sia all’URL assoluto che al percorso dei plugin ).

/plugin-name
     plugin-name.php
     uninstall.php
     /languages
     /includes
     /admin
          /js
          /css
          /images
     /public
          /js
          /css
          /images

Il file principale del plugin

/**
 * Plugin Name: Norisys Archive
 * Version: 1.0
 * Description: Plugin che realizza un archivio con i file caricati dall'applicazione Norisys (Oltreweb)
 * Author: Norisys srl
 * Author URI: http://www.norisys.it
 */

// If this file is called directly, abort. 
if( ! defined( 'WPINC' ) ) {
   die;
}

// Include the dependencies needed to instantiate the plugin.
foreach( glob( plugin_dir_path( __FILE__ ) . 'admin/*.php' ) as $file ) {
   include_once $file;
}

Questi sono i metadati del plugin che verranno usati da WordPress per identificarlo nel backend. La prima riga dichiara il nome del plugin, la seconda il numero di versione, la terza la descrizione, la quarta mostra l’autore del plugin e la quinta l’URL del sito dell’autore del plugin. Quando il plugin viene attivato le informazioni contenute in questi metadati vengono salvate nel database aggiungendole alla stringa contenuta nel campo active_plugins della tabella wp_options (si tratta di una stringa serializzata).

Percorsi ed URL

C’è una differenza sostanziale tra percorsi ed URL quando si parla di plugin e più in generale di tutto ciò che ha a che fare con WordPress. Un "percorso" (path) fa riferimento al file system del server che ospita WordPress, mentre un "URL" fa riferimento al protocollo HTTP e al dominio su cui risiedono i file.

Quindi /home/nomeutente/sito.com/public_html/wp-content/plugins/my_plugin è un percorso, mentre http://sito.com/wp-content/plugins/my_plugin/ è un URL.

I percorsi vengono usati per includere i file PHP, mentre gli URL per includere i file CSS, JavaScript e le immagini. WordPress gestisce i percorsi tramite la funzione plugin_dir_path() che restituisce il percorso alla directory del plugin compreso lo slash finale. Quindi nel file principale del plugin possiamo scrivere:

define( ‘MY_PLUGIN_PATH’, plugin_dir_path( __FILE__ ) ); // /home/nomeutente/sito.com/public_html/wp-content/plugins/my_plugin/

e quindi includere i file PHP in questo modo:

require_once( MY_PLUGIN_PATH . ‘framework/MyClass.php’ );

Al contrario la funzione plugin_dir_url() restituisce l’URL assoluto alla directory principale del plugin compreso lo slash finale. Quindi nel file principale del plugin possiamo scrivere:

define( ‘MY_PLUGIN_URL’, plugin_dir_url( __FILE__ ) ); // http://sito.com/wp-content/plugins/my_plugin/

e quindi usare l’URL in questo modo:

wp_register_script( ‘my’, MY_PLUGIN_URL . ‘js/my.js’, array( ‘jquery’ ), ‘1.0’, true );

Da segnalare anche la funzione plugins_url() che ha uno scopo identico anche se con parametri diversi.

Tutte queste funzioni si basano sul file o sulla directory passata come parametro per restituire il percorso o l'URL corretto. In PHP __FILE__ fa riferimento al file corrente in cui viene invocato. Quindi usarlo in my_plugin/my_plugin.php e in my_plugin/framework/MyClass.php restituirà due valori distinti poiché i file non si trovano nella stessa directory.

Backend

Caching delle query WordPress

Frontend

Il codice CSS e JavaScript va fornito in due formati: uno compresso e minimizzato da usare effettivamente sul sito Internet ed un formato non compresso per le eventuali modifiche da parte dell’utente (se si segue la licenza GPL).

Le immagini da usare con i CSS devono essere ottimizzate. Se usate le icone, è preferibile impiegare le sprite CSS per ridurre al minimo le richieste GET.

Se si utilizzano invece dei Web font per generare le icone, il peso complessivo dei file dovrà essere limitato. Si tenga presente che un Web font viene rilasciato in diversi formati (TTF, SVG, EOT ecc.).

In questo caso la regola da seguire è semplice: inserire il codice CSS e JavaScript solo dove è richiesto e non in tutto il sito Internet. Se sappiamo ad esempio che il nostro codice verrà usato solo nei custom post type di tipo prenotazioni possiamo scrivere:

if( is_singular( ‘prenotazioni’ ) ) { wp_register_script( ‘booking’, plugins_url() . ‘/my-plugin/js/booking.min.js’, false, ‘1.0’, true ); wp_enqueue_script( ‘booking’ ); }

Gli script JavaScript andrebbero sempre inseriti prima della chiusura dell’elemento <body> per velocizzare il caricamento delle pagine. Ecco perché usiamo l’ultimo parametro della funzione wp_register_script() impostato su true. Inoltre, se non possiamo limitare l’uso del codice a sezioni specifiche, è sempre buona norma creare un namespace per il codice CSS e JavaScript usando i prefissi per evitare conflitti, ad esempio:

#my-plugin-booking-form { }

In JavaScript:

(function( $ ) { $.MyPluginBooking = {}; //… })( jQuery );

Le ambiguità generano rallentamenti, perché i browser devono comunque risolverle, mentre la specificità implica velocità.

Sicurezza

Sicurezza nella personalizzazione e gestione di un sito WordPress

Press any key: l'utente ideale e l'utente reale

Un aneddoto molto in voga che si racconta a proposito degli utenti finali è quello del "Press any key" e dell'avvertenza che recita "Non esiste il tasto Any". L'aneddoto vuole ricordare che non è possibile conoscere in anticipo il livello tecnico degli utenti, quindi occorre adottare una strategia di tipo "difensivo".

Quando si crea un plugin di WordPress è necessario tenere in considerazione che:

  • i nostri utenti potrebbero avere una laurea in informatica o essere degli "analfabeti" informatici;
  • quello che per noi è scontato ed intuitivo, per un utente potrebbe essere contorto e complesso;
  • gli utenti vogliono usare il plugin da subito.

Stiamo quindi parlando degli utenti reali e non di quelli "ideali". Sulla base di tali osservazioni, quello che possiamo fare in concreto è:

  • creare un'interfaccia semplice ed intuitiva basandosi sull'approccio "Less is more";
  • usare delle etichette chiare ed autoesplicative;
  • spiegare brevemente in ogni sezione delle opzioni a cosa serve quella pagina;
  • fornire una o più pagine di documentazione;
  • fornire una o più pagine con le risposte alle domande frequenti (FAQ);
  • fornire un form di contatti per inoltrare una richiesta di supporto.

Inclusione del codice JavaScript e CSS

WordPress opera una distinzione tra il codice lato client inserito nel backend e quello inserito nel frontend, ossia nella sezione amministrativa e nel sito. Sono quindi presenti due action distinte:

  • admin_enqueue_scripts
  • wp_enqueue_scripts

La prima action è per il backend, la seconda per il frontend. Anche se i loro nomi potrebbero trarre in inganno, queste due action servono per includere i file JavaScript e CSS, come nell'esempio seguente:

function add_js() {
    wp_register_script( ‘my’, plugins_url() . ‘/plugin/js/my.js’ );
    wp_enqueue_script( ‘my’ );
}
add_action( ‘wp_enqueue_scripts’, ‘add_js’ );

// importazione stili
function admin_style() {
   wp_register_style( 'norisys-archive-admin', plugin_dir_url( __FILE__ ).'norisys-archive-admin.css' );
   wp_enqueue_style( 'norisys-archive-admin' );
}
add_action('admin_enqueue_scripts', 'admin_style');

In questo caso le funzioni di WordPress da utilizzare sono quelle elencate di seguito:

wp_register_script()
wp_enqueue_script()
wp_register_style()
wp_enqueue_style()
wp_script_is()
wp_style_is()

Per gli autori di plugin, anche se può sembrare strano, le funzioni più importanti per scrivere plugin flessibili sono le ultime due: servono infatti a verificare che uno script o un file CSS non sia già stato incluso. A questo proposito immaginiamo il caso in cui un tema usi il framework JavaScript jQuery, scenario molto comune. Il seguente codice ci eviterà di compromettere il frontend:

if( !wp_script_is( ‘jquery’ ) ) {
    wp_enqueue_script( ‘jquery’ );
}

WordPress dispone di molti script preinstallati, tra cui il già citato jQuery; in questo caso, dato che il nostro plugin usa jQuery, prima di includerlo dobbiamo verificare che non sia già presente.

Struttura del codice JavaScript

WordPress, specialmente con jQuery, spinge gli autori ad usare un namespace per il proprio codice JavaScript; a tal proposito avrete sicuramente osservato questo modo di usare jQuery in WordPress:

(function( $ ) {
    // codice
})( jQuery );

Si tratta di una funzione self-executing che assegna alla variabile $ l’oggetto

In questo modo possiamo usare jQuery direttamente con il suo alias.

In JavaScript quando usiamo questo pattern creiamo una sandbox in cui il nostro sorgente può sì operare sulle pagine ma resta isolato dal resto del codice JavaScript presente nel sito Web.

Questo fattore è fondamentale, dato che noi non possiamo sapere se i nomi delle nostre variabili, delle funzioni e degli oggetti siano stati già usati da qualche altro script, in un plugin o dal tema.

Struttura del codice CSS

Il principio della creazione di un namespace per il nostro codice si applica anche ai CSS con una fondamentale differenza: nei CSS i prefissi sono l’unico sistema. Possiamo aggiungere un prefisso ai selettori di classe e di ID in questo modo:

#mioplugin-container { … }
.mioplugin-item { … }

mioplugin è il nostro prefisso che non solo ci mette al riparo da possibili conflitti, ma permette anche agli autori ed agli utenti di modificare i nostri stili con maggiore facilità.

Una volta creato un namespace possiamo sfruttare il contesto creato dai selettori per definire regole più specifiche:

#mioplugin-container .mioplugin-item a { … }

API, filtri e hook

API, filtri e hook per la creazione dei plugin di WordPress

Creare tabelle custom

Creare tabelle custom con i plugin di WordPress

Creare la voce di sottomenu

Creare la voce di sottomenu per un plugin di WordPress