Web Template in PHP

31 agosto 2007 webdev

Perché ci sono così tante librerie di templating in PHP quando la loro utilità è pressoché nulla?

Uno dei difetti che viene rimproverato al PHP è che… è semplice. La semplicità deriva dal fatto che in origine era un semplice “hypertext preprocessor”, ovvero aveva lo stesso ruolo delle SSI (Server Side Include) per facilitare l’inclusione di pezzi di codice ripetitivo all’interno di diverse pagine HTML. Dalla semplice gestione di variabili si è poi passati a cicli, controlli di flusso e così via fino all’interfacciamento nativo con i database, programmazione a oggetti, etc.

Questa semplicità di inserire comandi all’interno del codice HTML, unita alla crescente complessità del linguaggio, ha portato negli anni passati a produrre molti script PHP in cui erano presenti sia la logica di funzionamento che la struttura del documento; non usando i CSS ci avremmo trovato anche il codice di presentazione.

La produzione di questo codice in stile spaghetti non è assolutamente proponibile per progetti seri, poiché porta facilmente a perdere il bandolo della matassa, senza avere nessuna linea guida per lo sviluppo e la manutenzione del codice prodotto.

Sentita la necessità di mettere ordine, molti hanno prodotto librerie (sotto forma di classi) che permettono di separare la parte logica da quella di struttura, senza bisogno di arrivare agli estremi di una completa implementazione del pattern MVC. L’esempio forse più conosciuto di libreria per template è Smarty, ma le soluzioni a disposizione dello sviluppatore sono numerosissime… e tutte ugualmente inutili.

Non sono a favore del “codice spaghetti” ma, come detto sopra, il PHP è già un motore di templating. Non c’è bisogno di aggiungere niente. Questo lo dice anche chi una libreria di templating l’ha realizzata (Beyond The Template Engine).

Gli argomenti contro l’adozione di una libreria sono semplici:

  1. overhead: qualunque libreria si voglia utilizzare, sarà comunque del codice ulteriore da dover caricare e interpretare (spesso molto codice);
  2. sintassi: bisogna imparare tutta una serie di nuovi comandi che sono specifici della libreria utilizzata e, in alcuni casi, sono complicati quanto il PHP stesso;
  3. lentezza: alcune di queste librerie, tra cui Smarty, sono talmente pesanti che per ottenere prestazioni dignitose si è obbligati a usare un meccanismo di caching.

Tutto questo per avere quali vantaggi?

  1. scrivere qualcosa come {$variabile} invece di <?=$variabile?>
  2. ?

Non credo che ne valga la pena.

Una soluzione

Per alcuni dei miei progetti ho sfruttato le possibilità del PHP per “includere” il template subito dopo aver elaborato i dati. Faccio un esempio: nel codice PHP vengono impostate alcune variabili come $titolo , $descrizione , $prezzo , $immagine, poi si include un file che contenga l’intero template con un’istruzione

include 'template.php';

al cui interno ci sarà l’HTML della pagina con alcuni piccoli pezzi di codice php per fare l’echo delle variabili precedentemente impostate.

I vantaggi sono evidenti:

  • il file template.php non è altro che un file HTML al cui interno vengono messe le istruzioni per espandere le variabili, quindi estrema velocità tra la fase di progettazione del web-designer e l’implementazione da parte del programmatore;
  • l’ubicazione del file di template può essere facilmente inserita all’interno di un file di configurazione richiamato da tutti i file PHP, ottenendo così una gestione centralizzata dell’aspetto del sito;
  • in forza del punto precedente, è possibile passare ad una nuova versione del sito cambiando solo una riga di codice (anzi, di meno: cambiando solo il nome di un file);
  • nessun overhead;
  • nessun nuovo “linguaggio” da imparare.

A riprova della bontà di questo approccio, un CMS per blog del calibro di Wordpress utilizza proprio questo tipo di approccio e c’è da considerare che gran parte del suo successo è dovuto proprio all’immensa quantità di template disponibili. La quantità di template per Wordpress è così elevata perché è facile realizzarli.

Il sistema di template basato sugli include si presta anche ad una facile scalabilità per adattarsi a nuove esigenze. Non è detto, infatti, che il template debba risiedere in un unico file; si possono prevedere dei file header.php e footer.php fissi e poi una serie di template diversi per il corpo centrale della pagina, magari differenti per ogni sezione del sito. Si può utilizzare un template per la home page, uno per la scheda prodotto e uno per gli articoli delle news; in ogni file PHP, a seconda del lavoro che deve eseguire, si inseriranno i due template “fissi” e il template “corpo” adeguato, ad esempio:

include 'header.php';
include 'prodotto.php';
include 'footer.php';

Se il programmatore si accorge di avere una barra di navigazione che è diventata troppo complessa, può decidere di estrapolarla dal template principale e metterla in un file tutto suo. Produrrà così un template naviga.php e lo inserirà dove ne ha bisogno:

