3 Approcci per aggiungere campi configurabili al plugin di WordPress

Pubblicato: 2022-03-10
Riepilogo rapido ↬ Chiunque abbia creato un plugin per WordPress comprende la necessità di creare campi configurabili per modificare il funzionamento del plugin. Esistono innumerevoli usi per le opzioni configurabili in un plug -in e quasi altrettanti modi per implementare tali opzioni. Vedi, WordPress consente agli autori di plugin di creare il proprio markup all'interno delle loro pagine delle impostazioni. Come effetto collaterale, le pagine delle impostazioni possono variare notevolmente tra i plugin. In questo articolo esamineremo tre modi comuni per rendere configurabile il tuo plug-in. Inizieremo creando una pagina delle impostazioni e creeremo i nostri campi utilizzando l'API delle impostazioni di WordPress predefinita. Ti illustrerò quindi come impostare i tuoi campi con un gestore personalizzato. Infine, ti mostrerò come integrare un ottimo plug-in per campi configurabili Advanced Custom Fields (ACF) nel tuo plug-in.

Chiunque abbia creato un plugin per WordPress comprende la necessità di creare campi configurabili per modificare il funzionamento del plugin. Esistono innumerevoli usi per le opzioni configurabili in un plug -in e quasi altrettanti modi per implementare tali opzioni. Vedi, WordPress consente agli autori di plugin di creare il proprio markup all'interno delle loro pagine delle impostazioni. Come effetto collaterale, le pagine delle impostazioni possono variare notevolmente tra i plugin.

In questo articolo esamineremo tre modi comuni per rendere configurabile il tuo plug-in. Inizieremo creando una pagina delle impostazioni e creeremo i nostri campi utilizzando l'API delle impostazioni di WordPress predefinita.

Ulteriori letture su SmashingMag:

  • Estendi WordPress con campi personalizzati
  • Hack di campi personalizzati per WordPress
  • Estendere i campi personalizzati avanzati con i tuoi controlli
  • La guida completa ai tipi di post personalizzati

Ti illustrerò quindi come impostare i tuoi campi con un gestore personalizzato. Infine, ti mostrerò come integrare un ottimo plug-in per campi configurabili Advanced Custom Fields (ACF) nel tuo plug-in.

Altro dopo il salto! Continua a leggere sotto ↓

Poiché questo è un post lungo, ecco un sommario con collegamenti a ciascuna delle sezioni principali:

  • Creazione della nostra pagina Plugin e Impostazioni
  • Approccio 1: utilizzo della funzionalità integrata di WordPress
  • Approccio 2: impostazione di un modulo e un gestore personalizzati
  • Approccio 3: integrazione di ACF (campi personalizzati avanzati) nel plug-in

Per esempi di codice, vedere il repository che ho impostato per accompagnare questo post.

Creazione del nostro plugin e pagina delle impostazioni

