Creare temi WordPress è un arte che richiama molte competenze perché non sempre basta essere bravi in HTML e CSS e “cavarsela” con quel tanto di PHP che basta.
In questo articolo ti guido alla scoperta di come poter gestire il caricamento del nostro tema in modo da poter applicare le proprie modifiche andando a selezionare granularmente la sezione di nostro interesse.
Se sviluppi con WordPress da diverso tempo dovresti già aver incontrato la gerarchia dei temi e queste conoscenze ti saranno fondamentali per poter comprendere meglio le informazioni che troverai più in basso.
Questo perché in questo articolo studierai degli esempi abbastanza avanzati e se non ti ricordi che WordPress ha una serie di file che carica in base alla pagina visualizzata rischi di confonderti.
Come ormai dovresti sapere, la logica di WordPress si basa sugli Hook che ci permettono di agganciarci a determinate azioni o eventi che accadono durante la generazione della nostra pagina HTML.
In questo articolo andremo proprio a conoscere quelli che ci permettono di personalizzare quando la gerarchia e quando la possibilità di caricare o meno il template intero.
Ti chiedi forse del perché fare una cosa del genere? Andiamo a scoprire il primo Hook che ti svelo questo primo particolare.
Evita il caricamento del template con template_redirect
Questo è un Action Hook che viene eseguito prima ancora che venga determinato quale template il nostro utente ha scelto di visualizzare e ci permette di impedirne il caricamento.
Forse sei un po’ confuso. Perché mai dovresti impedire il caricamento del template che hai costruito con tanto sforzo?
Oggi WordPress è ben lontano dall’essere una semplice piattaforma di blogging come alla sua nascita, piuttosto siamo parlando di un CMS completo!
Infatti un Action Hook come template_redirect
ci può tornare comodo quando abbiamo bisogno che la nostra piattaforma risponda ad una determinata richiesta senza neanche dover caricare il template.
Molto spesso ci troviamo di fronte a questa situazione quando usiamo le WordPress REST API dove la richiesta che viene inviata al nostro server invoca template_redirect
per la creazione dell’oggetto JSON terminando successivamente la sessione.
Praticamente si ottengono le informazioni contenute nel nostro database senza neanche dover mettere in moto il motore di template che WordPress ha al suo interno, questo si traduce in un’ottimizzazione dei processi e prestazioni migliori per l’utente finale.
Un altro esempio dell’utilizzo di questa funzione è quello di poterla utilizzare per cacciare gli utenti non loggati da una pagina specifica, magari una pagina dove condividiamo del contenuto soltanto con i nostri iscritti!
add_action( 'template_redirect', function() { if ( !is_user_logged_in() && is_page( 'contenuto-privato' ) ) { wp_redirect( wp_login_url() ); exit(); } });
Se sei rimasto a bocca aperta dal fatto che sia presente una funzione come secondo parametro del nostro add_action()
non devi assolutamente agitarti.
Queste si chiamano funzioni anonime e sono state introdotte in PHP dalla versione 5.3. Sono molto utili perché, un po’ come accade in JavaScript, ci permettono di scrivere meno codice e l’organizzazione rispecchia da vicino la logica di utilizzo dato che vengono create ed eseguite nel momento stesso in cui vengono trovate.
Avresti potuto anche creare questo controllo senza l’uso di template_redirect
, magari ti saresti appoggiato all’azione the_post
ma così facendo avresti lasciato che WordPress caricasse tutto il tema e di conseguenza avresti rallentato l’esperienza del tuo utente, tutto per venir poi buttato fuori ?
Individua parti singole del tuo template
Sono sicuro che ti sarai trovato a lavorare con dei plugin scritti bene che, oltre a popolare il backend della nostra piattaforma, ci permettono di avere la parte del frontend già popolata e con diversi stili applicati ad esse.
Sforzati per un attimo… Sono convinto che te ne viene in mente almeno uno.
Non ce la fai?
Va bene ti tolgo la fatica, uno di questi è WooCommerce.
Se ci fai caso, una volta installato questo plugin hai le pagine Prodotto, Carrello e molte altre già presenti nel tuo tema e già personalizzate da regole CSS.
Eppure nella cartella del tuo tema non è presente un single-product.php
o un page-car.php
.
Come hanno fatto ad inserire queste pagine?
Ebbene hanno usato un Filter Hook di WordPress davvero interessante che cambia il nome dinamicamente in base alla pagina che stiamo cercando di visualizzare!
Se vogliamo dargli un nome generico possiamo chiamarlo type_template
ma sono sicuro che con un esempio più concreto la sua funzionalità sarà più chiara.
Prendiamo la classica pagine dove viene mostrato un singolo articolo, come ormai dovresti sapere WordPress sceglie di utilizzare il file single-post.php
, la cosa che non sapevi ancora è che usa proprio questo stesso filtro per prendere la sua decisione.
Trovi questo filtro all’interno del core WordPress dove, grazie a un semplice ciclo, è in grado di comprendere il tipo di pagina che vogliamo visualizzare creando automaticamente il filtro single-post_template
.
Tornando all’esempio di WooCommerce, anche se non sono andato a controllare il suo codice sorgente, posso immaginare che all’interno del suo plugin si trovi qualcosa del genere:
add_filter( 'single-product_template', function( $template ){ if ( !$template ) { $template = dirname( __FILE__ ) . '/templates/single-product.php'; } return $template; });
Praticamente WooCommerce sta dicendo a WordPress che prima ancora di andare a cercare il file che fornisce struttura al suo CPT deve entrare all’interno della cartella templates/
presente nel plugin e caricare il file single-product.php
.
Questa è la stessa tecnica che ha implementato Daniele Scasciafratte nella creazione del suo WordPress Plugin Boilerplate Powered, praticamente usando la sua soluzione disponibile su GitHub puoi creare la struttura base del tuo plugin e tutte le pagine frontend di cui hai bisogno!
Una cosa da chiarire è che questa soluzione non è in grado di sovrascrivere la funzionalità interna di WordPress che riconosce le pagine all’interno della cartella del tema, ovvero i file template che creiamo per rispettare la sua gerarchia.
Questo succede perché se trova lo stesso file dentro la cartella del tema con lo stesso percorso, ovvero all’interno della cartella templates/
, andrà a caricare il file presente nel tema piuttosto che quello nel plugin.
E questa è una funzionalità incredibilmente interessante perché è proprio come WooCommerce e tutti i plugin che vengono sviluppati seguendo la WordPress Way ci offre la possibilità di sovrascrivere questi file con il tema che stiamo realizzando!
Prima di passare al prossimo Hook voglio chiarire un dubbio che forse precedentemente ti ha colpito: perché non uso la funzione is_singular()
per accertarmi che mi trovo effettivamente in una di queste pagine?
Ebbene grazie a questo filtro un controllo del genere è superfluo perché, dato che è creato dinamicamente nella logica di WordPress, verrà eseguito soltanto se si troverà a dover caricare quel tipo di pagina.
Sovrascrivi qualsiasi comportamento con template_include
Con il filtro che ti ho appena presentato hai conosciuto una soluzione che ti permette di comprendere quale file caricare in base alla pagina che viene visualizzata.
In un contesto come quello di WooCommerce, che ha bisogno di creare un gran numero di pagine e CPT per gestire le varie attività interne ad un eCommerce, questo fa anche molto senso.
Però non sempre è l’effetto che stiamo cercando, esistono dei casi dove vogliamo sovrascrivere completamente il file che stiamo caricando.
Facciamo un piccolo esempio che però ci è utile come esercizio di stile.
Diciamo che vuoi sviluppare un tema nipote.
Anche se questo non esiste all’interno delle definizioni WordPress, al massimo abbiamo i child theme, diciamo che hai bisogno di creare un child theme per un child theme.
In questo contesto utilizerai un plugin che si comorta come nipote. A questo punto, nel file principale del plugin, inserirai qualcosa come segue:
add_filter( 'template_include', function( $template ) { $percorso = explode('/', $template ); $template_scelto = end( $percorso ); $nipote_template = dirname( __FILE__ ) . '/' . $template_chosen; if ( file_exists( $nipote_template ) ) { $template = $nipote_template; } return $template; });
Praticamente con questo codice stiamo controllando quale sia il tema che WordPress sta caricando e una volta trovato il nome della cartella, controlliamo che all’interno del nostro plugin sia presente una cartella che porta lo stesso nome, se viene trovata verrà caricata questa al posto della cartella del tema principale.
Riconosco che il ragionamento è un po’ contorto ma è un esempio molto avanzato sul corretto uso del filtro template_include
.
Nella frase precedente ho parlato di uso corretto perché trovo questa funzione molto utilizzata per creare le pagine frontend dei nostri plugin, ma questo non è un uso corretto.
Dato che questo filtro viene lanciato come ultimo il nostro WordPress si troverà nella situazione di aver già eseguito tutti i cicli foreach
che gli hanno permesso di selezionare la pagina del tema che vuole caricare e questo colpisce non poco le nostre prestazioni.
Ho scelto di inserirti anche questo filtro per completezza del concetto ma stai bene attento a quando la utilizzi.
Chiediti sempre se c’è la possibilità di di utilizzare i filtri dinamici che abbiamo appena conosciuto, ti assicuro che le prestazioni del tuo WordPress ne beneficeranno.
Conclusioni
In questo articolo abbiamo parlato di tre Hook differenti che ti permettono di personalizzare il caricamento delle pagine del tuo tema, generalmente questi si usano con i plugin perché, come già detto, i tuoi temi possono sfruttare la gerarchia WordPress.
Se hai intenzione di utilizzare quanto appreso nella creazione di un tema e rilasciarlo nel repository WordPress non potrai utilizzare queste funzionalità perché vanno a modificare la logica della gerarchia dei file e questa non è un’attività consentita.
Alla fine poco importa perché le nozioni che hai appreso da questo articolo ti saranno incredibilmente utili per poter sviluppare dei prodotti professionali.
Spero che i concetti che ti ho appena presentato ti siano utili per il tuo lavoro.
Riconosco che sono delle nozioni più avanzate rispetto a quelle che generalmente condividiamo in questo blog ma farti crescere è l’obbiettivo di questo stesso sito e il mio desiderio è quello di supportarti in questo percorso sia attraverso la lettura di questi contenuti che attraverso i corsi esclusivi che pubblico.
Fammi sapere che ne pensi del materiale che hai appena seguito.
È stato troppo difficile da seguire?
Mi sono spiegato con i piedi?
Insomma qualsiasi siano le tue impressioni o il tuo feedback scrivi un commento e fammi conoscere la tua opinione.
Ricorda che credo fortemente che la vera crescita avviene soltanto attraverso il confronto ?
carlo dice
ottimo articolo Andrea!
ti segnalo che nell’ultimo esempio ci sono alcune variabili che prima hanno un nome (es. $percorso) e poi ne hanno un altro (es. $path) 🙂
Andrea Barghigiani dice
Ciao Carlo e grazie mille per questa correzione, non sai il piacere che provo quando i nostri lettori ci permettono di scoprire alcuni refusi. Oltre che migliorarne la qualità ci fa capire che leggete veramente i nostri lunghi articoli.
Grazie ancora e a presto,
Andrea