Articoli Manifesto Tools Links Canali Libri Contatti ?
Abstract
Come integrare make con WPP per semplificarsi la vita. Veloce introduzione ai makefiles per gli utenti di WPP.
Data di stesura: 20/02/2003
Data di pubblicazione: 19/04/2003
Ultima modifica: 04/04/2006
di Adam Byrtek Discuti sul forum   Stampa

Ho cercato per molto tempo una buon preprocessore HTML open source. Ho avuto modo di provare diverse soluzioni, ma nessuna di queste si adattava alle mie esigenze. Volevo qualcosa di semplice, facile da imparare ma al contempo potente e flessibile, uno strumento su cui potessi avere il pieno controllo. Per essere concisi - qualche cosa in stile con lo spirito di Unix. Trovai in WPP la risposta alle mie esigenze. È ben progettato ed è possibile estenderlo. Ha alcune funzionalità integrate che sono estremamente importanti per lo sviluppo in abito web, tutto il resto può essere facilmente ottenuto tramite l'inclusione di codice Perl nelle pagine da preprocessare. Il manuale di WPP è disponibile sul sito del progetto (http://wpp.sf.net).

Questo articolo non è un tutorial su WPP. Se volete imparare le basi di WPP andate a leggere il manuale sul suo sito [2]. Questo documento è una raccolta di note su come integrare make e WPP per semplificarvi la vita. Descriverò il processo di creazione di un Makefile da zero, anche se la sintassi di make vi è già familiare, potreste trovare alcuni spunti e trucchi interessanti procedendo nella lettura.

Introduzione

Generare un sito web con WPP è molto simile alla compilazione di un programma. Ci sono dei files "raw" (sorgenti) e dei documenti html (analoghi al codice oggetto) generati dalla trasformazione dei "raw" files tramite wpp. In questa metafora è praticamente naturale l'adozione del tool make della GNU per lavorare con WPP e semplificare la "compilazione" dei propri siti. Ho intenzione di mettere in luce i seguenti vantaggi che derivano dall'uso di make:

  • Risoluzione delle dipendenze: solo i files modificati o la modifica di uno o più files da cui dipendono, sono rigenerati, questo è estremamente comodo specie quando il sito è composto da numerose pagine.
  • La sintassi dei Makefiles è estremamente potente e flessibile. È necessario spendere un po' di tempo per crearli, ma una volta fatti le cose diventano molto più veloci, basta lanciare make ed il resto va da sé.
  • Make è un tool standard e molto diffuso. Perché reinventare la ruota? Tutto quello che imparate ora potrebbe tornare utile in futuro. I Makefiles possono essere molto complicati, in questo articolo presenterò solo alcune funzionalità di base, se volete saperne di più vi suggerisco di leggere le pagine in formato "info" del manual di make. Sono disponibili anche on-line sul sito GNU: http://www.gnu.org/manual/make-3.80/

Regole di base