La prima cosa che dobbiamo fare è configurare il nostro plugin e creare una pagina delle impostazioni. Tutti e tre gli approcci descritti in questo articolo iniziano con la struttura del plug-in di seguito. Questa struttura del plugin è orientata agli oggetti, quindi potrebbero esserci alcune differenze nel tuo codice se il tuo plugin è scritto in modo procedurale. Prestare particolare attenzione al formato della funzione di richiamata nelle azioni e nei filtri.

 /* Plugin Name: Smashing Fields Plugin description: >- Setting up configurable fields for our plugin. Author: Matthew Ray Version: 1.0.0 */ class Smashing_Fields_Plugin { // Our code will go here } new Smashing_Fields_Plugin();

All'interno della nostra classe aggiungeremo un action hook per aggiungere la pagina delle impostazioni:

 public function __construct() { // Hook into the admin menu add_action( 'admin_menu', array( $this, 'create_plugin_settings_page' ) ); }

Puoi vedere che il callback della nostra azione è create_plugin_settings_page , quindi creiamo quel metodo. Nota: ho impostato gli argomenti come variabili denominate separate per dare un po' di contesto al nostro codice, ma puoi semplicemente inserire i valori direttamente nella funzione per risparmiare memoria.

 public function create_plugin_settings_page() { // Add the menu item and page $page_title = 'My Awesome Settings Page'; $menu_title = 'Awesome Plugin'; $capability = 'manage_options'; $slug = 'smashing_fields'; $callback = array( $this, 'plugin_settings_page_content' ); $icon = 'dashicons-admin-plugins'; $position = 100; add_menu_page( $page_title, $menu_title, $capability, $slug, $callback, $icon, $position ); }

Dai un'occhiata al codice WP per add_menu_page per ulteriori informazioni.

Questa funzione creerà la nostra pagina e la voce di menu. Le parti importanti qui sono gli argomenti slug, capacità e callback. Lo slug che useremo in seguito per registrare i nostri campi, quindi scrivilo da qualche parte. È possibile modificare la capacità per consentire a diversi livelli utente di accedere alla pagina delle impostazioni. Per quanto riguarda il callback, creeremo quel metodo a breve. Nota che puoi anche inserire una classe dashicon direttamente nella funzione per cambiare l'icona del menu. L'ultimo argomento è la posizione della voce di menu all'interno del menu; gioca con questo numero per trovare il punto nel menu in cui desideri che le tue impostazioni cadano. Nota: puoi utilizzare valori decimali per evitare conflitti con altre voci di menu.

Il nostro prossimo passo è creare il metodo di callback plugin_settings_page_content per la nostra pagina delle impostazioni.

 public function plugin_settings_page_content() { echo 'Hello World!'; }

Se salvi il plugin e aggiorni il pannello di amministrazione di WordPress dovresti vedere quanto segue:

Layout iniziale per la pagina delle impostazioni
Lo stato iniziale per la pagina delle impostazioni. (Visualizza versione grande)

Puoi vedere che la pagina delle impostazioni è una voce di menu di primo livello. Potresti preferire lasciarlo in questo modo in base alle esigenze della tua pagina delle impostazioni. Tuttavia, potresti anche voler avere le impostazioni del tuo plug-in in un'altra voce di menu. In questo caso cambierai semplicemente l'ultima riga del metodo create_plugin_settings_page come segue:

 add_submenu_page( 'options-general.php', $page_title, $menu_title, $capability, $slug, $callback );

Qui stiamo cambiando la funzione add_menu_page in add_submenu_page e anteponendo un nuovo argomento. Tale argomento è la voce di menu principale in cui si troverà la nuova pagina delle impostazioni. Nella documentazione add_submenu_page puoi vedere un elenco abbastanza buono per le voci del menu principale e i loro slug. Potresti anche vedere che non abbiamo più gli ultimi due argomenti, $icon e $position . Poiché ora siamo nella sezione del sottomenu, non abbiamo più il controllo sulla posizione dell'elemento. Inoltre, i sottomenu non hanno icone disponibili, quindi non c'è bisogno di quell'argomento.

Se salvi questo nuovo codice vedrai che la nostra pagina delle impostazioni verrà visualizzata sotto la voce di menu Impostazioni:

La pagina del sottomenu è ora nelle impostazioni
La pagina delle impostazioni è stata ora posizionata nel menu Impostazioni. (Visualizza versione grande)

In molti casi, il posto più appropriato per aggiungere una pagina delle impostazioni del plug-in è sotto la voce Impostazioni. Nel codice di WordPress viene spiegato che la sezione Impostazioni viene utilizzata per "Visualizzare le opzioni del plug-in che solo gli amministratori dovrebbero visualizzare". Tuttavia, questa è solo una linea guida, non una regola.

Ora che abbiamo impostato la nostra pagina delle impostazioni e sappiamo come spostare gli elementi, possiamo iniziare a lavorare sui campi. Il lavoro svolto finora verrà riutilizzato per i vari metodi di seguito.

Approccio 1: utilizzo della funzionalità integrata di WordPress

Prima di approfondire il codice, esaminiamo alcuni dei pro e dei contro dell'utilizzo di questo approccio.

Professionisti

  • Facile da integrare nelle pagine delle impostazioni esistenti
  • La sanificazione è fatta per te
  • Difficilmente si rompe poiché il codice è gestito da WordPress
  • Può essere utilizzato sia per temi che per plugin
  • Flessibile, sicuro ed estensibile

contro

  • La convalida dei dati personalizzati è manuale
  • I tipi di campo avanzati (ripetitori, mappe, caricamenti, ecc.) sono più difficili da implementare

Quando dovresti usare questo approccio?

Questo approccio è sufficientemente flessibile da poter essere personalizzato per pagine di impostazioni molto semplici o molto avanzate. Puoi usare questo metodo nella maggior parte delle situazioni se non ti dispiace fare alcune cose manualmente.

Iniziare

Utilizzando questo approccio dovremo seguire lo stesso markup utilizzato dalle pagine delle opzioni di WordPress. Dovremmo modificare il nostro metodo plugin_settings_page_content come segue:

 public function plugin_settings_page_content() { ?> <div class="wrap"> <h2>My Awesome Settings Page</h2> <form method="post" action="options.php"> <?php settings_fields( 'smashing_fields' ); do_settings_sections( 'smashing_fields' ); submit_button(); ?> </form> </div> <?php }

Il markup sopra è direttamente dal codice di WordPress sulla creazione delle pagine delle opzioni. Il nome del metodo dovrebbe corrispondere al nome di callback che abbiamo inserito nella funzione add_menu_page sopra. Il wrapper div è in realtà lo stesso di un modulo WordPress predefinito e inserirà gli stili da quelle sezioni. Il tag del form punta al gestore del modulo delle opzioni predefinito per WordPress.

Le tre linee di PHP fanno diverse cose:

  • La funzione settings_fields è fondamentalmente un riferimento per il resto dei nostri campi. L'argomento stringa che hai inserito in quella funzione dovrebbe corrispondere alla variabile $slug che abbiamo impostato in precedenza: sarà in tutti i campi che registreremo in seguito nel plug-in. Questa funzione emette anche alcuni input nascosti per il nonce, l'azione del modulo e alcuni altri campi per la pagina delle opzioni.
  • La prossima funzione, do_settings_sections , è un segnaposto per le sezioni e i campi che registreremo altrove nel nostro plugin.
  • L'ultima funzione, submit_button , produrrà l'input di invio, ma aggiungerà anche alcune classi in base allo stato della pagina. Potrebbero esserci altri argomenti che vorrai passare nella funzione submit_button ; sono delineati nel codice.

Se aggiorniamo la nostra pagina delle impostazioni, dovremmo ottenere qualcosa che assomiglia a questo:

Pagina delle impostazioni di WordPress vuota
La nostra pagina delle impostazioni prima di registrare sezioni e campi.

Sembra un po' scarno! Iniziamo ora a configurare i campi.

Sezioni e campi

WordPress separa le sue pagine delle opzioni in sezioni. Ad ogni sezione può essere associato un elenco di campi. Dobbiamo registrare una sezione nel nostro plugin prima di poter iniziare ad aggiungere i nostri campi. Aggiungi il codice seguente alla tua funzione di costruzione:

 add_action( 'admin_init', array( $this, 'setup_sections' ) );

Questo hook imposterà le sezioni per la nostra pagina. Ecco il codice per la richiamata:

 public function setup_sections() { add_settings_section( 'our_first_section', 'My First Section Title', false, 'smashing_fields' ); }

Il primo argomento è un identificatore univoco per la sezione e lo useremo per i campi che desideriamo assegnare alla sezione. Questi identificatori dovrebbero essere univoci per tutte le nuove sezioni di questa pagina. L'argomento successivo è il titolo che viene generato sopra la sezione: puoi farlo come vuoi. Il terzo argomento è il callback. In questo momento l'ho impostato su false , ma lo rivisiteremo a breve. Il quarto argomento è la pagina delle opzioni a cui verranno aggiunte le opzioni (la variabile $slug di prima).

Allora perché c'è un false nella nostra richiamata? Bene, qualcosa che non è molto chiaro quando si impostano le opzioni di WordPress utilizzando la loro documentazione è che più sezioni possono condividere una richiamata. Spesso, quando si imposta una richiamata, esiste una relazione 1 a 1 tra l'hook e la richiamata. Quindi, solo per un esempio, proviamo a creare tre sezioni con la stessa richiamata:

 public function setup_sections() { add_settings_section( 'our_first_section', 'My First Section Title', array( $this, 'section_callback' ), 'smashing_fields' ); add_settings_section( 'our_second_section', 'My Second Section Title', array( $this, 'section_callback' ), 'smashing_fields' ); add_settings_section( 'our_third_section', 'My Third Section Title', array( $this, 'section_callback' ), 'smashing_fields' ); }

Tutte e tre queste sezioni hanno il callback section_callback impostato in quel terzo slot di argomenti. Se quindi creiamo un metodo che corrisponda a quella richiamata e rilasciamo un "Hello World" lì:

 public function section_callback( $arguments ) { echo '

Ciao mondo

'; }

otteniamo qualcosa che assomiglia a questo:

Tre sezioni che condividono la stessa funzione di richiamata
Tre sezioni che condividono la stessa richiamata.

So cosa stai pensando, "Perché diavolo dovrei voler avere lo stesso testo in tutte le mie sezioni?" La risposta è che probabilmente non lo faresti. È qui che possiamo diventare un po' complicati con la funzione add_settings_section . Se guardi la documentazione per quella funzione vedrai che nella parte Note della pagina alla funzione di callback verrà assegnato un array di argomenti che sono direttamente correlati agli argomenti nel nostro hook. Se entri e var_dump( $arguments ) vedrai tutti gli argomenti che vengono passati nella nostra funzione.

Possiamo quindi scrivere un semplice interruttore nella nostra richiamata per modificare il testo in base all'ID che viene passato in esso:

 public function section_callback( $arguments ) { switch( $arguments['id'] ){ case 'our_first_section': echo 'This is the first description here!'; break; case 'our_second_section': echo 'This one is number two'; break; case 'our_third_section': echo 'Third time is the charm!'; break; } }

Ora abbiamo un testo personalizzato per ogni sezione che possiamo modificare in una funzione!

Testo personalizzato in ogni sezione
Testo personalizzato in ogni sezione.

Ovviamente puoi specificare callback univoci anche per queste sezioni, ma questo approccio ti consente di consolidare il tuo codice in un'unica funzione. Questa idea funziona allo stesso modo per l'impostazione dei campi. Possiamo fare in modo che tutti i nostri campi condividano un callback e che restituisca il tipo di campo corretto in base agli argomenti che passiamo. Aggiungiamo i campi al nostro metodo di costruzione. Inserisci questo codice subito dopo che le nostre sezioni si agganciano nel costruttore:

 add_action( 'admin_init', array( $this, 'setup_fields' ) );

Dato che conosci già il trapano, ti richiamo solo per la nostra azione:

 public function setup_fields() { add_settings_field( 'our_first_field', 'Field Name', array( $this, 'field_callback' ), 'smashing_fields', 'our_first_section' ); }

Gli argomenti in questa funzione sono simili a quelli nella funzione sezioni. Il primo argomento è l'identificatore univoco per il campo. La seconda è l'etichetta che compare accanto al campo. Nel terzo argomento puoi vedere che sto chiamando il metodo field_callback ; creeremo quella richiamata in un secondo. La quarta è la pagina delle opzioni che vogliamo usare (il nostro $slug di prima). Il quinto argomento è l' identificatore univoco per la sezione a cui vogliamo assegnare questo campo.

Ecco il codice per il callback nel nostro terzo argomento:

 public function field_callback( $arguments ) { echo '<input name="our_first_field" type="text" value="' . get_option( 'our_first_field' ) . '" />'; }

Qui sto semplicemente copiando l'identificatore univoco del campo nel nome, nell'ID e nella nostra funzione get_option . Vediamo come appare la nostra pagina con il nostro nuovo campo allegato:

La nostra pagina delle impostazioni con il nostro primo campo.
La pagina delle impostazioni con il nostro primo campo allegato.

Fantastico, abbiamo il nostro campo sulla pagina! Prova ad aggiungere del contenuto e a salvare le modifiche, aspetterò qui...

Lo hai fatto? Se hai fatto tutto fino a questo punto, dovresti aver ricevuto un errore che dice qualcosa come ERROR: options page not found o simile. Il motivo per cui ciò accade è in realtà una funzionalità di sicurezza in WordPress.

Vedete, senza questa funzione, un utente potrebbe entrare nell'HTML e cambiare il nome di un campo in qualsiasi cosa volesse, premere salva, e inserirebbe quell'opzione nel database con qualunque nome gli fosse stato assegnato (supponendo che fosse un nome opzione). Ciò potrebbe consentire a qualsiasi utente di modificare le opzioni su altre pagine (anche quelle a cui normalmente non potrebbero accedere) semplicemente inserendo il nome corretto nel campo e premendo Salva, non interessante.

Questo problema viene risolto aggiungendo una funzione chiamata register_setting . A meno che tu non dica specificamente a WordPress "Ehi, questo campo può essere salvato in questa pagina", WordPress non aggiornerà un campo nel database. Quindi, sotto il nostro markup del campo, aggiungeremo questa nuova funzione. Ecco come appare la richiamata dopo aver aggiunto il codice:

 public function field_callback( $arguments ) { echo '<input name="our_first_field" type="text" value="' . get_option( 'our_first_field' ) . '" />'; register_setting( 'smashing_fields', 'our_first_field' ); }

Il primo argomento nella nuova funzione è la pagina delle opzioni su cui vogliamo salvare il campo (lo $slug di prima) e il secondo argomento è il campo che vogliamo salvare. Ora prova ad aggiornare il campo: ha funzionato!

Congratulazioni! Hai appena salvato il tuo primo campo utilizzando l'API delle impostazioni di WordPress. E se volessimo avere alcuni tipi di campo diversi invece del solo testo? Rivisitiamo il nostro callback sul campo e parliamo di quella variabile $arguments che viene passata nella nostra funzione.

Argomenti sul campo

Se entriamo nel nostro campo callback e var_dump( $arguments ) otterremo un array vuoto. Cosa dà? Nella nostra richiamata di sezione abbiamo un sacco di cose sulla sezione. Bene, qui sta succedendo qualcosa di diverso. Se controlli la documentazione per add_settings_field , c'è un quinto argomento che può essere passato nella funzione. Quella variabile è direttamente correlata alla variabile $arguments nella nostra callback. Quindi vorremo mettere le nostre nuove cose lì dentro.

Se osserviamo uno dei campi predefiniti in una pagina delle impostazioni di WordPress, possiamo vedere che ci sono diverse aree che possiamo aggiungere al nostro campo per ottenere una formattazione predefinita. Ecco uno screenshot del campo del fuso orario nella pagina delle impostazioni generali:

Il campo del fuso orario di WordPress
Il campo del fuso orario di WordPress. (Visualizza versione grande)

Utilizzando questo campo come punto di partenza, esaminiamo i dati che vogliamo passare al nostro campo di callback.

  • L'identificatore univoco
  • L'etichetta per il campo (Fuso orario nell'esempio)
  • In quale sezione dovrebbe entrare
  • Il tipo di campo (testo, textarea, select, ecc.)
  • Nel caso in cui ci siano più opzioni, le vorremo
  • Forse un segnaposto se il tipo di campo ne supporta uno
  • Testo di supporto (a destra del campo nell'esempio)
  • Testo supplementare (sotto il campo nell'esempio)
  • Forse una selezione predefinita se ce n'è una

Da questo elenco possiamo impostare un array associativo di campi e valori che possiamo passare al nostro callback:

 public function setup_fields() { $fields = array( array( 'uid' => 'our_first_field', 'label' => 'Awesome Date', 'section' => 'our_first_section', 'type' => 'text', 'options' => false, 'placeholder' => 'DD/MM/YYYY', 'helper' => 'Does this help?', 'supplemental' => 'I am underneath!', 'default' => '01/01/2015' ) ); foreach( $fields as $field ){ add_settings_field( $field['uid'], $field['label'], array( $this, 'field_callback' ), 'smashing_fields', $field['section'], $field ); register_setting( 'smashing_fields', $field['uid'] ); } }

Quindi la prima cosa che abbiamo qui è una variabile chiamata $fields che conterrà tutti i campi che vogliamo creare. All'interno di quell'array abbiamo un altro array che contiene i dati specifici per ogni campo. Ho impostato i dati in modo che corrispondano esattamente al nostro elenco sopra. Quindi, eseguo ogni campo (ne aggiungeremo altri a breve) nell'array, aggiungo il campo e lo registro. Alla fine della funzione add_settings_field sto anche aggiungendo l'intera matrice di dati per quel campo specifico in modo da poter fare alcune cose nella funzione di callback. Diamo un'occhiata a quella funzione di callback qui:

 public function field_callback( $arguments ) { $value = get_option( $arguments['uid'] ); // Get the current value, if there is one if( ! $value ) { // If no value exists $value = $arguments['default']; // Set to our default } // Check which type of field we want switch( $arguments['type'] ){ case 'text': // If it is a text field printf( '<input name="%1$s" type="%2$s" placeholder="%3$s" value="%4$s" />', $arguments['uid'], $arguments['type'], $arguments['placeholder'], $value ); break; } // If there is help text if( $helper = $arguments['helper'] ){ printf( '<span class="helper"> %s</span>', $helper ); // Show it } // If there is supplemental text if( $supplimental = $arguments['supplemental'] ){ printf( '<p class="description">%s</p>', $supplimental ); // Show it } }

Nell'esempio sopra, stiamo facendo diverse cose. Stiamo impostando i valori predefiniti per i campi se sono vuoti e aggiungendo l'helper e il testo supplementare. La parte più importante del nostro codice, tuttavia, è l'istruzione switch. In questa affermazione delineeremo come verranno gestiti i nostri argomenti in base al tipo di campo che vogliamo.

Ad esempio, se abbiamo un campo di testo, non abbiamo bisogno di avere più opzioni. Tuttavia, un menu a discesa <select> deve avere opzioni per funzionare correttamente. Poiché disponiamo di tipi di testo già impostati, eseguiamo questo codice e vediamo cosa otteniamo.

Il nostro campo è stato compilato con segnaposto
Il nostro campo è stato compilato includendo il testo segnaposto. (Visualizza versione grande)

Quando carichi la pagina delle impostazioni del plugin dovresti vedere il campo in alto in questa immagine. Il fondo è quello che vedrai se rimuovi il contenuto dal campo (cioè il segnaposto). Se dovessi rimuovere gli argomenti helper o supplimental dal nostro array di campi, dovrebbero scomparire nella pagina delle impostazioni. Possiamo anche cambiare l'argomento della section e spostarci nella posizione del campo nelle sezioni.

OK, quindi abbiamo campi di testo; che ne dici di alcuni tipi di campo più complessi? Diamo un'altra occhiata alla nostra istruzione switch e aggiungiamo l'opzione per le aree di testo e le selezioni singole:

 switch( $arguments['type'] ){ case 'text': // If it is a text field printf( '<input name="%1$s" type="%2$s" placeholder="%3$s" value="%4$s" />', $arguments['uid'], $arguments['type'], $arguments['placeholder'], $value ); break; case 'textarea': // If it is a textarea printf( '<textarea name="%1$s" placeholder="%2$s" rows="5" cols="50">%3$s</textarea>', $arguments['uid'], $arguments['placeholder'], $value ); break; case 'select': // If it is a select dropdown if( ! empty ( $arguments['options'] ) && is_array( $arguments['options'] ) ){ $options_markup = '; foreach( $arguments['options'] as $key => $label ){ $options_markup .= sprintf( '<option value="%s" %s>%s</option>', $key, selected( $value, $key, false ), $label ); } printf( '<select name="%1$s">%2$s</select>', $arguments['uid'], $options_markup ); } break; }

Nel codice sopra noterai diverse differenze tra ciascuno dei tipi di campo. Sebbene le aree di testo siano funzionalmente simili ai normali campi di testo, richiedono un markup diverso. Seleziona i menu a discesa sono un altro animale a causa delle opzioni. Dobbiamo scorrere le opzioni e impostare valori, stati selezionati ed etichette. Quindi il nostro markup è drasticamente diverso.

Ora che abbiamo aggiornato la nostra funzione di callback, vediamo come sono cambiati i dati del campo:

 $fields = array( array( 'uid' => 'our_first_field', 'label' => 'Awesome Date', 'section' => 'our_first_section', 'type' => 'text', 'options' => false, 'placeholder' => 'DD/MM/YYYY', 'helper' => 'Does this help?', 'supplemental' => 'I am underneath!', 'default' => '01/01/2015' ), array( 'uid' => 'our_second_field', 'label' => 'Awesome Date', 'section' => 'our_first_section', 'type' => 'textarea', 'options' => false, 'placeholder' => 'DD/MM/YYYY', 'helper' => 'Does this help?', 'supplemental' => 'I am underneath!', 'default' => '01/01/2015' ), array( 'uid' => 'our_third_field', 'label' => 'Awesome Select', 'section' => 'our_first_section', 'type' => 'select', 'options' => array( 'yes' => 'Yeppers', 'no' => 'No way dude!', 'maybe' => 'Meh, whatever.' ), 'placeholder' => 'Text goes here', 'helper' => 'Does this help?', 'supplemental' => 'I am underneath!', 'default' => 'maybe' ) );

Ecco tre campi, ognuno dei quali utilizza un diverso tipo di campo nel nostro plugin. Il primo che abbiamo già esaminato. Il secondo è il nostro nuovo campo textarea . Possiamo passare gli stessi parametri con l'array (con l'eccezione dell'UID), ma una semplice modifica al nostro tipo e otterremo invece una textarea . L'ultimo campo in questa matrice è il menu a discesa di selezione. L'aggiornamento principale qui è l'aggiunta dell'array di opzioni. Aggiungiamo un semplice array associativo con la chiave dell'array come valore dell'opzione HTML e l'etichetta. Utilizzando questo array, ecco come appaiono i nostri campi:

La nostra pagina delle impostazioni dopo che i campi sono stati compilati
La nostra pagina delle impostazioni con i campi. (Visualizza versione grande)

Quasi fatto!

Ora abbiamo una pagina delle impostazioni del plugin funzionante. Abbiamo impostato le sezioni per la pagina, le opzioni, tutti i callback e registrato i campi. L'unica cosa rimasta è ottenere i nostri valori di impostazione altrove. Che tu ci creda o no, l'abbiamo già fatto. Nella parte superiore del nostro campo di richiamata puoi vedere che stiamo verificando il valore del database:

 $value = get_option( $arguments['uid'] );

Possiamo usare lo stesso codice nel nostro plugin (o tema) e passare semplicemente l' uid nella funzione. Quindi, se volessi ottenere il valore del our_first_field , scriverei semplicemente:

 get_option('our_first_field')

Ehi presto! Abbiamo il nostro fantastico plugin e le nostre fantastiche impostazioni! Ovviamente abbiamo impostato solo alcuni tipi di campo, ma ho esaminato e aggiunto altri nel repository di codice per questo approccio (in particolare campi di testo, password, numeri, aree di testo, menu a discesa di selezione, selezioni multiple, pulsanti di opzione e caselle di controllo).

Approccio 2: impostazione di un modulo e un gestore personalizzati

In passato questo approccio era l'unico modo per aggiungere le pagine delle impostazioni. Prima di WordPress 2.7 gli autori dei plugin dovevano creare i propri moduli e gestori personalizzati. Questo ovviamente ha portato a molti bug e incongruenze tra i plugin. Sebbene questo approccio sia alquanto deprecato, in alcuni casi è ancora un'opzione praticabile.

Professionisti

  • Puoi inviare il modulo a gestori personalizzati e remoti
  • Puoi aggirare alcune delle restrizioni dell'API delle impostazioni integrate

contro

  • La compatibilità deve essere mantenuta dallo sviluppatore
  • Deve igienizzare e convalidare manualmente

Quando dovresti usare questo approccio?

Utilizzare questo approccio quando è necessario disporre assolutamente di un gestore personalizzato o di un'interfaccia altamente personalizzata. Probabilmente puoi cavartela con l'Approccio 1 nella maggior parte dei casi, ma hai maggiore flessibilità con la convalida e la gestione usando questo metodo.

Iniziare

Prima di entrare nei dettagli, dobbiamo creare uno scenario in cui utilizzeremmo un gestore personalizzato. Per semplicità, creiamo un modulo che verificherà un nome utente e un indirizzo email. Potremmo estrarre i dati da un database o anche da un server remoto. In questo caso, imposterò un array con nomi utente e indirizzi e-mail validi per il controllo. Quindi memorizzeremo i valori dei campi immessi dall'utente e li memorizzeremo nel database.

Creazione del modulo

Come ho detto prima, seguiremo gli stessi passaggi che abbiamo fatto in "Creazione del nostro plug-in e pagina delle impostazioni". Per questo approccio imposteremo i nostri campi usando il markup HTML statico. Aggiungeremo questo codice al callback dalla funzione plugin_settings_page_content questo modo:

 public function plugin_settings_page_content() { ?> <div class="wrap"> <h2>My Awesome Settings Page</h2> <form method="POST"> <table class="form-table"> <tbody> <tr> <th><label for="username">Username</label></th> <td><input name="username" type="text" value="" class="regular-text" /></td> </tr> <tr> <th><label for="email">Email Address</label></th> <td><input name="email" type="text" value="" class="regular-text" /></td> </tr> </tbody> </table> <p class="submit"> <input type="submit" name="submit" class="button button-primary" value="Check My Info!"> </p> </form> </div> <?php }

Puoi vedere sopra che stiamo solo aggiungendo dell'HTML statico per i nostri campi. Stiamo duplicando il markup dalle pagine delle impostazioni principali di WordPress. Stiamo anche omettendo l'azione del modulo in modo che invii il modulo alla pagina corrente anziché al gestore predefinito options.php .

Prima di scrivere il nostro gestore personalizzato, inseriamo alcune rapide funzionalità di sicurezza. La prima cosa che dovremmo fare è inserire un nonce nella nostra forma. Nonces proteggerà dai tentativi di falsificazione delle richieste tra siti, che è simile allo spoofing degli utenti o agli attacchi di riproduzione. Mettiamo il nonce nel nostro HTML:

 <form method="POST"> <?php wp_nonce_field( 'awesome_update', 'awesome_form' ); ?> <table class="form-table">

Il wp_nonce_field aggiungerà un paio di campi nascosti al nostro modulo; il nonce e il referrer. Torneremo al nonce quando esamineremo il codice del gestore.

Successivamente è necessario aggiungere un campo per rilevare quando il modulo è stato aggiornato. Possiamo farlo semplicemente aggiungendo un campo nascosto nella parte superiore del nostro modulo:

 <form method="POST"> <input type="hidden" name="updated" value="true" /> <?php wp_nonce_field( 'awesome_update', 'awesome_form' ); ?> <table class="form-table">

Ora possiamo inserire uno snippet di codice nella parte superiore della nostra pagina per rilevare quando il nostro modulo viene inviato e inviarci al nostro gestore personalizzato:

 public function plugin_settings_page_content() { if( $_POST['updated'] === 'true' ){ $this->handle_form(); } ?> <div class="wrap"> <h2>My Awesome Settings Page</h2>

Qui stiamo semplicemente controllando se il campo updated nascosto è stato inviato e, in tal caso, chiamiamo un metodo nel nostro plugin chiamato handle_form . È qui che possiamo iniziare a scrivere il nostro gestore personalizzato.

Creazione del gestore

Ci sono un paio di cose che dobbiamo controllare nel gestore prima di gestire effettivamente i dati del modulo. Dobbiamo prima verificare se il nostro nonce esiste ed è valido:

 public function handle_form() { if( ! isset( $_POST['awesome_form'] ) || ! wp_verify_nonce( $_POST['awesome_form'], 'awesome_update' ) ){ ?> <div class="error"> <p>Sorry, your nonce was not correct. Please try again.</p> </div> <?php exit; } else { // Handle our form data } }

Il codice sopra verifica che il nonce sia corretto. Se non è valido, diamo all'utente un messaggio sul motivo per cui il modulo non è stato aggiornato. Se il nonce esiste ed è corretto, possiamo gestire il nostro modulo. Scriviamo ora il codice per il nostro gestore di moduli (questo codice sostituirà il commento nello snippet sopra):

 $valid_usernames = array( 'admin', 'matthew' ); $valid_emails = array( '[email protected]', '[email protected]' ); $username = sanitize_text_field( $_POST['username'] ); $email = sanitize_email( $_POST['email'] ); if( in_array( $username, $valid_usernames ) && in_array( $email, $valid_emails ) ){ update_option( 'awesome_username', $username ); update_option( 'awesome_email', $email );?> <div class="updated"> <p>Your fields were saved!</p> </div> <?php } else { ?> <div class="error"> <p>Your username or email were invalid.</p> </div> <?php }

Esaminiamo il codice in questa sezione. Le prime due righe sono gli array di nomi utente/e-mail validi che verificheremo. Questi valori di matrice possono essere popolati da qualsiasi luogo.

Le prossime due righe sono i valori che il nostro utente ha inserito nel modulo. Stiamo utilizzando le funzioni di sanificazione integrate che ci offre WordPress. Questo passaggio è importante per evitare diverse vulnerabilità con i moduli Web. Successivamente, stiamo verificando se i valori forniti dagli utenti sono nella nostra matrice di valori accettabili. Se lo sono, aggiorna le opzioni del modulo nel database. Questo passaggio potrebbe anche essere sostituito con un meccanismo di archiviazione personalizzato. Stiamo anche dando all'utente un messaggio che i suoi campi sono stati salvati. Se l'input dell'utente non è valido, glielo diciamo.

L'ultima cosa che dobbiamo fare è mostrare i campi memorizzati nel modulo dopo che sono stati inseriti. Lo faremo nello stesso modo in cui recupereremo questi campi altrove nel plugin: con la funzione get_option . Ecco i campi dopo aver aggiunto il codice corretto:

 <tr> <th><label for="username">Username</label></th> <td><input name="username" type="text" value="<?php echo get_option('awesome_username'); ?>" class="regular-text" /></td> </tr> <tr> <th><label for="email">Email Address</label></th> <td><input name="email" type="text" value="<?php echo get_option('awesome_email'); ?>" class="regular-text" /></td> </tr>

Ora siamo pronti per testare il nostro modulo. Prova a inserire il nome utente admin e l'indirizzo email [email protected] . Dovresti ottenere quanto segue sul tuo modulo:

I campi salvati dopo aver inserito i valori corretti
I campi salvati dopo aver inserito i valori corretti. (Visualizza versione grande)

Se provi a impostare uno dei campi su un valore non valido, dovresti ricevere un messaggio di errore e i campi non dovrebbero aggiornarsi a causa del nostro gestore personalizzato.

Questo è tutto per il nostro secondo approccio! Ora hai impostato un modulo e un gestore personalizzati per gestire i campi del plug-in. Il codice completo per questo approccio è disponibile nel repository di questo articolo. Ora, passiamo al nostro approccio finale.

Approccio 3: integrazione di ACF (campi personalizzati avanzati) nel plug-in

Se non hai ancora utilizzato ACF di Elliot Condon, lascia che ti presenti. ACF è un meraviglioso field manager per WordPress. Una delle cose migliori è l'interfaccia di configurazione del campo. Rende abbastanza facile creare campi per un certo numero di pagine diverse all'interno di WordPress (come post, pagine, utenti, tassonomie, persino le proprie pagine di opzioni integrate). Potresti pensare "Non riesco a integrare il plug-in di qualcun altro nel mio - è losco!" ma il signor Condon comprende la difficile situazione dei suoi colleghi sviluppatori e ha pianificato questo nel suo plugin. È possibile visualizzare la sua documentazione su questo argomento, ma ne riproporrò alcuni qui. Andiamo oltre le regole.

  1. Innanzitutto, se stai distribuendo un plug-in gratuito, devi utilizzare la versione gratuita di ACF. Questo è così che le persone non possono ottenere la versione PRO dal tuo plug-in gratuito - non sarebbe bello. Puoi utilizzare la versione PRO in plugin e temi premium senza problemi, assicurati solo di acquistare la licenza per sviluppatori.
  2. In secondo luogo, non modificare le informazioni sul copyright di ACF. Dai un po' di credito all'uomo!
  3. Infine, non distribuire la chiave di licenza con il tuo plug-in.

Ora, i pro e i contro di questo approccio:

Professionisti

  • Molto facile da integrare in temi e plugin
  • Puoi sfruttare i campi avanzati che fanno parte di ACF
  • Il codice e gli aggiornamenti di sicurezza sono gestiti dal team ACF
  • ACF ha ottimi componenti aggiuntivi e supporto se rimani bloccato
  • La configurazione dei campi è semplicissima grazie all'interfaccia utente di configurazione dei campi

contro

  • Accesso limitato al markup
  • Crea una dipendenza per il tuo plugin o tema
  • Per mantenere aggiornato ACF devi tenerlo aggiornato nei tuoi file di plugin/tema (maggiori informazioni di seguito)

Quando dovresti usare questo approccio?

Quando si desidera creare un'interfaccia di impostazioni avanzate molto rapidamente e non è necessario personalizzare l'aspetto grafico.

Iniziare

For this approach I will show you how to set up the options page for the free version of ACF. To view a guide on setting up the PRO version check out the ACF documentation. To get started we will be adding ACF to our plugin directory. First, download the latest version of ACF and unzip its contents. In your plugin directory create a (Visualizza versione grande)

Again, we will follow the steps we did in “Creating Our Plugin And Settings Page”. Before we get into that, though, we should include ACF in our plugin.

Include ACF In Your Plugin

It's actually pretty easy to include ACF in your plugin – there are only three steps. First we have to include the main ACF file with PHP. Add the following code to the bottom of our constructor function:

 include_once( plugin_dir_path( __FILE__ ) . 'vendor/advanced-custom-fields/acf.php' );

If you refresh the admin you should see a new menu item titled Custom Fields . Before we go into that page and start setting up our fields we need to update a couple of paths in ACF. We need to tell ACF to look for its front-end assets and file includes in our plugin directory instead of its normal place. Add these two hooks to your constructor:

 add_filter( 'acf/settings/path', array( $this, 'update_acf_settings_path' ) ); add_filter( 'acf/settings/dir', array( $this, 'update_acf_settings_dir' ) );

And the callbacks for those hooks:

 public function update_acf_settings_path( $path ) { $path = plugin_dir_path( __FILE__ ) . 'vendor/advanced-custom-fields/'; return $path; } public function update_acf_settings_dir( $dir ) { $dir = plugin_dir_url( __FILE__ ) . 'vendor/advanced-custom-fields/'; return $dir; }

The first callback updates the include paths for the PHP files within the ACF plugin. The second updates the URIs for the ACF assets. Now we can set up our fields.

Configuring Your Fields

Now comes the fun part: the ACF field configuration UI. Add a title and any fields you'd like in your form. There is a great walkthrough of what everything on this page does in the ACF documentation. Here's how I have set up mine:

ACF fields configured
My ACF fields in the configuration UI. (Visualizza versione grande)

Once you are ready hit the Publish button on the right and your fields will be saved. Now we have to get the fields we set up into our plugin. Right now they only exist in the database. On the left-hand navigation, click the Tools item. On the new page, select the field group we just created and hit Generate Export Code . This will create a chunk of PHP code that we can now include in our plugin.

To add the options, we need to add a method call to our constructor. Add this line to the end of your constructor after our ACF include:

 $this->setup_options();

Then we can create the method that will wrap our options:

 public function setup_options() { if( function_exists( 'register_field_group' ) ) { register_field_group(array ( 'id' => 'acf_awesome-options', 'title' => 'Awesome Options', 'fields' => array ( array ( 'key' => 'field_562dc35316a0f', 'label' => 'Awesome Name', 'name' => 'awesome_name', 'type' => 'text', 'default_value' => ', 'placeholder' => ', 'prepend' => ', 'append' => ', 'formatting' => 'html', 'maxlength' => ', ), array ( 'key' => 'field_562dc9affedd6', 'label' => 'Awesome Date', 'name' => 'awesome_date', 'type' => 'date_picker', 'date_format' => 'yymmdd', 'display_format' => 'dd/mm/yy', 'first_day' => 1, ), array ( 'key' => 'field_562dc9bffedd7', 'label' => 'Awesome WYSIWYG', 'name' => 'awesome_wysiwyg', 'type' => 'wysiwyg', 'default_value' => ', 'toolbar' => 'full', 'media_upload' => 'yes', ), ), 'location' => array ( array ( array ( 'param' => 'options_page', 'operator' => '==', 'value' => 'smashing_fields', ), ), ), 'menu_order' => 0, 'position' => 'normal', 'style' => 'default', 'label_placement' => 'top', 'instruction_placement' => 'label', 'hide_on_screen' => ', 'active' => 1, 'description' => ', )); } }

Now that we have our fields ready to go, we can add them to the settings page.

Modifying The Settings Page Code

To add the fields we just created to the page we will need to update our plugin_settings_page_content method.

Previously, we set up the form tag for our page. In this case we will let ACF do that part for us. Here is what our updated function should look like:

public function plugin_settings_page_content() { do_action('acf/input/admin_head'); // Add ACF admin head hooks do_action('acf/input/admin_enqueue_scripts'); // Add ACF scripts $options = array( 'id' => 'acf-form', 'post_id' => 'options', 'new_post' => false, 'field_groups' => array( 'acf_awesome-options' ), 'return' => admin_url('admin.php?page=smashing_fields'), 'submit_value' => 'Update', ); acf_form( $options ); }

Le prime due righe della nostra funzione stanno aggiungendo gli script e gli stili di cui avremo bisogno per i campi delle impostazioni. Dopodiché stiamo configurando le opzioni per il nostro modulo. Potresti notare che il valore nell'argomento field_groups corrisponde all'ID della nostra funzione register_field_group . Per vedere gli altri parametri di configurazione dai un'occhiata alla documentazione acf_form . L'ultima riga della nostra funzione renderà effettivamente il modulo.

Se provi a caricare la pagina delle impostazioni ora, potresti vedere che la pagina è effettivamente rotta. Questo perché ACF ha bisogno di localizzare alcune variabili per JavaScript. Per fare ciò, dobbiamo aggiungere un altro hook al nostro costruttore:

 add_action( 'admin_init', array( $this, 'add_acf_variables' ) );

Ora dobbiamo impostare la richiamata:

 public function add_acf_variables() { acf_form_head(); }

Puoi provare ad aggiungere alcuni contenuti e salvare e dovrebbe funzionare proprio come i nostri altri due approcci. Ecco come dovrebbe essere la nostra pagina:

Modulo ACF finito
Il nostro modulo ACF compilato. (Visualizza versione grande)

Ci sono solo un paio di articoli per la pulizia di cui abbiamo bisogno:

  • Potresti voler nascondere il fatto che stai usando ACF per il tuo plugin. In questo caso, è necessario nascondere la voce di menu Campi personalizzati . Puoi farlo aggiungendo questo snippet alla tua funzione di costruzione:

     add_filter( 'acf/settings/show_admin', '__return_false' );
  • Dovremmo rimuovere la versione del database del nostro gruppo di campi. Basta andare alla sezione dei campi personalizzati e premere il pulsante del cestino. Questo passaggio è facoltativo poiché influirà solo sull'ambiente in cui hai creato il plug-in, ma potrebbe introdurre problemi se stai testando il plug-in nello stesso ambiente.

Utilizzo dei campi ACF all'interno del plug-in

Per ottenere i campi ACF che hai creato, devi semplicemente utilizzare la funzione get_field ACF predefinita. La prima opzione dovrebbe essere l'ID univoco per il campo e il secondo argomento impostato su 'option' . Ecco come otterremmo il campo Awesome Date :

 get_field( 'awesome_date', 'option' )

E questo è tutto. Ora hai impostato un plug-in con le impostazioni ACF! È possibile visualizzare il codice per questo approccio nel repository.

Conclusione

Quindi il gioco è fatto: tre modi per rendere configurabili i tuoi plugin. Mi piacerebbe conoscere i plugin che puoi creare usando questi metodi. Ancora una volta, ho creato un repository che ospita il codice per ciascuno di questi approcci. Sentiti libero di biforcarli e personalizzarli in base alle tue esigenze.

Per quanto riguarda le mie preferenze personali per questi approcci, tendo a propendere per l'Approccio 1. Preferisco mantenere il minor numero possibile di dipendenze nei miei plugin e puoi personalizzare il markup in base al tema della pagina delle impostazioni per i progetti personalizzati. Per prototipi rapidi o progetti in cui ho bisogno di impostare campi molto avanzati utilizzerò ACF, ma aggiunge un livello di complessità alla gestione degli aggiornamenti dei plugin.

Vale anche la pena ricordare la proposta di una Fields API di Scott Clark. Sebbene sia attualmente ancora in lavorazione, l'API consentirebbe essenzialmente agli sviluppatori di plugin e temi di utilizzare la stessa interfaccia dell'API di personalizzazione per creare campi delle impostazioni su altre aree del pannello di amministrazione.

Alternative ACF

Come sottolineato nei commenti qui sotto, e per offrire agli sviluppatori altre opzioni simili all'approccio ACF, puoi controllare alcune alternative che possono offrire funzionalità diverse. Se ne hai altri, inviali nei commenti qui sotto! Eccoli senza alcun ordine particolare:

  • CMB2 di WebDevStudios
  • Meta Box di Tran Ngoc Tuan Anh ( Rilwis )