include 'header.php';
include 'naviga.php';
include 'prodotto.php';
include 'footer.php';

Qui sta al progettista considerare se usare sempre un file template monolitico o suddividerlo in “parti” da assemblare.

È interessante notare che anche siti del calibro di “A Lista Apart” si sono dedicati all’argomento (Manage Your Content With PHP).

Questa soluzione al templating, oltre che efficiente, è anche molto semplice. Forse è per questo che alcuni non la considerano “professionale”. C’è infatti in molti la tendenza a confondere la complicazione con la potenza. Questo succede solo quando non si hanno le cognizioni per giudicare qualcosa in base alle sue effettive caratteristiche.

Si può obiettare che, anche volendo evitare lo “spaghetti code” separando la logica dalla struttura, il file di template conterrà codice PHP come ad esempio cicli for..next. Questa è un’obiezione stupida.

Se tolgo tutto il codice PHP dal template, poi come faccio a mostrare i risultati? L’HTML ovviamnte non è un linguaggio di scripting. Nel template il codice PHP ci deve essere, è l’ultimo anello del progetto.

Lo scopo del templating non è di separare brutalmente il codice PHP dal codice HTML, ma di separare la “logica” di uno script dalla “struttura e presentazione” di una pagina web. Uno script PHP serve, ad esempio, ad estrapolare un elenco di prodotti da un database, mettere il risultato in un array e passare l’array al template. Il codice PHP nel template (ad esempio un ciclo while) si occuperà di stamparlo a video. Quindi il codice che sta nel template non decide niente ma ha il solo scopo di spedire al browser i risultati in una forma leggibile, ad esempio una lista ordinata o una tabella prodotto-prezzo.

Se vi sono delle istruzioni decisionali nel template (come può essere un if...then...else) sarà sempre a puro scopo di “struttura e/o presentazione”, non di elaborazione dati. Posso ad esempio decidere con un if se è il caso di stampare un messaggio di testo in colore rosso in base al valore di una variabile $err che mi segnala che è un messaggio di errore. Tutto qui. Questo codice deve stare nel template, è una caratteristica visuale, se lo mettessi nello script farei un errore perché lo script deve solo elaborare i dati, non decidere come presentarli. Nello script posso solo decidere se impostare la variabile $err al valore 1 (per “errore”) o 0 (per “tutto ok”).

È un po’ come dire che lo script prepara gli ingredienti e il template li cucina.

Buon appetito.

Commenti

12/12/2008 15:29 - GREY_FOX

Ciao, Ho trovato molto interessante questo articolo e sotto vari punti di vista hai pienamente ragione. Una cosa non comprendo…. perchè non separare dall’html anche il rendering del risultato offerto dallo script php che tratta la parte logica? In questo modo si può decidere se cambiare il rendering di un insieme di dati senza andare ad intaccare il template…

12/12/2008 17:18 - **Scaracco**

Se per rendering intendi l’aspetto visuale, allora certamente questo va fatto con i CSS. Il template ha la funzione di unire i dati con l’HTML:

lo script genera/estrae i dati e li passa al template; il template unisce i dati all’interno della struttura HTML; il CSS imposta la visualizzazione (layout, tipografia, ecc.)

13/12/2008 17:36 - GREY_FOX

grazie per la risposta. Sei stato molto esaustivo ma io intendevo separare il rendering nel senso… se abbiamo la necessità di riportare sotto forma tabellare dei dati esportati della parte logica perchè non creare una libreria/funzione a parte riutilizzabile e facilmente sostituibile solo cambiando la chiamata alla funzione all’interno dell’html? spero di essere stato chiaro.

Grazie per i chiarimenti :)

14/12/2008 06:21 - **Scaracco**

Le mie obiezioni all’uso di una libreria di funzioni (o addirittura una classe) per il templating le hai già lette nel post.

Se poi la sviluppi da solo è un vero guaio: ti assorbirà una buona parte del tempo dedicato al progetto dell’intero sito/applicazione. Già una sola funzione, tanto flessibile da adattarsi a varie esigenze, può diventare molto complessa.

Personalmente ho trovato più semplice e produttivo modificare direttamente il template, magari facendone uno diverso per una particolare sezione del sito, piuttosto che sviluppare (e mantenere!) un altro pezzo di codice.

14/12/2008 16:33 - GREY_FOX

grazie ora credo di aver capito. Sei stato molto gentile, scusa se ti ho disturbato :)

Ciao!

17/03/2009 08:50 - schirone

sei stato molto convincente. Penso di adottare la tua filosofia. Potresti fare un esempio minimale di quello che dici? Mi sarebbe molto utile per cominciare! Grazie

8/06/2012 22:09 - Francesco

Verissimo. Dopo 4 ore passate a capire come funziona zend studio con pattern mvc mi sono detto: a che scopo? Poi ho trovato questo bellissimo post in cui anche tu esponi gli stessi miei dubbi. I template mvc vanno bene per asp.net, ma php proprio no!