WPP è uno strumento comodo ma quando il sito su cui state lavorando diventa progressivamente più grande diviene anche più difficile operare delle modifiche. È necessario ricordarsi di rigenerare ogni file a mano con wpp dopo ogni modifica, è sufficiente dimenticarsi ciò per avere un sito non aggiornato se non addirittura con degli errori. Questo può non essere un problema per un sito personale (home page), ma è sicuramente una cosa più grave in siti dove non ci si può permettere questo genere di sviste (ad esempio quelli di una societa`). Inoltre la mia pigrizia mi porta a cercare di ridurre le operazioni di manutenzione al minimo, il più semplici possibili. Per fortuna, come vedremo più avanti in questo articolo, con l'aiuto di make questo compito può essere facilmente automatizzato.

Prima di tutto è necessario creare un file che si chiami Makefile (o makefile) nella directory principale del vostro progetto. Quando viene eseguito il comando make le informazioni contenute in questo file verranno usate per rigenerare tutti i files destinazione (html) a partire dai sorgenti (raw) quando questi o le loro dipendenze risultino modificati (in realtà viene usata la data di modifica del file).

Ogni makefile contiene in una serie di regole. Ogni regola è definita da elementi base così:

target : dipendenze ...
  commandi
  ...

Ricordate che ogni linea dei "comandi" è preceduta da un carattere di tabulazione (tab), NON sono spazi! Inserire degli spazi, un errore comune da chi è alle prime armi con make, è causa dell'errore di "missing separator".

Target è il file di destinazione o un alias (una sequenza a piacere di caratteri, come "all", "full"). Le dipendenze sono i sorgenti da cui generare il target. Quando uno di questi cambia è possibile eseguire l'intero target e lanciare i "comandi" per rigenerarlo. Se una delle dipendenze ha un suo target nel Makefile questo verrà eseguito prima di quello chiamato. Ricordate che che quando si esegue make bogus il target "bogus" viene invocato, make senza argomenti richiama il primo target (default).

Nei Makefiles si possono definire delle variabili usando la sintassi VARIABILE="valore". Da quella linea in poi ogni occorrenza di $(VARIABILE) verrà sostituita con "valore".

Un semplice makefile per WPP (nella sua configurazione standard) localizzato nella directory dove sono i "raw" files potrebbe esser fatto così:

# definizione di una variabile
WPP=/usr/bin/wpp

# prima regola (default), senza comandi
all : ../about.html ../index.html

# regola: come creare about.html
../about.html : about.raw config
    $(WPP) about.raw

# regola: come creare index.html
../index.html : index.raw config templates/logo.tmpl
    $(WPP) index.raw

Scommetto che avete già indovinato che tutto quello che segue il carattere '#' è un commento, ignorato da make. Cercherò di spiegare come opera questo primo makefile:

  • Comincia con il target 'all', il primo target, ne guarda le dipendenze.
  • Esiste il target '../about.html', quindi lo analizza:
    • Se almeno uno dei files 'about.raw' o 'config' è stato modificato esegue il comando '/usr/bin/wpp about.raw' per rigenerare '../about.html'.
  • Esiste il target '../index.html', quindi lo analizza:
    • Se almeno uno dei files 'index.raw' o 'config' è stato modificato esegue il comando '/usr/bin/wpp index.raw' per rigenerare '../index.html'.
  • Torna al target 'all' e termina perché non ci sono comandi e altre dipendenze da vagliare.

Regole di pattern

Per fare in modo di aggiornare il sito dopo aver modificato uno o più raw files serve solo eseguire make. Ma ci sono alcuni svantaggi, il nostro makefile richiede la modifica manuale ogni volta che aggiungiamo un nuovo file serve inserire la rispettiva regola. Questo diviene progressivamente più scomodo al crescere del sito da mantenere. Per fortuna si può ovviare a questo problema usando le regole di pattern matching di make:

all: ../index.html ../about.html

# regola per creare TUTTI gli html dai raw
../%.html : %.raw
  @wpp -x $<

Il target di default "all" semplicemente afferma che il nostro sito consiste in due files. La seconda regola è usata per rigenerare ogni file il cui nome cominci per '../' e termini con '.html' (nell'esempio sono sia ../index.html che ../about.html). Afferma anche che "../file.html" dipende dal sorgente "file.raw", quando questo risulti modificato il file di destinazione verrà ricostruito con il comando "wpp -x file.raw" ("$<" è una variabile predefinita che contiene il nome della prima dipendenza). Il carattere "@" davanti al comando serve a far si che make non stampi il comando a video prima dell'esecuzione dello stesso.

Funzioni

A questo punto, dopo aver aggiunto un nuovo file bisogna aggiornare tutte le dipendenze della regola "all", non serve creare nuove regole. Ma noi siamo pigri e vogliamo qualche cosa di più, vogliamo evitare di ricordare di dover aggiornare qualsiasi cosa. Ovviamente è possibile, ma richiede alcune modifiche al nostro makefile:

DSTDIR = ../html
WPP = wpp -D DEFAULT_OUTPUTDIR=$(DSTDIR)

# lista di tutti i .raw nella directory corrente
SRC = $(subst ./,, $(shell find -name "*.raw"))
# lista di tutti gli html che vogliamo creare in DSTDIR
DST = $(addprefix $(DSTDIR)/, $(SRC:.raw=.html))

all : $(DST)

$(DSTDIR)/%.html : %.raw
  $(WPP) $<

Come potete notare per rendere il makefile più flessibile è stata definita una variabile addizionale chiamata DSTDIR che contiene il nome della directory di destinazione. WPP ha bisogno di conoscerne il valore tramite DEFAULT_OUTPUTDIR (cfr. la sezione 4 del manuale di WPP). Inoltre sono state usate alcune caratteristiche di make che non sono state menzionate precedentemente: le funzioni. Ogni chiamata funzione si presenta in questo modo:

$(funzione argomenti)

All'inizio è stata usata la funzione "shell" per passare il comando "find -name '*.raw'" alla shell. Come probabilmente saprete il comando stampa una lista dei files che terminano con .raw nell'intera gerarchia di directories, partendo da quella corrente. L'output dovrebbe somigliare a questo:

./index.raw
./about.raw
./contact/email.raw

Make si occupa di convertire i terminatori di linea in spazi ma è necessario rimuovere il "./" dall'inizio di ogni valore. Questo può essere ottenuto tramite la funzione "subst":

$(subst from,to,text)

Questa funzione sostituisce ogni occorrenza di "from" all'interno della stringa "text" con la stringa "to". In questo modo abbiamo assegnato nella variabile SRC la lista di tutti files .raw presenti nella directory corrente. Non possiamo usarla nel target di default perché dovremmo mettere i files .html (non i .raw). Da notare che non possiamo usare "find" per cercare i .html perché potrebbero non esistere ancora.

Usando $(SRC:.raw=.html) possiamo sostituire il suffisso '.raw' con '.html' in ogni parola contenuta nella variabile SRC, i valori modificati vengono ritornati e possono essere assegnati ad un'altra variabile. Tuttavia i files di destinazione sono in DSTDIR, usiamo "addprefix" per aggiungere il prefisso "$(DSTDIR)/" prima di ogni parola nella lista ritornata. Ecco come viene ottenuta DST.

Ora possiamo usare $DST per le dipendenze del target di default.

# default rule
all : $(DST)

Dipendenze automatiche

Potremmo finire qui. Ma cosa succede se viene modificato qualche template in uso in qualche file? E se viene riscalata un'immagine che è usata da WPP tramite la macro @HTML_IMAGE@ per determinarne automaticamente le dimensioni?

In questo caso il comando make mostrerà questo messaggio:

make: `all' is up to date.

Questo perché  make conosce solo le dipendenze dirette dei files html nella regola 'all': i raw files. Non sa nulla dei templates, delle immagini, dei file di configurazione di WPP o qualsiasi altro documento che può influenzare l'output di WPP. Dobbiamo dire a make ogni dipendenza, non volendolo fare a mano è possibile ricorrere allo switch "-d" di WPP:

-d, --depend    Generate dependencies for make.

Sembra che l'autore abbia previsto quello che stiamo cercando di ottenere! Questa opzione forza WPP a guardare in ogni file e mostrare ogni immagine usata o (opzionalmente) ogni link locale via RURL. Genera anche le dipendenze verso i files di configurazione ed i templates. L'output generato è nel formato di make:

../html/l5k/index.html: \
  Config \
  TEMPLATES/head.tmpl \
  ../html/portal.gif \
  ../html/index.raw

Il carattere "\" alla fine di una riga serve per indicare che questa continua sotto. A questo punto potremmo copiare direttamente le dipendenze nel nostro makefile ma sarebbe una perdita di tempo qualora si dovesse rigenerarle, meglio tenere il tutto in un file separato per poterlo aggiornare solo quando serve:

# rule to build 'Makefile.dep', alias 'dep'
Makefile.dep dep :
  @$(WPP) -d $(SRC) > Makefile.dep

Oltre a questo serve aggiungere un'istruzione include Makefile.dep alla fine del makefile in modo da utilizzare le dipendenze generate. Il target si chiama "Makefile.dep" così da essere invocato automaticamente qualora make non trovasse il file delle dipendenze. L'alias "dep" serve per abbreviare qualora voleste forzare la rigenerazione delle dipendenze con il comando make dep.

Cleaning up

Adesso avete un sistema perfettamente funzionante basato su make. Alla fine possiamo aggiungere un'ultima regola la quale verrà usata per rimuovere ogni file generato nella directory di destinazione (attenzione: controllate la correttezza del comando altrimenti rischiereste di perdere files importanti!):

clean :
  find $(DSTDIR) -name "*.html" -exec rm -f {} \;

Ora potrete digitare make clean per rimuovere ogni file non necessario e liberare un po' di spazio o rigenerare l'intero sito "ex novo".

Questo è tutto, spero che la maggior parte dei semplici "trucchi" inclusi in questo documento vi siano d'aiuto e possano semplificare di molto la gestione del vostro sito con WPP.
"May the Source be with You!"

Informazioni sull'autore

Adam Byrtek, studente, vive a Cracovia, Polonia e va in università solo quanto è realmente necessario. È un sostenitore dell'Open-Source, sviluppatore in Debian, ha contribuito a diversi progetti Open-Source. È anche un freelance web designer. Appassionato di letteratura e vela.

È possibile consultare l'elenco degli articoli scritti da Adam Byrtek.

Altri articoli sul tema Web / Preprocessori / WPP.

Risorse

  1. L'articolo originale in inglese.
    http://www.siforge.org/articles/2003/04/19-wpp-tekst-en.html
  2. WPP Web Site.
    http://wpp.sf.net/
  3. GNU Make: Manuale
    http://www.gnu.org/manual/make-3.80/
Discuti sul forum   Stampa

Cosa ne pensi di questo articolo?

Discussioni

Questo articolo o l'argomento ti ha interessato? Parliamone.