Una applicazione web e' un programma che ha come formato di output principale
l'HTML. La generazione di HTML e' pertanto una parte importante nella scrittura di applicazioni web: programmatori e web framework cercano di risolvere il problema in vari modi dagli albori della web programing.
Alcuni linguaggi di programmazione quali il PHP hanno addirittura fatto della semplicita' di interpolazione tra l'HTML e i frammenti di programma uno dei loro punti di forza. Qual'e' ad oggi il modo migliore per generare l'HTML? Segue una
descrizione dei principali metodi e del perche' e' cambiato qualcosa
di importante nel contesto delle applicazioni web che determina la superiorita'
di uno di questi metodi.
Approcci diversi
I metodi piu' importanti per generare l'HTML sono i seguenti:
- Generazione tramite template
- Generazione per interpolazione
- Generazione tramite funzioni di output
- Generazione per traduzione da un formato piu' astratto
Questi metodi vengono a volte utilizzati assieme, in particolare
la generazione tramite template e' spesso associata ad un metodo diverso.
Generazione tramite template
L'idea del template e' quella di avere un pezzo di HTML valido,
separato dal programma, che contiene all'interno dei riferimenti
che indicano dove sostituire il contenuto reale per generare l'HTML
finale.
Ad esempio il seguente frammento di HTML potrebbe essere un template:
<div>Nome: <span class="name">%name%</span></div>
<div>Cognome: <span class="surname">%surname%</span></div>
Il compito della applicazione e' quello di caricare tale template
da un file (dal DB, o da qualunque altra parte) e sostituire i
markers con il contenuto reale:
la stringa
%name% sara' sostituita con il nome di una persona, e cosi'
via per il cognome e per le altre eventuali parti da riempire con contenuto.
Il template separa fisicamente l'HTML dal codice della applicazione
e rende editabile la parte HTML anche da chi non ha alcuna competenza
di programmazione. Poiche' offre questo vantaggio e perche' **fino a qualche anno fa assurdi layout fatti con le tabelle e la necessita' di specificare
gli attributi di stile direttamente dentro i tag rendevano la produzione dell'HTML dall'interno della applicazione un incubo** il template e'
stato considerato per un po' di tempo
The Right Thing in relazione
alla produzione di HTML.
Tanto e' vero che ancora oggi e' considerato un buon sistema, ma...
Il modo in cui scriviamo l'HTML grazie ai CSS e all'XHTML e' cambiato
profondamente. La struttura logica della pagina non e' piu' strettamente
legata al suo aspetto, per tale ragione i sistemi di produzione dell'HTML
alternativi sono ad oggi una soluzione piu' pratica e potente dei template.
I template hanno profondi limiti. Nelle applicazioni
web piu' complesse non si tratta soltanto di sostituire contenuti
in posizioni prestabilite. Liste, tag cloud e molti altri elementi
di una pagina vengono prodotti partendo da alcuni dati e nulla piu'
e in questi casi ovviamente i template non aiutano o finiscono per
diventare un incubo di piccoli frammenti di HTML da editare singolarmente.
Interpolazione
L'interpolazione tra codice ed HTML e' la tecnica spesso usata in applicazioni
PHP, per cui quest'ultimo ha supporto diretto tramite la sintassi <? ?>.
Immagino che tutti coloro che stanno leggendo questo articolo sanno
di cosa si tratta. Il codice PHP viene miscelato e/o emette direttamente l'HTML. Per i grossi
blocchi si usa appunto la sintassi <? ?> che se ci pensate un po'
su non e' antro che
zucchero sintattico per chiamate alla funzione echo().
Per le parti piu' brevi viene utilizzata la funzione
echo()
direttamente. Molti programmi PHP generano l'HTML piu' o meno cosi' (non ho provato il codice, e' solo un esempio):
<h1>Evviva lo spaghetti code</h1>
<?
$a = Array("pomo","pera","arancio");
foreach ($a as $ele) {
$bold = (strlen($ele) > 4) ? 1 : 0;
if ($bold) echo("<b>");
echo (htmlentities($ele));
if ($bold) echo("</b>");
echo("<br/>");
}
?>
<small>Copyright (C) 2007 BlaBlaBla</small>
Anche se e' facile e immediato purtroppo
questo non e' un buon modo di programmare perche' non scala. Quando l'output da produrre diventa
complesso e' difficilissimo editare questo tipo di codice, si rischia sempre di non chiudere un tag e a colpo d'occhio la struttura dell'HTML che viene generato non e' evidente. Bisogna seguire i tag uno ad uno.
Inoltre la produzione dell'HTML e' sparpagliata in tutto il codice.
Se ad un certo punto si decide di emettere <strong> invece di <b> bisogna
controllare ogni parte in cui c'e' un <b> e modificarla. Non c'e' alcuna
centralizzazione nel modo in cui l'HTML viene prodotto.
Eppure questo modo di scrivere il codice e' molto diffuso: e' la cosa
piu' immediata che si possa fare, per piccole applicazioni finisce per
funzionare, e la semplificazione che ha visto l'HTML negli ultimi
anni ha fatto diventare questo tipo di programmazione piu' gestibile nel lungo termine: basta emettere un po' di DIV e SPAN in relazione al contesto e poi lasciare
tutto il lavoro sporco ai CSS. Tuttavia e' sconsigliabile utilizzare
questa tecnica, ecco l'alternativa.
Generazione tramite funzioni di output
L'idea di base e' quella di produrre l'output utilizzando delle funzioni
che generano precisi elementi HTML. Solo tali funzioni avranno la necessita'
di
sporcarsi le mani con l'HTML, tutto il resto del codice chiamera'
le funzioni di generazione. Un semplice esempio in PHP:
function ul($content) {
return "<ul>$content</ul>";
}
function li($content) {
return "<li>$content</li>";
}
function div($content) {
return "<div>$content</div>";
}
$a = Array("pomo","pera","arancio");
$list = "";
foreach ($a as $ele) {
$list .= li(htmlentities($ele));
}
echo(div(ul($list)));
Il codice ora e' piu' chiaro, anche se abbiamo reso l'HTML generato piu'
articolato rispetto
all'esempio dell'interpolazione. Non puo' accadere
di dimenticare tag aperti o fare altri errori di markup, e abbiamo un
singolo set di funzioni per modificare in maniera centralizzata il modo in cui produciamo tutto l'HTML della applicazione.
Le funzioni proposte sono solo un esempio. Nello specifico quelle che utilizzo nelle mie applicazioni sono implementate in maniera generalizzata (finiscono per essere molto simili tra di loro a parte qualche eccezione)
e permettono di passare una lista variabile di attributi inizialmente,
ad esempio:
$mydiv = div("id","foo","class","bar",$content);
produce qualcosa come
<div id="foo" class="bar"> ... content ... </div>
Purtroppo il PHP non e' abbastanza potete da rendere l'annidamento piu' semplice come invece accade in Ruby:
require "cgi"
cgi = CGI.new("html3") # add HTML generation methods
cgi.out{
cgi.html{
cgi.head{ "\n"+cgi.title{"This Is a Test"} } +
cgi.body{ "\n"+
cgi.form{"\n"+
cgi.hr +
cgi.h1 { "A Form: " } + "\n"+
cgi.textarea("get_text") +"\n"+
cgi.br +
cgi.submit
}
}
}
}
Anche in questo caso i Ruby blocks mostrano la loro potenza. L'unica restrizione e' che ogni blocco restituisca una stringa, per cui
all'interno del blocco ci potrebbero essere anche dei cicli o altre
strutture di controllo complesse.
Se usate il PHP dovete accontentarvi (come sempre) ma almeno avrete
fatto un bel passo avanti rispetto alla generazione diretta dell'HTML.
Credo che ad oggi questo sia il miglior modo per generare HTML. In passato non era esattamente fattible, avete presente la complessita' dei layout a tabelle e tutti gli hack necessari per far funzionare le cose in ogni browser? Non rendeva le cose molto pratiche e se c'era da cambiare un colore bisognava andare a toccare il codice sorgente della applicazione! Oggi per fortuna e' diverso, ma
sarebbe stato ben difficile gestire codice simile al seguente:
font("color","#ff0000","face","Verdana","Attento! Questo codice e' una m...da");
Se questo e' a mio avviso il metodo di riferimento per generare HTML ne esiste pero' un quarto fondamentale in certe applicazioni: la creazione di un linguaggio di piu' alto livello che viene tradotto in HTML.
Conversioni di formato
Tutto sommato l'HTML e' tedioso da generare. Pensate ad esempio ai
form, ci sono sempre le stesse cose da scrivere, gli stessi controlli
da fare sull'obbligatorieta' e la formattazione dei campi.
E' possibile rendere le cose piu' rosee creando funzioni di piu' alto
livello che usano quelle di creazione dell'HTML viste sopra per avere
un nuovo layer di astrazione, ma a volte viene proprio la
tentazione di inventare un formato piu' semplice che venga tradotto
in HTML in maniera automatica. Ad esempio in questo blog quando scrivo
un post e voglio fare una lista invece di scrivere a mano i tag
ul
e
li mi basta scrivere cosi':
Questa e' una lista:
. uno
. due
. tre
. e quattro
Mentre questa **e' una scritta in bold**
Ecco come viene reso dal programma che implementa questo blog:
Questa e' una lista:
Mentre questa
e' una scritta in bold
Chiaramente e' molto meno tedioso da scrivere a mano rispetto all'utilizzo
diretto dell'HTML. Questa strategia di generazione dell'HTML e'
assolutamente vincente quando bisogna trasformare in HTML l'input
che proviene dall'utente: in queste circostanze non e' necessario disporre della piena potenza
dell'HTML, e' molto piu' importante riuscire a rappresentare in
maniera immediata alcuni elementi pre impostati.
In alcune applicazioni che generano nella pagina piu' o meno sempre lo stesso tipo di elementi questo sistema di generazione potrebbe essere benissimo esteso al programma stesso. In questo caso bisogna creare
una funzione che traduce il nostro nuovo
linguaggio di descrizione della pagina in HTML. Il linguaggio puo' essere specializzato molto
in relazione al dominio della nostra applicazione.
Ad esempio se la nostra applicazione ha molto a che fare con i tag
e' pensabile che il testo
Questi sono tre tag: [blog],[web],[html]
produca direttamente tag che sono degli
span con la giusta
classe ed un link alla pagina in cui vengono listate le risorse
relative a quel tag.
Questo approccio ha sicuramente la sua validita', anche se puo'
essere opportuno utilizzarlo solo quando l'applicazione finisce
per generare un output che e' composto da sotto parti identificabili
in maniera chiara. Inoltre e' opportuno implementare appositi meccansimi
di caching perche' la traduzione dal nuovo linguaggio all'HTML potrebbe
essere abbastanza dispendiosa in termini di CPU.
Quando invece si deve implementare un wiki, un blog, o un sistema di
commenti, la traduzione da un formato piu' semplice all'HTML e'
praticamente una scelta obbligata oltre che conveniente.
Questa tecnica e' l'unica tra quelle proposte che ha il vantaggio
della reale astrazione dal formato di output.
Se domani voglio implementare la possibilita' di scaricare gli articoli
in formato PDF in questo blog non avro' da passare dall'HTML, potro'
generare il formato finale in maniera diretta traducendo il post in PDF
invece che in HTML.