Sei sulla pagina 1di 42

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

Guida a DRUPAL

Pi che una guida completa, riporto in queste pagine alcuni appunti su ci che ho potuto capire leggendo la Guida in linea in drupal.org e lavorando a questo e ad altri siti. Non nascondo che quando ho iniziato a lavorare con Drupal, ho avuto forti perplessit e difficolt a comprendere questo CMS. Ne esistevano altri pi intuitivi, meno tecnici. Per ne sentivo parlare molto bene e quindi sono andato avanti. L'approccio iniziale a Drupal quello di provare gli svariati temi disponibili, attivare modulli, leggere la documentazione ufficiale inglese (per me molto dispersiva) e quel poco che si trova in rete, in italiano, in siti e forum. Inizialmente ho girato dentro al codice cercando di capire come funzionasse, cercando di modificare i temi, arrabbiandomi quando le cose non funzionavano. Ma alla fine mi rendevo sempre conto di non sapere ancora bene dove mettere le mani. Mano a mano che capivo come risolvere qualcosa , me l' appuntavo e alla fine nata la sezione Come fare per. Dopo lungo girovagare per il codice , alla fine mi si sono schiarite un po' le idee, quando mi sono chiesto: Ma cosa fa Drupal quando parte? Logico, legge il file index.php. Allora ho cominciato a seguire il codice dall'inizio e finalmente mi si sono schiarite le idee (credo). Ho cominciato a capire cosa veramente un nodo e come salvato, cosa sono i file templete e quando sono utilizzati, cosa un tema etc. Ecco perch in questi miei appunti ho messo come secondo argomento proprio l' Avvio di Drupal, cercando di spiegare, e mentre scrivevo di fermare le idee, cosa succede da quando viene letto il file index.php a quando termina la presentazione della home page. Ho cercato di approfondire l'argomento in modo tale da poter controllare la situazione e capire meglio gli argomenti successivi. Ci sono ancora delle lacune, ma credo sia un buon punto di partenza per avvicinarsi a Drupal. I due argomenti successivi riguardano lo sviluppo di temi e moduli. Sono ancora all'inizio e spero con il tempo di approfondire. Ovviamente per approfondire gli argomenti trattati d'obbligo la guida ufficiale di drupal.org, e i forum di drupalitalia.org e di drupal.it Per , andate anche, in questo sito, alla pagina Drupal e al paragrafo "Ma si parla di Drupal anche in ..." dove riporto alcuni link verso siti che ritengo veramente ben fatti e da cui possibile "attingere sapere" e imparare molte cose su Drupal. Buona lettura

Drupal 6.x
In attesa di fornire documentazione alla versione 6, di seguito riporto alcuni link alla documentazione originale in lingua inglese su Drupal.org Descrizione Conversione temi da 5.x a 6.x Anatomia di un tema Drupal Struttura del file .info Nomi di funzione e template dei temi Link

1 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

Descrizione Registrazione del tema Screenshots del tema Sub-tema:ereditariet Modifica interattiva dei colori Funzioni da implementare per temi Funzioni per il template.php Variabili di base disponibili a tutti i template Module developer's guide

Link

Come fare per


Questa sezione della guida dedicata a quei piccoli problemi che ho incontrato durante lo sviluppo con Drupal a cui per non avevo trovato , nei vari forum su Drupal , risposta immediata. Modificare il titolo del sito Ripristinare la pagina di login scomparsa Sito off-line:non riesco pi ad entrare Eseguire il Logout Aprire una nuova finestra da menu (target="_blank") Il test per abilitare URL semplificati fallisce Ordinare i contenuti nella prima pagina Cambiare il proprietario di un contenuto I fogli di stile non sono caricati

Modificare il titolo del sito


Come amministratore del sito, andando sulla voce di menu amministra->impostazioni compare la pagina con tutte le impostazioni del sito. Su impostazioni generali possibile definire il titolo del sito, la email e l'icona.

Ripristinare la pagina di login scomparsa


Se stata disabilitata la visualizzazione del Login , collegarsi con www.miosito.it/user, per far comparire la pagina di login.

Sito off-line:non riesco pi ad entrare


Provare in uno di questi modi: Provare a collegarsi con www.miosito.com/user, per far comparire la pagina di login. Se si visualizza entrare come amministratore e riportare il sito on-line. Controllare se nella tabella variable c' un record con name= 'site_offline': se c' cancellarlo insieme al record della tabella cache con cid='variables' Se ancora non funziona il controllo del sito offline fatto in includes/menu.inc funzione _menu_site_is_offline() chiamata dalla funzione menu_execute_active_handler() Verificare 'impostazione della variabile $db_url nel file /sites/defaultl/settings.php Se ancora non funziona il controllo del sito offline fatto in includes/menu.inc funzione

2 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

_menu_site_is_offline() chiamata dalla funzione menu_execute_active_handler()

Eseguire il Logout
Per eseguire un Log-out non da menu chiamare la pagina http://miosito.com/logout

Aprire una nuova finestra da menu (target="_blank")


Sostituire la funzione theme_menu_item_link() (contenuta in includes/menu.c) con il seguente codice: Per versione 6.x
<?php function theme_menu_item_link($link) { if (empty($link['localized_options'])) { $link['localized_options'] = array(); } if( strtolower(substr($link['href'],0,4))=="http") { $link['localized_options']['attributes'] = array('target' => '_blank'); } return l($link['title'], $link['href'], $link['localized_options']); } ?>

Per versione 5.x


<?php function theme_menu_item_link($item, $link_item) { $attributes = array(); if (!empty($item['description'])) $attributes['title'] = $item['description']; if( strtolower(substr($link_item['path'],0,4))=="http") { $attributes['target'] = "_blank"; } return l($item['title'], $link_item['path'], $attributes, isset($item['query']) ? $item['query'] : NULL); } ?>

Attenzione , se il tema che si sta utilizzando implementa la funzione miotema_menu_item_link() nel file template.php, inserire la patch anche in questa funzione. Il test per abilitare URL semplificati fallisce Per sistemi Windows e server Apache fare le seguenti modifiche: in httpd.conf
1. scommentare LoadModule rewrite_module modules/mod_rewrite.so 2. impostare AllowOverride All in .. <Directory "C:/drupal"> AllowOverride All Options None Order allow,deny Allow from all </Directory>

essendo C:/drupal la documentRoot di Apache

Ordinare i contenuti nella prima pagina


Come sono ordinati i contenuti nella rima pagina? All'avvio di Drupal viene eseguita la funzione node_page_default() , contenuta in includes/node.module. In

3 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

questa funzione viene eseguita la seguente query per vedere quali contenuti devono essere inseriti in prima pagina.
SELECT n.nid, n.sticky, n.created FROM node n WHERE n.promote = 1 AND n.status = 1 ORDER BY n.sticky DESC, n.created DESC

Quindi affinch un contenuto compaia in prima pagina nella tabella NODE si deve avere: promote = 1 ; cio promosso in prima pagina. status = 1; cio pubblicato. L'ordinamento fatto sui due campi: sticky(opzione fisso in cima alla lista ) e created (data creazione) e su entrambi in modo discendente. Per il campo sticky pi alto il valore pi il commento sar in cima alla lista. Per il campo created , i commenti pi recenti saranno visualizzati per primi. Quindi, al di l della data di creazione, per portare un commento al primo posto nella pagina, basta assegnarli (direttamente nella tabella NODE) il valore di sticky pi alto in assoluto e via via decrescente per i contenuti che devono seguire. Per tutti i contenuti che si vogliono visualizzare in base alla loro data di creazione, basta mantenere sticky=0. Attenzione:se ad un contenuto si assegna l'opzioe "fisso in cima alla lista" il valore di sticky sar posto=1 sovrascrivendo eventuali valori da noi impostati direttamente nella tabella NODE.

Cambiare il proprietario di un contenuto


Ci sono due modi per modificare il proprietario del nodo. 1. Il primo consiste nell'entrare nel nodo del contenuto come amministratore e nelle informazioni sull'autore inserire il nome dell'utente a cui dare la propriet del nodo. Attenzione: il nuovo utente potr ora modificare il contenuto solo se in Controllo accessi ha il permesso amministra filtri nel modulo filter oppure se il formato del contenuto Filtered HTML. Nel caso non fosse cos, permessi non assegnati o formato uguale a PHP code o Full HTML, necessario o cambiare il permesso o impostare il formato a Filtered HTML. 2. Il secondo metodo consiste nel modificare il campo uid nella tabella node inserendo il valore uid assegnato all'utente (vedere tabella users). Vale la stessa considerazione fatta precedentemente per il formato. Il valore del formato selezionato comunque indicato nella tabella node_revisions nel campo format per il/i record con campo nid uguale al valore nid del nodo nella tabella node. La tabella node_revisions ha anche il campo uid che per correttezza dovrebbe essere posto uguale al valore in tabella node, ma anche se mantiene il precedente valore non inficia il cambiamento del proprietario. Format = 1 Filtered HTML valore di default per tutti gli utenti Format = 2 PHP code Format = 3 Full HTML

I fogli di stile non sono caricati


Compare solamente il contenuto senza sidebar intestazione etc. Controllare che il nome del tema assegnato all'utente sia presente nella tabella system per type="theme" Controllare che file di stile indicato nella tabella system nel campo filename, esista per quel tema e che non sia corrotto

Definizioni
Sono riportati in questo capitolo alcuni concetti che saranno utilizzati nel proseguo di questa documentazione. Contenuti Page callback URL alias
4 di 42 22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

Contenuti
In questa documentazione sar indicato con il termine di contenuto l'informazione archiviata in un sistema CMS come Drupal. L'informazione pubblicata orientata alla diffusione di conoscenza , idee, proposte e altro che gli ideatori del sito hanno come loro missione. L'informazione resa disponibile nel sito web sotto forma di articoli, libri, forum e ancora con il supporto di immagini , video e suoni. Tutto questo quello che chiameremo contenuto primario del sito. Ma oltre al contenuto primario, nel sito sono presenti altri contenuti come i menu per la navigazione, maschere per l'interazione con l'utente, commenti agli argomenti lasciati dai visitatori o utenti del sito, pubblicit e tutto ci che pu essere necessario per raggiungere lo scopo finale per cui il sito stato pensato. Tutto questo quello che chiameremo contenuto secondario del sito Il contenuto primario viene gestito dal Drupal attraverso i NODI. Possiamo pensare al nodo come il contenitore della nostra informazione che viene poi visualizzato sul web sotto forma di pagina singola o di pagina di un libro o ancora come contenuto di un singolo intervento in un forum. Drupal mette a disposizione dei nodi di base come appunto la creazione di una singola pagina o di un pagina appartenente ad un libro come questa che state leggendo. Ma Drupal consente anche di creare nuove tipologie di nodi. Si potrebbe creare quindi una rubrica telefonica dove ogni nodo costituito da un singolo nominativo , uno scadenzario, un reportage fotografico e cos via. Il contenuto secondario viene gestito da Drupal attraverso i BLOCCHI. I menu di navigazione sono dei blocchi, l'elenco degli ultimi commenti alle pagine o delle ultime discussioni aperte in un forum sono dei blocchi, la maschera di login un blocco cos come i tag di ricerca delle pagine. In pratica, come detto, tutto ci che utile per una buona navigazione e fruibilit del sito va a finire in un blocco.

Page callback
Quando viene inviata una richiesta, Drupal mediante la tabella MENU_ROUTER individua la funzione da chiamare per leggere, codificare e visualizzare il contenuto richiesto. Questa specifica funzione viene indicata con il nome di page callback. Ad esempio la richiesta di un singolo nodo seleziona la page callback node_page_view() , per la visualizzazione della prima pagina node_page_default().

URL alias
Drupal archivia il contenuto primario nei nodi. All'interno del database i nodi sono numerati sequenzialmente. Per accedere ad un nodo e quindi al suo contenuto , necessario indicare a Drupal l'identificativo del nodo che si vuole estrarre dal database. Questa informazione contenuta nell' URL inserito nel browser. Ad esempio: URL = www.miosito.com/node/345 Con questo URL diciamo al sistema di mostrarci il contenuto del nodo 345. Questo URL un po' criptico perch non dice nulla circa il contenuto del nodo a meno di non ricordarsi che il nodo 345 corrisponde ad un certo contenuto che molto improbabile. Drupal viene in aiuto con gli URL alias. In pratica possibile associare all' URL precedente un qualsiasi altro URL . Ad esempio: URL = www.miosito.com/contabilita/elenco-fatture/attive Si noti che tre voci 'contabilita' 'elenco-fatture' 'attive' sostituiscono due voci 'node' '345'. In questo modo non interessa pi sapere quale nodo chiamare per avere l'elenco delle fatture attive, in quanto abbiamo un alias pi facilmente ricostruibile. Sar compito di Drupal convertire l' URL alias in un URL di sistema e richiamare successivamente la funzioni per visualizzare il contenuto.

5 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

Avvio di Drupal
Quando un browser invia un URL a Drupal per richiedere una pagina , la prima azione che viene eseguita dal sistema la lettura del codice php nel file index.php. Nel file, riportato a fondo pagina, sono definite le quattro fasi distinte che Drupal esegue per portare a termine la visualizzazione della pagina richiesta. inizializzazione o bootstrap del sistema - drupal_bootstrap() lettura del contenuto dei nodi - menu_execute_active_handler() lettura del contenuto dei blocchi e visualizzazione della pagina - theme('page',$return) chiusura - drupal_page_footer()

Bootstrap
Il sistema chiama la funzione drupal_bootstrap() che inizializza tutte le variabili di sistema , carica i moduli attivi , si connette al database, converte l'url alias ed altro ancora, predisponendo l'ambiente alla lettura e codifica dei contenuti.

Lettura del contenuto primario (nodi)


Il sistema chiama la funzione menu_execute_active_handler() che legge e codifica il contenuto richiesto, tornando una stringa contenente il codice HTML da visualizzare. In questa fase Drupal individua, in base al path ricevuto, la page callback, che consente di estrarre il contenuto della pagina. Ad esempio per un nodo generico la page callback la node_page_view(). In pratica viene preparato tutto tranne le barre, l'intestazione, il pi di pagina. Per un esempio di quello che Drupal genera in questa fase, aprire il file index.php e aggiungere le due righe indicate sotto la funzione menu_execute_active_handler().
...... $return = menu_execute_active_handler(); print $return; exit(); ....

Richiamando ora la home page del sito si vedr il solo contenuto della pagina senza barre laterali, intestazione e fondo pagina. Questo perch $return contiene il codice HTML del contenuto ed quello che viene stampato con l'istruzione print $return. E' da notare che al risultato non sono applicati gli stili del tema corrente, poich il tema, e quindi lo stile, non ancora stato completamente applicato cosa che viene fatta successivamente chiamando la funzione theme('page',$return).

Lettura del contenuto secondario (blocchi, menu)


Il sistema chiama la funzione theme('page') che legge e codifica il contenuto secondario unendolo al primario. Il risultato ottenuto inviato al browser mediante l'istruzione "print". Anche qui possibile isolare il risultato ottenuto sostituendo il parametro $return con una stringa vuota, come in esempio:
...... $return=""; // annulla $return print theme('page', $return); } ...

Richiamando ora la home page del sito si vedr il solo contenuto secondario, intestazione, blocchi, menu ma senza il contenuto primario definito in $return.

Chiusura
6 di 42 22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

Il sistema chiama la funzione drupal_page_footer(). Nelle fasi precedenti sono state avviate tutte le funzioni per preparare i contenuti. In questa fase Drupal chiama tutte le funzioni hook_exit() implementate nei moduli attivi, per avvisare che la pagina richiesta stata inviata e che le operazioni da attivare sono terminate. Queste funzioni possono essere utili per eseguire un debugging del sistema o aggiornare, in fase di chiusura, alcune tabelle associate ai moduli. Contenuto del file index.php.
<?php require_once './includes/bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); /* Con questa funzione viene generato il solo contenuto dei nodi e, al ritorno, nella variabile $return presente il codice HTML del contenuto dei nodi. */ $return = menu_execute_active_handler(); // Menu status constants are integers; page content is a string. if (is_int($return)) { switch ($return) { case MENU_NOT_FOUND: drupal_not_found(); break; case MENU_ACCESS_DENIED: drupal_access_denied(); break; case MENU_SITE_OFFLINE: drupal_site_offline(); break; } } elseif (isset($return)) { // Print any value (including an empty string) except NULL or undefined: /* Con questa funzione viene generato il contenuto dei blocchi , assemblato insieme al precedente contenuto dei nodi e visualizzato sul web */ print theme('page', $return); } /* * Preparazione della parte finale della pagina */ drupal_page_footer(); ?>

Riporto di seguito la descrizione maggiormente dettagliata di quel che succede nelle quattro fasi suddette.

Decodifica URL
Drupal un sistema in cui le pagine richieste sono quasi sempre costruite dinamicamente. Il testo della pagina archiviato in un database e quando viene richiesto, Drupal deve leggerlo e trasformarlo in codice HTML per essere visualizzato sul browser. Drupal quindi un sistema che genera pagine dinamiche. Quando un browser invia un URL per richiedere una pagina del sito ,il sistema deve individuare dall' URL quale funzioni attivare per generare e visualizzare la pagina richiesta. Il meccanismo che individua le funzioni da richiamare descritto qui di seguito.

Impostazione della variabile $_GET['q']


La variabile $_GET['q'] , e il suo valore , resa disponibile dal server web. Il server web imposta il valore di $_GET['q'] al percorso richiesto interno al sito, in seguito indicato con il

7 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

termine path. E' dal valore di questa variabile che Drupal parte per determinare quale funzione attivare per visualizzare il contenuto richiesto. Ad esempio: se l' URL=http://miosito.com allora $_GET['q'] = '' se l' URL=http://miosito.com/node/345 allora $_GET['q'] = node/345 se l' URL=http://miosito.com/contabilita/elenco-fatture/attive allora $_GET['q'] = contabilita/elenco-fatture /attive

Conversione Url alias Richiesta della home page


Se l' URL inviato contiene il solo nome del sito www.miosito.com e quindi $_GET['q'] = "", Drupal non effettua alcuna conversione riconoscendo nell' URL la richiesta della home page del sito. In questo caso Drupal forza $_GET['q'] = "node".

Richiesta di una pagina generica


L'URL inviato al sistema, pu contenere un alias dell'URL, come nell'esempio di "miosito.com/contabilita /elenco-fatture/attive". Il path contenuto nella variabile $_GET['q'] in questo caso sar uguale a "contabilita/elenco-fatture/attive". Il sistema per prima cosa converte il path ricevuto in un indirizzo interno e successivamente individua la funzione da attivare per estrarre dal database il contenuto richiesto. La conversione viene eseguita nella fase di bootstrap, a cui si rimanda , ed in particolare nella fase di BOOTSTRAP_PATH. In questa fase Drupal cerca nella tabella URL_ALIAS il path "contabilita/elenco-fatture/attive" e se esiste imposta la variabile $_GET['q'] al valore del corrispondente path di sistema. Esempio: contabilita/elenco-fatture/attive => node/345 A conversione avvenuta avremo $_GET['q'] = node/345 e quindi il sistema sapr quale nodo deve essere visualizzato. Evidentemente se non si trova una corrispondenza nella tabella indicata, significa che l'URL non contiene un alias e quindi la variabile $_GET['q'] non sar alterata.

Individuazione della page_callback


Dopo l'eventuale conversione dell' URL , in $_GET['q'] si trova l'indirizzo reale della pagina da visualizzare. Drupal deve ora individuare la page_callback, per estrarre e visualizzare il contenuto richiesto. Abbiamo visto in Avvio di Drupal che all'interno del file index.php la lettura del contenuto viene eseguito dalla funzione menu_execute_active_handler(), il cui codice parzialmente riportato a fondo pagina. Questa , al suo interno, chiama la funzione menu_get_item() che individuer la page_callback, e se specificato, caricher anche il nodo o l'oggetto richiesto. In che modo viene individuata la page callback? La page_callback individuata grazie alla tabella MENU_ROUTER. In questa tabella sono contenute le informazioni necessarie per individuare la page_callback, il cui nome indicato nel campo <page_callback>. in base al path fornito. In particolare la colonna <path> contiene i possibili path parametrizzati che possono essere richiesti. I nomi delle funzioni di callback, di caricamento etc, sono lette e caricate da Drupal in MENU_ROUTER chiamando l'hook_menu su tutti i moduli abilitati. Di questo si parla nello sviluppo di un modulo. Ad esempio, volendo modificare il nodo 12345 , potrebbe essere inviato a Drupal il path node/12345/edit. In questo caso, il sistema cercherebbe nella colonna <path> uno dei seguenti path: 7 node/12345/edit 6 node/12345/% 5 node/%/edit 4 node/%/%

8 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

3 node/12345 2 node/% 1 node Potrebbero non essere tutti presenti, ma tra quelli presenti, l'ordine di selezione dato dal valore del campo <fit> della tabella. Il path node/%/edit indica che il record della tabella contiene il nome della page_callback per tutti i path costituiti da 'node', un numero identificativo del nodo , e 'edit' come per 'node/12345/edit' Individuato il path, il corrispondente record viene posto in un array e tornato alla funzione menu_execute_active_handler() che chiamer la page_callback. Oltre a tutti i campi della tabella menu_router, l'array conterr anche: $router_item[access] = che indica se si pu accede al percorso. $router_item[href] = equivalente al campo <path> $router_item[localized_options] per ulteriori opzioni sul path inseribili da altre funzioni.

Gli argomenti della page callback e la lettura dell'oggetto


La funzione menu_get_item() in grado di leggere l'oggetto richiesto (ad esempio un nodo) se nella tabella MENU_ROUTER specificata una funzione di caricamento.

argomenti per la homepage


La page_callback chiamata la node_page_default() a cui non vengono passati argomenti. Il valore $router_item[page_arguments] nullo.

argomenti per un nodo generico


Abbiamo visto ad esempio che per la richiesta node/12345, il sistema trova nella tabella MENU_ROUTER il path 'node/%' e a questo corrispondono i due campi: <page_callback> : node_page:view() <load_function>: node_load() (serializzata in tabella) Essendo presente il nome di una funzione di caricamento, la menu_get_item() sar in grado di leggere l'oggetto, utilizzando la funzione indicata, e inserirlo in $router_item[page_arguments] come argomento della funzione di page_callback. Di seguito un frammento del codice che : chiama la menu_get_item() per riempire l'array $router_item con le informazione sulla page_callback da chiamare; lancia la page_callback tramite la funzione PHP call_user_func_array();
<?php function menu_execute_active_handler($path = NULL) { // altro codice ... if ($router_item = menu_get_item($path)) { if ($router_item['access']) { if ($router_item['file']) { require_once($router_item['file']); } return call_user_func_array( $router_item['page_callback'], $router_item['page_arguments'] ); } else { // altro codice ... } } ?>

9 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

All'avvio di Drupal, il valore di $path NULL e la funzione menu_get_item() legger il path dalla variabile globale $_GET['q']. La page_callback a questo punto legger il contenuto e torner una stringa contenente il corrispondente codice HTML.

Bootstrap
La funzione drupal_bootstrap() contenuta nel file ./includes/bootstrap.inc che viene subito caricato. All'interno del file bootstrap.inc sono definite le otto costanti che indicano quale sotto fase attivare nel bootstrap. DRUPAL_BOOTSTRAP_CONFIGURATION=0 DRUPAL_BOOTSTRAP_EARLY_PAGE_CACHE=1 DRUPAL_BOOTSTRAP_DATABASE=2 DRUPAL_BOOTSTRAP_ACCESS=3 DRUPAL_BOOTSTRAP_SESSION=4 DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE=5 DRUPAL_BOOTSTRAP_PATH=6 DRUPAL_BOOTSTRAP_FULL=7 Alla funzione drupal_bootstrap() viene passato un parametro che indica a quale fase fermarsi del bootstrap. All'avvio, e in generale su richiesta di un nodo generico, il parametro posto uguale a DRUPAL_BOOTSTRAP_FULL in modo tale da eseguire tutte le otto le fasi. Le funzioni attivate dalle singole fase sono definite nella funzione _drupal_bootstrap($phase). 1) DRUPAL_BOOTSTRAP_CONFIGURATION Funzioni utilizzate: conf_init() inizializza le variabili conf_path() torna il percorso del file settings.php 1. Vengono eliminate le definizioni , se esistenti (ini_get('register_globals')=1), delle variabili globali del php: _ENV, _GET, _POST, _COOKIE, _FILES, _SERVER, _REQUEST, access_check, GLOBALS . 2. Sono inizializzate le variabili globali locali di Drupal. Le variabili $db_url, $db_prefix ,$db_type sono lette dal file sites/default/settings.php Le variabili: $base_url, $base_path, $base_root, $cookie_domain, $conf, $installed_profile sono calcolate a run-time 2) DRUPAL_BOOTSTRAP_EARLY_PAGE_CACHE Include il file ./includes/cache.inc Funzioni utilizzate: _drupal_cache_init() Inizializzazione della cache. All'avvio non viene eseguita nessuna operazione. 3) DRUPAL_BOOTSTRAP_DATABASE Include il file ./includes/database.inc Funzioni utilizzate: - db_set_active() Apre la connessione al database definito in settings.php Apre la connessione al database. Le funzioni per accedere al database sono definite nel file ./includes/database.$db_type.inc. (tipicamente $db_type=mysql) Se il file non esiste, Drupal si ferma indicando che non possibile utilizzare il tipo di database definito in $db_type. Se la connessione va a buon fine viceversa vengono impostati i valori delle seguenti variabili

10 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

globali: $db_url contiene la stringa di connessione definita in settings.php $db_type contiene il tipo di database da utilizzare per la connessione corrente (dedotta da $db_url) $active_db = Resource php al database attivo. Se username='username' e password='password' in $db_url di settings.php, Drupal avvia l'installazione del sistema caricando il file instal.php. Il valore di ritorno della funzione db_set_active() il nome del database precedentemente attivato, FALSE se non ce ne era nessuno. 4) DRUPAL_BOOTSTRAP_ACCESS Funzioni utilizzate: _drupal_is_denied() La funzione drupal_is_denied(), verifica che ci siano i permessi per l'accesso all'host contenente Drupal. 5) DRUPAL_BOOTSTRAP_SESSION Include il file ./includes/session.inc Funzioni utilizzate: session_set_save_handler() (nativa php) Imposta le funzioni di archiviazione sessioni a livello utente, ed avvia mediante session_start() la gestione della sessione. 6) DRUPAL_BOOTSTRAP_LATE_PAGE_CACHE Include i file ./includes/cache.inc, ./includes/module.inc Funzioni utilizzate: _drupal_cache_init() Se la cache abilitata e per la URL fornita esiste un record nella tabella cache, Drupal legge il contenuto della cache, visualizza la pagina e si ferma. Se la cache non abilitata o vuota , Drupal torna dalla funzione _drupal_cache_init() e continua con il bootstrap eseguendo le funzioni e le fasi successive. In particolare in questa fase esegue le seguenti funzioni: timer_start() drupal_page_header() Inizializza l'array globale $conf utilizzata dalla funzione variable_get(). Attiva , mediante drupal_page_header(), le impostazioni del protocollo HTTP per la risposta. header("Expires: Sun,19 Nov 1978 05:00:00 GMT"); header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); header("Cache-Control: store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", FALSE); 7) DRUPAL_BOOTSTRAP_PATH Include il file ./includes/path.inc Funzioni utilizzate: drupal_init_path() Inizializza la variabile $_GET['q'] al valore 'node'. 8) DRUPAL_BOOTSTRAP_FULL Include il file ./includes/common.inc Funzioni utilizzate: _drupal_bootstrap_full() E' l'ultima fase del bootstrap del sistema. La funzione drupal_bootstrap_full() consente di caricare gli ultimi file include:

11 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

./includes/theme.inc ./includes/pager.inc ./includes/menu.inc ./includes/tablesort.inc ./includes/file.inc ./includes/unicode.inc ./includes/image.inc ./includes/form.inc che conterranno le funzioni da utilizzare nelle tre successive fasi (vedi Avvio di Drupal), attivare delle funzioni di inizializzazione del sistema e caricare i moduli abilitati. L'ultima funzione module_invoke_all('init') invoca tutte le funzioni di inizializzazione del tipo hook_init(), se esistenti, dei singoli moduli.

Visualizzazione del contenuto


Gli argomenti trattati fanno riferimento alla versione 5.x di Drupal In questa fase Drupal visualizza la pagina richiesta utilizzando gli stili del tema impostato e il file page.tpl.php come guida per la costruzione dinamica della pagina. Per fare questo Drupal chiama la funzione theme('page',$return) a cui passa, come argomenti, il parametro 'page' e il codice HTML del contenuto della pagina preparato nella precedente fase. La funzione theme() La funzione theme() individua la funzione corretta da eseguire. In questo caso, in base al parametro passato 'page' , chiamer: miotema_page() se esiste questa funzione in /miotema/template.php phptemplate_page()se esiste questa funzione in phptemplate.engine > theme_page() altrimenti (questa funzione sempre presentte in includes/theme.inc ) Generalmente, e consideriamo questo caso, Drupal trova e chiama la funzione phptemplate_page() La funzione phptemplate_page() Al suo interno la funzione avvia le seguenti operazioni: Legge e definisce la variabile $mission (missione del sito) Inserisce il path di favicon.ico nel tag <HEAD> Se richieste, riempie le barre laterali (sidebar-left e sidebar-right) Le barre laterli Per le barre laterali Drupal definisce la variabile $layout che pone uguale a:left, right, both, none a seconda che sia stata definita la barra laterale sinistra, la destra, entrambe o nessuna. In fase di definizione dello stile del tema, questa variabile pu essere usata per definire le dimensioni delle regioni dei contenuti in funzione della presenza o meno delle barre laterali. Poich la barre laterali sono costituite da blocchi, Drupal legge tutti i blocchi da visualizzare nella pagina richiesta e genera il corrisondente codice HTML che pone nelle variabili $sidebar_left e $sidebar_right. Il loop sui blocchi viene eseguito dalla funzione theme_blocks($region), essendo $region la regione da caricare: left o right. Ogni singolo blocco formattato con la funzione phptemplate_block() che a sua volta si avvale delle funzioni: _phptemplate_callback() per caricare, nell'array $variables, tutte le variabili da usare nei template phptemplate_default() per individuare il file di template da usare per il rendering _phptemplate_render()a cui viene passato il nome del file (generalmente block.tpl.php) di template e l'array $variables per eseguire la definitiva preparazione del codice HTML del blocco. Il processo si ripete per il blocco successivo, fino a completare il codice di tutta la barra laterale.

12 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

E' possibile generare la funzione miotema_page($return) in template.php per decidere il valore della variabile $show_blocks che consente di nascondere(=false) o mostrare (=true) le barre laterali.
function miotema_page($return) { $show_blocks = false return phptemplate_page ($return,$show_blocks) }

Lettura dei contenuti


Come descritto in Avvio di Drupal il contenuto primario e secondario letto rispettivamente dalle due funzioni: menu_execute_active_handler() theme('page') Questo capitolo entra nel merito delle due funzioni per meglio capire il processo di lettura, codifica e visualizzazione dei contenuto richiesto.

Nodi
Gli argomenti trattati fanno riferimento alla versione 6.x di Drupal I nodi contengono il contenuto primario del sito. L'elenco di tutti i nodi inseriti nel sistema contenuto nella tabella NODE. Le informazioni sono lette e codificate dal sistema, mediante la funzione menu_execute_active_handler(), descritta in Decodifica URL. La funzione individua la page callback e, tramite essa, torna la stringa del contenuto codificato. Per i nodi sono disponibili due page callback: node_page_default() , se la richiesta relativa alla homepage. node_page_view() se la richiesta relativa ad un nodo specifico. Le funzioni principali La selezione dei nodi Lettura del contenuto di un nodo - node_load() Lettura extra-contenuto di un nodo Preparazione alla visualizzazione del nodo - node_view()

Le funzioni principali
node_page_default() node_load() node_view() node_invoke() node_invoke_api()

La selezione dei nodi


La home page - node_page_default() La prima pagina del sito mostra generalmente pi di un nodo. Questi sono i nodi a cui stato assegnato l'attributo di pubblicazione "promosso in prima pagina". Per selezionare tali nodi, la funzione node_page_default() esegue la seguente query sulla tabella NODE:
SELECT n.nid, n.sticky, n.created FROM node n WHERE n.promote = 1 AND n.status = 1

13 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

ORDER BY n.sticky DESC, n.created DESC

Dalla query si vede che le condizioni affinch un nodo venga selezionato sono: avere l'attributo di pubblicazione - status=1; avere l'attributo promosso in prima pagina - promote=1; L'ordine di visualizzazione dei nodi fornito invece dal valore sticky:pi alto, pi il nodo salir nell'elenco. A parit di valore l'ordine dato dalla data di creazione. I nodi pi recenti , sono visti per prima. Il valore di sticky normalmente vale zero. Volendo quindi mostrare un nodo sempre per primo, indipendentemente dalla data di creazione, baster assegnare un valore >0 al nodo, ad esempio 100. Individuati i nodi da visualizzare , la funzione node_page_default(), inizia un ciclo di lettura e visualizzazione di tutti i nodi. Questo processo viene eseguito mediante le due funzione node_load() per il caricamento e node_view() per la visualizzazione. Vediamo allora come lavorano queste due funzioni.

Lettura del contenuto di un nodo - node_load()


La lettura del contenuto del nodo, eseguita mediante la funzione node_load($nid) a cui passato il valore dell'identificativo univoco del nodo <nid> da caricare. Al suo interno viene generata la query indicata, che usa tre tabelle: NODE da cui sono estratte informazioni sulla pubblicazione e tipo del nodo NODE_REVISIONS da cui sono estratte informazioni sul contenuto del nodo (Il titolo del nodo letto da questa tabella e non da NODE come si potrebbe pensare) USERS da cui sono estratte informazioni sul proprietario del nodo Query di selezione

SELECT n.nid, n.type, n.language, n.uid, n.status, n.created, n.changed, n.comment, n.promote, n.moderate, n.sticky, n.tnid, n.translate, r.vid, r.uid AS revision_uid, r.title, r.body, r.teas r.timestamp AS revision_timestamp, r.format, u.name, u.picture, u.data FROM node n INNER JOIN users u ON u.uid = n.uid INNER JOIN node_revisions r ON r.nid = n.nid AND r.vid = <n.nid> WHERE n.nid = <n.nid>

Dala funzione node_load() torna un oggetto ($node) contenente le informazioni lette mediante la query. In particolare i valori $node->body e $node->teaser conterranno rispettivamente contenuto e sommario del nodo. Oggetto $node generato dalla funzione. (ND=da tabella NODE; NR da tabella NODE_REVISIONS; US da tabella USERS) $node->nid $node->language $node->type $node->uid $node->status $node->created $node->changed $node->comment $node->promote ND identificativo univoco del nodo ND lingua del contenuto:'it' , 'en', 'fr', ND tipo del nodo. Tabella di codifica NODE_TYPE ND identificativo utente del proprietario del nodo ND =0 non visibile; =1 visibile ND timestamp della data di creazione del nodo ND timestamp della data di modifica del nodo ND identificativo utente dell'ultimo commento ND =1 il nodo visualizzato in prima pagina

14 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

$node->moderate $node->sticky $node->vid $node->uid $node->title $node->body $node->teaser $node->log

ND =1 il nodo deve essere controllato prima della pubblicazione ND numero d'ordine del nodo nella prima pagina NR identificativo del numero di revisione NR identificativo utente del proprietario del nodo NR titolo del nodo per la revisione corrente NR contenuto del nodo per la revisione corrente NR sommario del nodo per la revisione corrente NR Messaggio di log contenente le modifiche eseguite

$node->revision_timestamp NR data di modifica del nodo $node->format $node->name $node->picture $node->data NR formato del nodo da tabella FILTERS_FORMAT US nome utente US percorso all'immagine utente US serializzazione di un array che rappresenta i campi dela form utente

Lettura extra-contenuto di un nodo


Oltre alla lettura delle informazioni contenute specificatamente nelle tabelle NODE e NODE_REVISIONS, Drupal consente di aggiungere ulteriori informazioni ai nodi e quindi all'oggetto $node. Potremmo decidere di definire un nuovo tipo di nodo con informazioni aggiuntive salvate in una tabella separata. Pensiamo ad esempio ad una rubrica telefonica. Il nominativo e l'identificativo univoco potrebbero essere rispettivamente il campo <title> e il campo <nid> della tabella NODE, mentre tutte le informazioni aggiuntive come l'indirizzo, il telefono, l'email etc, potrebbero essere memorizzate in una tabella separata. Si pone quindi il problema di leggere queste ulteriori informazioni associate ai nodi. Drupal consente di leggere queste extra informazioni implementando funzioni particolari che gestiscano queste situazioni. Dobbiamo distinguere due casi:

Implementazione della funzione legata alla tipologia del nodo


Nella tabella NODE_TYPES sono elencati il tipo di nodi definiti nel sistema. Tra questi sono presenti i nodi principali, forniti con il sistema, quali: page, book, story etc. Dalla stessa tabella vediamo che il campo <module> ci dice da quale modulo sono gestiti i nodi. Ora supponiamo di aggiungere il nuovo tipo di nodo "rubrica" e che questo tipo di nodo sia gestito dall'omonimo modulo con tutte le sue funzioni implementate in rubrica.module. Ora quando Drupal legger un nominativo dal nodo rubrica, nominativo e identificativo saranno letti come indicato nel precedente paragrafo, mentre l'ulteriore contenuto sar letto chiamando la funzione rubrica_load($node). La funzione deve tornare un array associativo costituito dalle coppie chiave=valore. Un esempio di semplice codice il seguente:

15 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

<?php function rubrica_load($node) {

// rid = identificativo nominativo ; $r = db_fetch_object(db_query('SELECT WHERE rid = %d ', $node->nid));

telefono, indirizzo,citta

FROM {rubrica}

info = array(); info['telefono'] = $r->telefono; info['indirizzo'] = $r->indirizzo; info['citta'] = $r->citta; return $info; } ?>

All'oggetto $node originale, Drupal aggiunger le informazioni: $node->telefono $node->indirizzo $node->citta La funzione chimata all'interno di node_load() mediante node_invoke($node,'load'); Attenzione:Nel caso il modulo di gestione sia quello di default node, il nome della funzione deve essere node_content_load() e non node_load() come dovrebbe.

Implementazione della funzione legata ad un modulo


In questo caso viene chiamata una funzione per avvisare altri moduli che si sta caricando un nodo. Infatti la funzione non appartiene al modulo che gestisce il tipo di nodo come nel caso precedente , ma ad altri moduli attivi. A questo punto la funzione chiamata potrebbe compiere due diverse operazioni: aggiungere informazione al nodo. Si ricade nel caso precedente e quindi anche la funzione potrebbe essere implementata in modo analogo. Utilizzare l'informazione di lettura del nodo contenute in $node per altre attivit ad esempio per eseguire statistiche sulla frequenza di lettura di quel nodo. In entrambi i casi possono dunque essere aggiunte o meno extra informazioni all'oggetto $node. La funzione da implementare deve chiamarsi nomemodulo_nodeapi($node,$opz). A questa funzione passato l'oggetto $node e il valore $opz='load' . Un esempio di semplice codice, nel caso in cui venga aggiunta informazione a $node, il seguente:
<?php function nomemodulo_nodeapi($node,$opz) { switch ( $opz) { case 'load': $info = array(); $info['extrainfo-nomemodulo'] = 'torna qualcosa'; return $info; break; default: break;

} ?>

La funzione chiamata all'interno di node_load() mediante node_invoke_nodeapi($node,'load'); La funzione node_load() per ogni nodo letto chiama tutte le funzioni implametate in questo modo.

16 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

Preparazione alla visualizzazione del nodo - node_view()


Abbiamo visto che la funzione node_load() insieme ad altre funzioni di integrazione, genera l'oggetto $node con tutte le informazioni sul nodo e, tra queste, quelle sul contenuto generale ($node->body) e sul sommario ($node->teaser). La fase di preparazione del contenuto usa la funzione node_view() per preparare il contenuto letto alla sua visualizzazione finale. In questa fase Drupal applica al contenuto i filtri indicati al momento della creazione del nodo e genera l'array: $node[content][body][#value] = contenuto body o teaser filtrati (ci che sar visto nella pagina) ed altre componenti.

View
Inoltre Drupal chiama, se esistenti, le seguenti funzioni definibili dall' utente: se il nodo gestito dal modulo "modulo", la funzione modulo_view($node, $teaser, $page). tutte le funzioni nomemodulo_nodeapi($node, 'view',$teaser, $page) definite nei moduli attivi. Il valore di ritorno delle funzioni, se presente, non letto.

Alter
Drupal prima di inviare il nodo alle funzioni di rendering, per ogni modulo chiama la funzione: nomemodulo_nodeapi($node, 'alter',$teaser, $page) e al termine il nodo passato alla funzione theme('node) per essere definitivamente visualizzato.

Links
Oltre alle informazioni ricavate dalle tabelle NODE e NODE_REVISIONS, all'oggetto $node sono associati i Links di navigazione del nodo che , generalmente, compaiono al termine del sommario di un nodo in prima pagina. Se presenti sono inseriti nell' array $node->links. L'array riempita da ogni modulo che implementa la funzione: nomemodulo_link($type, $node, $teaser = FALSE) essendo: $type il tipo di nodo (ad esempio 'node'), $node l'oggetto in cui inderire l'array del link, $ teaser indica se il nodo in prima pagina o meno.

Blocchi
Gli argomenti trattati fanno riferimento alla versione 6.x di Drupal Fanno parte dei blocchi, oltre ai blocchi stessi, anche i menu, i commenti, gli utenti, le categorie etc. Tutti i blocchi condividono la tabella BLOCKS su cui il sistema salva informazioni di carattere generale. I contenuti sono invece salvati in tabella specifiche per ciascun tipologia di blocco. Le funzioni principali La selezione dei blocchi Query di selezione dei blocchi Il contenuto dei blocchi

Le funzioni principali
Riporto, per comodit, le principali funzioni che sono implicate nel processo di lettura e visualizzazione del contenuto dei blocchi.

17 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

- template_preprocess_page(&$variables) La funzione template_preprocess_page(), contenuta in includes/theme.inc, viene chiamata da theme('page') ed la funzione che avvia il processo di lettura dei blocchi utilizzando le successive funzioni. - theme_blocks($region) La funzione theme_blocks($region) legge tuttii blocchi da visualizzare e contenuti nella regione identificata da $region. Torna una stringa stampabile su web contenente tutto il codice HTML della regione richiesta. Il contenuto della regione inserito in $variables[$region] per essere utilizzato da page.tpl.php. Le regioni generalmente sono:$left,$right,$header,$footer,$content. - theme_block('view',$block) La funzione theme_block('view',$block) formatta il contenuto $block->content chiamando il file template block.tpl.php. Pu essere creata una funzione utente definendo la miotema_block() o phptemplate_block(). Torna una stringa stampabile su web contenente il codice HTML del contenuto $block->content. - block_list($region) La funzione block_list($region) legge le informazioni ed il contenuto dei blocchi da visualizzare nella pagina richiesta e nella regione identificata da $region. Torna un oggetto $block per ogni blocco letto. Questo oggetto utilizzato dal file template block.tpl.php.

La selezione dei blocchi


Quando viene richiesta la visualizzazione di una qualsiasi pagina, Drupal carica per prima cosa il file index.php. All'interno di questo file viene chiamata la funzione theme() a cui passato il paramentro 'page' . Con questo parametro la funzione theme() chiamer la funzione template_preprocess_page. All'interno di essa contenuto il seguente codice:
<?php ............................................ global $theme; // Populate all block regions. $regions = system_region_list($theme); // Load all region content assigned via blocks. foreach (array_keys($regions) as $region) { // Prevent left and right regions from rendering blocks when 'show_blocks' == FALSE. if (!(!$variables['show_blocks'] && ($region == 'left' || $region == 'right'))) { $blocks = theme('blocks', $region); } else { $blocks = ''; } // Assign region to a region variable. isset($variables[$region]) ? $variables[$region] .= $blocks : $variables[$region] = $blocks; } ......................... ?>

La system_region_list legge le regioni del tema corrente e, nel successivo cilclo, per ciascuna di esse, la funzione theme('blocks', $region) legge il contenuto dei blocchi appartenenti alla regione indicata e lo pone nella variabile $variables[$region] che sar successivamente utilizzata dal file template del tema: page.tpl.php. Sappiamo che chiamare la funzione theme('blocks', $region) equivale a chiamare la funzione theme_blocks($region) implementata nel modulo includes/theme.inc e di seguito riportata.
<?php

18 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

function theme_blocks($region) { $output = ''; if ( $list = block_list($region)) { foreach ( $list as $key => $block) { // $key == <i>module</i>_<i>delta</i> $output .= theme('block', $block); } } ?>

In theme_blocks() sono presenti le due funzioni responsabili della lettura e visualizzazione dei blocchi: block_list() theme('block', $block) La prima estrae dal database i contenuti da visualizzare insieme ad altre informazioni relative ai blocchi. La seconda incapsula il contenuto ($block->content) in codice HTML secondo quanto definito nei file di template del tema corrente block.tpl.php o in altri definiti dall'utente.

Query di selezione dei blocchi


Il contenuto dei blocchi da visualizzare sulla pagina individuato all'interno della funzione block_list() mediante l'esecuzione della seguente query di selezione:

SELECT DISTINCT b.* FROM blocks b LEFT JOIN blocks_roles r ON b.module = r.module AND b.delta = r.delta WHERE b.theme = '<nome tema corrente>' AND b.status = 1 AND (r.rid IN ( <elenco dei ruoli dell'utente corrente> ) OR r.rid IS NULL) ORDER BY b.region, b.weight, b.module

Da questa query vediamo che un blocco per essere selezionato deve: essere abilitato (status=1) appartenere al tema corrente in uso essere visualizzabile da un utente che ha i ruoli indicati in <elenco dei ruoli dell'utente corrente&gt oppure essere visualizzabile da chiunque (r.rid IS NULL) Da quanto detto si capisce perch, cambiando tema o utente certe volte non vengono visualizzati alcuni blocchi.

Il contenuto dei blocchi


Abbiamo visto che la funzione block_list() chiamata nel seguente modo: $list = block_list($region) Il valore di ritorno $list un array associativa i cui elementi sono cos formati: $block= $list["modulo_delta"] = oggetto dove: "modulo_delta" una stringa in cui "modulo" il nome del modulo che gestisce il blocco e "delta" il valore del campo delta della tabella BLOCKS. $block invece un variabile di tipo Object contenente le informazioni sul blocco letto: $block->bid $block->module da tabella BLOCKS da tabella BLOCKS

19 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

$block->delta $block->theme $block->status $block->weight $block->region $block->custom $block->throttle $block->visibility $block->pages $block->title $block->cache $block->content $block->subject $block->enabled

da tabella BLOCKS da tabella BLOCKS da tabella BLOCKS da tabella BLOCKS da tabella BLOCKS da tabella BLOCKS da tabella BLOCKS da tabella BLOCKS da tabella BLOCKS da tabella BLOCKS da tabella BLOCKS contenuto del blocco (per un blocco , il contenuto di body) titolo da visualizzare nella pagina VERO/FALSO (indica se il blocco abilitato ad essere visualizzato)

$block->page_match VERO/FALSO (indica se il blocco pu essere visualizzato) Queste informazioni sono disponibili in fase di lettura del file template block.tpl.php. Le tabelle dei contenuti L'oggetto precedente contiene il valore $block->content che rappresenta il vero contenuto del blocco, ci che stato effettivamente inserito come informazione del blocco. Questa informazione non contenuta nella tabella BLOCKS ma nelle tabelle relative alla tipologia del blocco. Ad esempio, per i principali moduli: modulo block => tabella BOXES modulo menu => tabella MENU_LINKS (ed altro) modulo comment => tabella COMMENTS modulo users => tabella USERS Per moduli non di sistema, potranno esserci altre tabelle di contenuto. Le funzioni di lettura dei contenuti Il contenuto del blocco letto dalla funzione di gestione del modulo: nomemodulo_block(). La funzione di lettura dei contenuti del blocco chiamata all'interno di block_list() mediante la funzione: module_invoke($block->module, 'block', 'view', $block->delta). Per i blocchi precedentemente indicati, il contenuto sar letto da: modulo block => block_block('view', $blocks->delta) modulo menu => menu_block('view', $blocks->delta) modulo comment => comment_block('view', $blocks->delta) modulo users => user_block('view', $blocks->delta) In generale , per moduli non di sistema , Drupal chiamer la funzione nomemodulo_block('view', $blocks).

Menu
20 di 42 22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

Gli argomenti trattati fanno riferimento alla versione 6.x di Drupal I menu sono un particolare tipo di blocco. La loro gestione fornita dal modulo modules/menu.module e dalle funzioni contenute nel file includes/menu.inc. Le funzioni principali La selezione dei menu Il contenuto dei menu Il contenuto dei menu Primary links e Secondary links

Le funzioni principali
menu_block($op = 'list', $delta = 0) La funzione menu_block() legge il contenuto del menu individuato dal valore $delta. E' chiamata in fase di generazione dei blocchi dalla funzione block_list() con $op='view'. Torna la seguente array: $block['subject'] = titolo del bloccco $block['content'] = stringa del contenuto del menu in formato HTML. [vedi menu_tree()] L'array usata in block.tpl.php. menu_tree($delta) La funzione menu_tree() ,chiamata da menu_block(), genera il codice HTML del menu individuato dal valore $delta. Il valore di ritorno una stringa. Questa funzione chiama la menu_tree_page_data() per la lettura del contenuto del menu e la menu_tree_output() per la generazione del contenuto in codice HTML. menu_tree_page_data($menu_name) La funzione menu_tree_page_data() legge i contenuti dalle tabelle MENU_LINKS e MENU_ROUTER. Ttornando un array associativa. Vedere Il contenuto dei menu per una descrizione pi dettagliata. menu_tree_output($tree) La funzione menu_tree_output() prende in ingresso l'array $tree prodotto da menu_tree_page_data() contenente tutte le informazioni sul menu da visualizzare e la converte in codice HTML . Torna una stringa. Questa funzione chiama le funzioni personalizzabili: theme_menu_item_link() che formatta una singola foglia (leaf) del menu theme_menu_item() che formatta una voce con figli. theme_menu_tree() che formatta l'albero dei menu. menu_primary_links() La funziome menu_primary_links() torna un array $tree contenente titolo e riferimenti del menu di navigazione Primary links. menu_secondary_links() La funziome menu_secondary_links() torna un array $tree contenente titolo e riferimenti del menu di navigazione Secondary links. theme_links($links,$attributes) La funzione theme_links() genera il codice HTML dei menu di navigazione Primary links e Secondary links. E' chiamata in page.tpl.php menu_list_system_menus() La funzione menu_list_system_menus() torna un array con i nomi dei menu di sistema:''navigation', 'primarylinks', 'secondary-links';

21 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

menu_get_menus() La funzione menu_get_menus() legge i nomi dei menu utente e di sistema dalla tabella MENU_CUSTOM. Torna un array associativo con i nomi dei menu. Esempio: $menu[menu-mio] = "Menu mio" $menu[navigation] = "Navigation" $menu[primary-links] = "Primary links" $menu[secondary-links] = "Secondary links" menu_get_item($path=NULL, $router_item = NULL) La funzione menu_get_item() legge i record dalla tabella MENU_ROUTER filtrando suii valori del campo "path" compatibili al percorso della pagina richiesta. Ad esempio se il percorso della pagina richiesta node/12345/edit, i possibili valori su cui sar eseguito il filtro saranno: 7 node/12345/edit 6 node/12345/% 5 node/%/edit 4 node/%/% 3 node/12345 2 node/% 1 node La funzione torna il primo record di MENU_ROUTER in cui il campo "path" uguale ad uno dei valori suddetti. La ricerca del valore di "path" che soddisfa ad uno dei valori suddetti eseguita secondo il numero d'ordine discendente definito nel campo "FIT".

La selezione dei menu


Abbiamo detto che un menu un particolare tipo di blocco. Questo significa che le informazioni di selezione sono contenute nella tabella BLOCKS e seguono gli stessi criteri descritti per i blocchi. Quindi i menu selezionati saranno quelli che nella query di selezione dei blocchi hanno il nome modulo uguale a "menu". Questo vero per i menu generici.Per i menu primary-links e secondary-links la selezione avviene mediante le due funzion menu_primary_links() e menu_secondary_links() chiamate in template_preprocess_page() durante la generazione della pagina. Rispetto ai blocchi, nei menu ci che cambia come leggere e visualizzare il contenuto e questo verr descritto qui di seguito.

Il contenuto dei menu


Il conenuto di un menu letto dalla funzione menu_block(). All'interno di essa, la lettura e codifica del contenuto del menu viene eseguita, attraverso la funzione menu_tree($menu_name) , dalle due funzioni: menu_tree_page_data() e menu_tree_output(). - La prima , prende in input un nome di menu e in output fornisce un array ($tree) contenente tutte le informazioni lette dalle tabelle MENU_LINKS e MENU_ROUTER per il menu richiesto. - La seconda, prende in input l'array $tree e genera in output il codice HTML del menu richiesto passandolo alla funzione menu_block().
<?php function menu_tree($menu_name = 'navigation') { static $menu_output = array(); if (!isset( $menu_output[$menu_name])) { $tree = menu_tree_page_data($menu_name); $menu_output[$menu_name] = menu_tree_output($tree); } return $menu_output[$menu_name]; }

22 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

?>

L'array $tree, contiene quindi tutte le informazioni delle singole voci appartenenti all'albero del menu corrente. La singola voce del menu individuata da una stringa costruita nel seguente modo: $tree[<50000 + campo_weight> spazio <campo_title> spazio <campo_mlid>] dove: 50000 un valore fisso; <campo_weight> il peso (ordine) della voce nel menu; <campo_title> il titolo della voce corrente; <campo_mlid> l'identificativo univoco della voce in MENU_LINKS Ad esempio per weight=-10 , title=Drupal mlid=96 la stringa che individua la voce : $tree["49990 Drupal 96"] Tutti i valori estratti per la singola voce del menu sono posti in $tree["49990 Drupal 96"][link]. Qui di seguito sono riportati i valori contenuti in $tree per ogni voce del menu:
(MR = da tabella MENU_ROUTER; ML= da tabella MENU_LINKS; AL=da altre fonti MR MR MR MR MR MR MR MR MR MR ML ML ML ML ML ML ML ML ML ML ML ML ML ML ML ML ML ML ML ML ML ML AL AL AL AL AL $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ $tree[ 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 49990 Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal Drupal 96][link][load_functions] 96][link][to_arg_functions] 96][link][access_callback] 96][link][access_arguments] 96][link][page_callback] 96][link][page_arguments] 96][link][title] = Drupal 96][link][title_callback] 96][link][type] 96][link][description] 96][link][menu_name] 96][link][mlid] = 96 96][link][plid] 96][link][link_path] = node/67 96][link][options] => array() 96][link][module] 96][link][hidden] 96][link][has_children] 96][link][expanded ] 96][link][weight ] = -10 96][link][depth] 96][link][customized] 96][link][p1] = 96 96][link][p2] 96][link][p3] 96][link][p4] 96][link][p5] 96][link][p6] 96][link][p7] 96][link][p8] 96][link][p9] 96][link][updated ] 96][link][in_active_trail] = FALSO/VERO 96][link][access ] = VERO/FALSO 96][link][href ] = node/67 96][link][localized_options] = array() 96][link][below] = FALSO/VERO )

Le prime componenti riguardano le funzioni e gli argomenti richiesti per visualizzare la voce del menu. Poi ci sono alcune voci interessanti: il nome del menu [menu_name], se la voce espansa o no [expanded], se ha figli [has_children], la pagina a cui punta [href ], il livello di profondit a cui appartiene la voce [depth], se la voce quella selezionata [in_active_trail]. La componente [localized_options] pu contenere un array caricato da funzioni di tematizzazione. Ad esempio la funzione theme_menu_item_link() la usa per inserite gli attributi per il tag HTML <a>. Avendo il menu una struttura ad albero , l' eventuale identificativo della voce padre posto in [plid], ed inoltre, per ogni ramo, sono indicati i nodi di diramazione <mlid> fino al nodo radice , attraverso i valori da [p1] (radice) a [p9].

23 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

Infine il valore [below] pu contenere un array. Questa array ancora di tipo $tree e rappresenta tutto il sotto albero che si sviluppa a partire dalla voce corrente.

Il contenuto dei menu Primary links e Secondary links


Le due funzioni preposte alla lettura dei menu di navigazione sono la menu_primary_links() e menu_secondary_links(), chiamate all'interno della funzione template_preprocess_page(). Il codice HTML dei menu generato viene posto in $variables['primary_links'] e $variables['secondary_links'], per essere infine reso disponibile nel template page.tpl.php mediante le variabili $primary_links e $secondary_links.

Il contenuto di Primary links


Dalla funzione menu_primary_links() torna un array $links[] ad esempio formato nel seguente modo:
$links[menu-45 active-trail][] = array() eventuali attibuti $links[menu-45 active-trail][href] => node/18 $links[menu-45 active-trail][title] => LINK_1 $links[menu-48][] = array() eventuali attibuti $links[menu-48][href] => node/19 $links[menu-48][title] => LINK_2 $links[menu-46l][] = array() eventuali attibuti $links[menu-46][href] => node/17 $links[menu-46][title] => LINK_3

Nell'esempio il menu formato da: le tre voci voci di titolo LINK1, LINK_2, LINK_3 i tre identificativi (mlid) definiti nella tabella MENU_LINKS : 45,48, 46 i tre riferimenti a cui puntano le voci :node/18 , node/19 , node/17 Questa array viene successivamente elaborata dalla funzione theme_links($primary_links,array('class' => 'links primary-links') ), chiamata nel file template page.tpl.php (tema garland), e che produce il codice HTML definitivo:.
<ul class="links primary-links"> <li class="first menu-45 active-trail"> <a href="/node/18" class="active">LINK1</a> </li> <li class="menu-48"> <a href="/node/19">LINK_2</a> </li> <li class="menu-46"> <a href="/node/17">LINK_3</a> </li> </ul>

Per la precisione in page.tpl.php viene chiamata la funzione theme('links',$primary_links,array('class' => 'links primary-links')) ma che sappiamo corrispondere alla theme_links(). Questa funzione peraltro pu essere personalizzata generando in template.php la funzione miotema_links() o phptemplate_links(). Il codice generato , infine incapsulato in page.tpl.php all'interno di un blocco <DIV> nel seguente modo:
<div class="links primary-links" > codice HTML prodotto </div>

Di seguito riportato il codice della funzione theme_links() fornita con Drupal . All'interno dell codice sono riportati alcuni commenti esplicativi.
<?php

24 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

// Parametri in ingresso // $links contiene l'array prodotto da menu_primary_links() // $attibutes un array che conterr il valore passato in page.tpl.php, in paticolare per il tema garland viene passata il // valore array('class' => 'links primary-links') function theme_links($links, $attributes = array('class' => 'links')) { $output = ''; // Qui vengono contati il numero di link del menu per definire la class 'first' e 'last' if (count($links) > 0) { // Inizio della lista con TAG <ul> l'attributo ID del tag corrisponde al valore 'class' passato in input $output = '<ul'. drupal_attributes($attributes) .'>'; $num_links = count($links); $i = 1; // Inizio lettura LINK foreach ($links as $key => $link) { // Definizione dell' attributo 'class' per il tag <li> // Il nome minimo sar menu-xx. nel nostro esempio menu-45 menu-46 menu-48 $class = $key; // Aggiunge 'first', 'last' e 'active' alla stringa della classe per meglio specificare l'elemento che si sta visualizzando. if ($i == 1) { $class .= ' first'; } if ($i == $num_links) { $class .= ' last'; } if (isset($link['href']) && ($link['href'] == $_GET['q'] || ($link['href'] == '<front>' && drupal_is_front_page()))) { $class .= ' active'; } // Scittura del tag <li> $output .= '<li'. drupal_attributes(array('class' => $class)) .'>'; // preparazione del tag anchor <a> if (isset($link['href'])) { // Pass in $link as $options, they share the same keys. $output .= l($link['title'], $link['href'], $link); } else if (!empty($link['title'])) { // Some links are actually not links, but we wrap these in <span> for adding title and class attributes if (empty($link['html'])) { $link['title'] = check_plain($link['title']); } $span_attributes = ''; if (isset($link['attributes'])) { $span_attributes = drupal_attributes($link['attributes']); } $output .= '<span'. $span_attributes .'>'. $link['title'] .'</span>'; } // fine primo link $i++; $output .= "</li>\n"; } // fine lista $output .= '</ul>'; } // torna il codice prodotto

return $output; } ?>

Il contenuto di Secondary links


Quanto detto per il menu Primary links vale per Il menu Secondary links.

25 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

E' utilizzata per la lettura dei contenuti la funzione: menu_secondary_links(). In page.tpl.php la variabile usata la $secondary_links. Il blocco <div> che coniene il codice HTML il seguente:
<div class="links secondary-links" > codice HTML prodotto </div>

Theme System
QUESTA SEZIONE E' IN LAVORAZIONE ---------------------------------------------Quando Drupal deve generare il codice HTML per elementi come nodi, blocchi , menu, breadcrumb, links e altro, cerca, per il tema corrente, le funzioni e file teplate che consentono di codificare gli elementi richiesti. La ricerca avviene applicando regole sulla priorit di ricerca, sui nomi e sulla posizione delle funzioni e dei file all'interno delle directory e dei moduli che consentono a Drupal di ottenere una elevata personalizzazione del sistema. Conoscendo e seguendo le regole di ricerca possibile personalizzare un sito generando nuove funzioni e file template in base alle proprie esigenze.

Sviluppare un Tema
Un tema identifica tutto ci che consente di visualizzare i contenuti del sito secondo una rappresentazione grafica definita dal tema stesso. I contenuti del sito sono quindi sempre gli stessi ma posizionati e visualizzati in modo diverso in funzione del tema scelto. Un tema costituito: da uno o pi file di stile. Il file principale degli stili si chiama style.css da un file che definisce l'intelaiatura principale del tema: page.tpl.php da file che definiscono l'intelaiatura dei contenuti della pagina: per i nodi: node.tpl.php per i blocchi:block.tpl.php per i box: box.tpl.php per i commenti: comment.tpl.php da un file (non sempre presente) template.tpl.php che contiene le funzioni tematizzate da uno pi file immagine , tipo logo, favico etc. e icone varie Tutta la gestione dei tema fatta da un motore (engine) apposito chiamato PHPTemplate Engine. PHPTemplate engine. Il file che costituisce il motore :miosito/themes/engines/phptemplate/phptemplate.engine. I file di template di questo engine hanno estensione .tpl.php e sono comtenuti nella directory del tema.

Convenzioni su nomi e file


Nome del tema Il nome del tema deve essere diverso dal nome di qualsiasi modulo Directory del tema

26 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

Tutti i file appartenenti alla definizione di un tema , devono stare allinterno di una propria subdirectory che prende il nome del tema. La subdirecotory pu essere contenuta all'interno di una delle seguente directory: miosito/themes/miotema miosito/sites/all/....../miotema Il motore di elaborazione del tema controller , per il tema selezionato, la presenza di file template con estensione .tpl.php. Il file screenshot del tema Il file deve essere in formato .png di dimensioni 150x90. Se presente viene mostrato nella pagina di amministrazione dei temi.

I file di stile CSS


Il file di stile del tema Il tema utilizza come dichiaratore di stile il file style.css per default. Altri file possono essere caricati utilizzando l'istruzione @import dei file css. Temi multipli con pi file di stile E possibile creare temi che differiscono per il solo file di definizione degli stili css:style.css. Per fare questo bisogna creare nella directory di base del tema, delle subdirectory contenenti i file style.css. Ogni subdirectory costituir un nuovo tema. Ad Esempio: miosito/sites/all/themes/miotema_A/ (directory principale del tema) template.tpl.php file di template comuni page.tpl.php file di template comuni ... style.css miotema_B/style.css miotema_C/style.css Il motore riconoscer tre temi: miotema_A, miotema_B, miotema_C. Ciascun tema utilizzer i file di base con estensione .tpl.php, e ciascuno avr nella propria subdirectory il file di stile style.css.

La suddivisione in Regioni
Funzioni principali: phptemplate_regions() drupal_set_content($region=NULL,$data=NULL) I temi possono definire ed implementare un numero generico di regioni. Le regioni sono essenzialmente contenitori di... contenuti. Le regioni suddividono la pagina del browser in aree che costituiranno i limiti in cui visualizzare i contenuti stessi. Cos, generalmente, tutti i temi hanno una regione per: i contenuti dellintestazione, header due regioni per i contenuti dei menu laterali, sidebar-left e sidebar-right una regione per i contenuti del fondo pagina, footer una regione centrale, content

27 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

ed altre regioni che possono complicare notevolmente il layout del sito. Definizione delle regioni Le regioni sono definite mediante una funzione php che torna un array associativo contenente la codifica delle regioni e la loro descrizione utilizzata nella pagina di amministrazione dei blocchi. La funzione la seguente:
function phptemplate_regions() { return array( 'left' => t('left sidebar'), 'right' => t('right sidebar'), 'content' => t('content'), 'header' => t('header'), 'footer' => t('footer') ); }

Il primo nome della regione diventa la regione di default per il posizionamento di blocchi nel caso in cui non sia dichiarata espressamente una regione. Nel caso di PhpTemplate Engine la funzione phptemplate_regions() contenuta nel file: miosito/themes /engines/phptemplate/phptemplate.engine. Drupal prima di chiamare questa funzione , verifica se esiste una funzione analoga fornita nei file template del tema corrente e che si chiami miotema_regions(). Per cui, per personalizzare le regioni di un tema, bisogna definire la funzione miotema_regions() nel file template.php nella directory del tema.
function miotema_regions() { return array( 'regione1' => t('regione1'), 'regione2' => t('regione2'), 'regione3' => t('regione3'), 'header' => t('header'), 'footer' => t('footer') );

Nel caso di .theme Engine la funzione contenuta nel file del tema miotema.theme Per riempire una regione possibile utilizzare la funzione
function drupal_set_content($region = NULL, $data = NULL) { static $content = array(); if (!is_null($region) && !is_null($data)) { $content[$region][] = $data; } return $content; }

Es.: drupal_set_content('left', 'Hello there.')

PHPTemplate theme engine


Il motore phptemplate contenuto nella direcotory themes/engines/phptemplate ed costituito dai seguenti file: 1) phptemplate.engine contenente le funzioni di default per la gestione di blocchi, box. commenti, nodi 2) default.tpl.php non ancora chiaro l'uso 3) node.tpl.php per la stampa delloggetto nodo 4) block.tpl.php per la stampa delloggetto blocco 5) box.tpl.php per la stampa delloggetto box 6) comment.tpl.php per la stampa delloggetto commento

28 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

Questi sono alcuni dei file necessari per la gestione di un tema di default. Ma per la realizzazione del tema sono necessari altri due file,fondamentali, contenuti obbligatoriamente nella subdirectory del tema selezionato: page.tpl.php il file principale del tema che definisce il layout del tema. style.css contiene la definizione degli stili del tema. Ogni tema pu quindi utilizzare, i due file page.tpl.php e style.css pi i cinque file di default .tpl.php contenuti in themes/engines/phptemplate oppure una loro implementazione personalizzata. In questo caso i file si dovranno chiamare allo stesso modo , ma dovranno trovarsi nella subdirectory del tema. Aggiungere un tema Per aggiungere un nuovo tema, si deve quindi: creare una nuova directory con il nome del tema in /sites/all/themes/miotema oppure /themes/miotema copiare nella directory i file *.tpl.php scrivere un nuovo file page.tpl.php per la definizione del layout del tema scrivere un nuovo file style.css per la definizione degli stili del tema La cosa pi semplice, comunque, prendere i file di un tema esistente, magari di quelli di default (bluemarine), copiarli nella nuova directory e cominciare a modificarli secondo le proprie esigenze.

block.tpl.php
I blocchi sono costituiti da codice HTML , eventualmente costruito dinamicamente da script PHP, posizionato allinterno di una regione del tema corrente. Esempi di un blocco sono i campi utente/password per il login al sistema, il menu di navigazione e in generale i menu utente, il calendario etc. Un blocco pu anche essere costituito da una singola stringa, immagine o altro da posizionare in una determinata regione del tema. Per definire un blocco si hanno due possibilit: Aggiunta da interfaccia di un nuovo blocco utente In questa modalit un utente con permessi di amministrazione dei blocchi, pu creare un nuovo blocco. Basta andare nella pagina di amministrazione dei blocchi ed eseguire Aggiungi blocco. Impostare un titolo e nellarea Corpo del blocco definire il codice HTML o PHP del nuovo blocco. Esempio.:
<p>questo un blocco </p> oppure <?php print questo un blocco; ?>

Attenzione, selezionare lopzione appropriata per il formato di input. Blocco che contiene un altro blocco Un blocco pu anche contenere, a sua volta, un altro blocco. Per richiamare un blocco utente scrivere:
<?php $block = module_invoke('block', 'block', 'view', 1); print $block['content']; ?>

29 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

Dove il valore 1 indica il delta , ma per i blocchi utenti rappresenta il primo blocco creato, 2 il secondo blocco creato etc. etc. Questo valore pu essere letto nella tabella blocks di MySQL nel campo delta. Il codice scritto dallutente &erave; invece contenuto nella tabella boxes nel campo body mettendo in join i campi boxes.bid = blocks.delta. Definizione di un modulo Per definire un blocco allinterno di un modulo Drupal, necessario implementare la funzione nomemodulo_block() allinterno del modulo. Questo esula dalla presente documentazione e si rimanda largomento alla trattazione dei moduli. Posizionamento di un blocco Tutti i blocchi definiti sono visibili nella pagina di amministrazione dei blocchi, da cui possibile indicare in quale regione visualizzare il blocco.

node.tpl.php
Template del tema corrente per la visualizzazione del contenuto di un nodo. E' usato nella fase di preparazione del codice HTML per il contenuto della pagina richiesta, preparazione avviata dalla funzione menu_execute_active_handler()

Stampa codice html:Le funzioni tematizzate; theme()


E' sconsigliato inserire direttamente codice HTML in Drupal, sebbene sia permesso dai formati di input (FilteredHTML,FullHTML). Drupal mette a disposizione delle funzioni proprio per produrre codice HTML personalizzabili all'interno di ciascun tema. Le funzioni che producono codice HTML, devono per poter funzionare per qualunque tema selezionato. Ad esempio volendo stampare una tabella si pu usare la funzione theme_table() o volendo stampare un blocco si pu usare la funzione theme_block(). Tutte le funzioni tematizzate di sistema si trovano nel file includes/theme.inc. Ma se, ad esempio, un tema deve visualizzare loggetto blocco in un modo particolare pu essere implementata la funzione theme_block(), chiamandola miotema_block(), ed inserendola nel file template.tpl.php. A questo punto necessario che Drupal sia in grado di sapere che esiste una funzione personalizzata ed usare quella invece della funzione di default. Prendondo come esempio la funzione theme_table(), Drupal, nel momento in cui deve chiamare la funzione, verifica, con le priorit indicate, se: Il tema implementa la funzione Verifica se la funzione theme_table() implementata nel tema corrente. La funzione implementata: si deve chiamare: miotema_table() pu stare nel file template.php o in un file .tpl.php del tema Il motore di template implementa la funzione Se il tema non implementa la funziona, Drupal verifica se la funzione theme_table() &egrave implementata dal motore di template del tema corrente. La funzione implementata: si deve chiamare phptemplate_table() pu stare:

30 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

nel file che implementa il motore (es.: phptemplate.engine) nei file .php o .tpl.php del tema (es.: template.php, block.tpl.php) Il sistema implementa la funzione Se il motore non implementa la funziona, Drupal chiama la funzione theme_table() implementata da sistema. La funzione implementata: star nel file includes/theme.inc Un help delle funzioni di sistema tematizzate pu essere trovato in http://api.drupal.org/api/group/themeable /5?sort=asc&order=Name La funzione theme() Quando abbiamo bisogno di chiamare una funzione tematizzata, bene non chiamare la funzione direttamente, ma lasciare che sia Drupal a fare questo per noi tramite la funzione theme('block',args). Infatti supponiamo di voler visualizzare una tabella all'interno di codice php scritto da noi, la chiamata alla funzione giusta potrebbe essere del tipo:
function miafunzione() { ...... // stampa tabella if (isset('miotema_table') miotema_table(.....); elseif (isset('phptemplate_table') phptemplate_table(.....); else theme_table(); ...... }

Tutto questo pu essere semplificato utilizzando la funzione theme() e delegare a Drupal la scelta della funzione corretta:
function miafunzione() { ...... // stampa tabella theme('table',$args); ...... }

Svilluppare un Modulo
Drupal cerca i moduli da installare nelle directory e sottodirectory: /modules contiene i moduli di sistema (core) /sites/all contiene altro tra cui moduli propri. E consigliato creare una sottodirectory per i moduli aggiuntivi. /sites/all/modules I file principali del modulo , che devono essere contenuti in /sites/all/modules/miomodulo si devono chiamare : miomodulo.info che contiene informazioni sul modulo miomodulo.install che contiene il codice per la installazione del modulo miomodulo.module che contiene il codice php miomodulo.css che contiene gli stili css del modulo

Tipologia dei moduli


31 di 42 22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

Un modulo pu essere di tipo: Block module Sono moduli che generalmente vengono posizionati sulle barre laterali. Drupal chiama la funzione miomodulo_block($op=='view') con opzione uguale a view per ottenere il contenuto del blocco. In particolare Drupal si aspetta un array $block di ritorno con i seguenti valori impostati: $block['subject'] = t('MioModulo'); $block['content'] = contenuto del blocco; Node module Sono moduli che generalmente generano pagine di contenuto come blog, forum, book pages. Le funzioni minime che bene definire per un modulo sono: miomodulo_block() miomodulo_help() miomodulo_perm()

Hook principali
IN FASE DI REALIZZAZIONE Elenco degli hook principali

hook_exit
Drupal chiama tutte le funzioni hook_exit() implementate nei moduli attivi, per avvisare che la pagina richiesta stata inviata e che le operazioni da attivare sono terminate. L' hook exit pu essere utile per eseguire un debugging del sistema o aggiornare, in fase di chiusura della pagina, alcune tabelle associate ai moduli. Due moduli di sistema che usano questo hook sono: Modulo statistics che esegue le statistiche di accesso al sito. Funzione statistics_exit(); Modulo throttle che esegue il controllo della congestione del sito. Funzione throttle_exit();

hook_load
Drupal chiama tutte le funzioni hook_load() implementate nei moduli attivi, per aggiungere campi non predefiniti nell'oggetto nodo. Ad esempio una rubrica telefonica pu avere campi come indirizzo, telefono etc. con un modulo rubrica che implementa la funzione rubrica_load (&$nodo)

Accesso ai moduli:permessi
Premesso che , laccesso ad un modulo viene impostato tramite la pagina Gestione utenti->Controlli accessi. In questa pagina compaiono per ogni modulo i permessi associati ad esso e per ogni permesso a quale ruolo assegnato il permesso.

32 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

I ruoli per default sono due: anonymous user e authenticated user. E possibile aggiungere altri ruoli utilizzando la pagina Gestione utenti->Ruoli. Detto questo, le descrizione dei permessi che compaiono nella pagina Gestione utenti->Controlli accessi sono definite mediante la funzione:
<?php function miomodulo_perm() { return array( "amministra contenuti miomodulo", "crea contenuti miomodulo");, } ?>

Qui sopra sono riportati solo due permessi, ma ovviamente ne potrebbero essere definiti altri. E' bene inserire sempre il nome nel modulo per ogni permesso. In caso contrario Drupal potrebbe assegnare la stringa di permesso a pi moduli, creando seri problemi all'impianto di sicurezza. Per verificare se lutente corrente ha determinati permessi usare la funzione user_access()
<?php if (!user_access("amministra contenuti miomodulo")) { $form['error'] = array('#type' => 'item', '#title' => t("Non sei autorizzato ad accedere a miomodulo.")); return $form; } ?>

Versioni precedenti alla 5.0 di Drupal usavano la funzione message_access() ora deprecata.

Messaggi di configurazione del modulo


Pagina dei moduli Nella pagina dei moduli le descrizioni associate al modulo provengono dal file miomodulo.info contenuto nella directory del modulo. Allinterno del file sono contenute almeno le prime due variabili:
$Id$ name = miomodulo description = "Descrizione MioModulo" dependencies = modulo1 modulo2 modulo3 package = MieModuli

con i seguenti significati name Nome del modulo description Descrizione del modulo dependencies Indica i moduli da cui il modulo stesso dipende. Drupal non attiver il modulo finch non saranno attivi i moduli da cui dipende package Pakage di appartenenza del modulo.Tutti i moduli appartenenti allo stesso package sono mostrati raggruppati nella pagina dei moduli Pagina dei blocchi Nome del blocco nella lista blocchi Funzione miomodulo_block($op=list) Esempio:
<?php function miomodulo_block($op = 'list', $delta = 0) { if ($op == "list") {

33 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

$block[0]["info"] = t('MioBlocco'); return $block; } } ?>

* Descrizione dell'help allinterno della configurazione del blocco Funzione miomodulo_help($section = "") Come definito al paragrafo Accesso ai moduli:permessi, i permessi di accesso ai moduli sono definiti mediante la funzione miomodulo_perm()
<?php function miomodulo_perm() { return array("amministra contenuti miomodulo", "crea contenuti miomodulo"); } ?>

Il valore di $section deve essere verificato posizionando il cursore sul link configura della pagina dei blocchi e vedere a quale percorso punta. Generalmente admin/build/block/configure/MioBlocco/0 e quindi scrivere la funzione miomodulo_help() nel seguente modo:
<?php function miomodulo_help($section = "") { $output = ""; switch ($section) { case "admin/build/block/configure/MioBlocco/0": $output = "<p>" . t("Descrizione di MioBlocco") . "</p>"; break; default: } return $output; } ?>

Pagina del controllo accessi utenti Come definito al paragrafo Accesso ai moduli:permessi, i permessi di accesso ai moduli sono definiti mediante la funzione miomodulo_perm()
<?php function miomodulo_perm() { return array("amministra contenuti miomodulo", "crea contenuti miomodulo"); } ?>

Style sheet
Quando un modulo ha fogli di stile propri, questi devono essere caricati prima di visualizzare il contenuto della pagina generata dal modulo. Nella pagina HTML generata da Drupal i file di stile compaiono secondo la sequenza: stile/i del modulo corrente stile/i del modulo corrente contenuti nel tema corrente stili di default di Drupal stili del tema corrente come di seguito indicato.
34 di 42 22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

<style type="text/css" media="all">@import "/sites/all/modules/miomodulo/miomodulo.css"</style> <style type="text/css" media="all">@import "/sites/all/themes/miotema/miomodulo.css"</style> <style type="text/css" media="all">@import "/modules/book/book.css"</style> <style type="text/css" media="all">@import "/modules/node/node.css"</style> <style type="text/css" media="all">@import "/modules/system/defaults.css"</style> <style type="text/css" media="all">@import "/modules/system/system.css"</style> <style type="text/css" media="all">@import "/modules/user/user.css"</style> ... <style type="text/css" media="all">@import"/sites/all/themes/miotema/style.css"</style> Per fare questo utilizzata la funzione drupal_add_css() secondo il codice riportato. L'esempio riporta il codice necessario per caricare il foglio di stile miomodulo.css. Questo codice deve essere chiamato dalle funzioni del modulo che preparano codice HTML.
function miomodulo_css_file() { $css_files = array(); // array in cui definire i file css // Definisce i percorsi dei file di stile $file_css_modulo = drupal_get_path('module', 'miomodulo') . '/miomodulo.css'; $file_css_modulo_in tema = path_to_theme() . '/miomodulo.css'; // se esistente // Definisce nell'array lo stile di default del modulo $css_files[] = array('file' => $file_css_modulo, 'type' => 'module', ); /* Definisce nell'array lo stile ripetuto nella directory del tema corrente Se esiste un file di stile nella directory del tema corrente con lo stesso nome dello stile del modulo lo carica. */ if (file_exists($file_css_modulo_in tema) { $css_files[] = array('file' => $file_css_modulo_in tema, 'type' => 'theme', ); } // Avvisa Drupal di caricare i fogli definiti foreach ($css_files as $css_file) { drupal_add_css($css_file['file'], $css_file['type'], 'all', false); } }

Tabelle
Tabella BLOCK Tabella BLOCK_ROLES Tabella BOXES Tabella MENU_CUSTOM Tabella MENU_LINKS Tabella MENU_ROUTER Tabella NODE Tabella NODE_REVISIONS Tabella ROLE Tabella URL_ALIAS Tabella USERS Tabella USERS_ROLES

Tabella BLOCKS
La tabella BLOCKS contiene le informazioni sui blocchi:tipo, regole di accesso, tema , regione etc.
Tabella BLOCKS I campi sono i seguenti: module T indica da quale modulo gestito il blocco

35 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

delta theme status weight region custom throttle

T identificativo univoco del blocco in riferimento al proprio modulo T indica che il blocco pu essere visualizzato per il tema N =1 il blocco abilitato N ordine di visualizzazione del blocco T indica la regione in cui deve essere visualizzato T T

visibility N indica il tipo di visualizzazione delle pagine pages title bid cache T elenco delle pagine in cui vera il tipo di visibility T titolo del blocco N identificativo univoco del blocco N assume valore 1 o -1

La chiave primaria PRIMARY KEY UNIQUE KEY bid, theme,module,delta

Tabella BLOCK_ROLES
La tabella BLOCK_ROLES riporta l'identificativo rid (roles identifier) che indica il ruolo necessario per visualizzare il blocco. I ruoli sono definiti nella tabella dei ruoli "role"
Tabella BLOCK_ROLES I campi sono i seguenti: module T indica da quale modulo gestito il blocco delta rid T identificativo univoco del blocco in riferimento al proprio modulo N iidentificativo univoco del ruolo (vedi tabella role)

PRIMARY KEY

module,delta,rid

Tabella BOXES
La tabella BOXES contiene il contenuti dei blocchi gestiti dal modulo block.
Tabella BOXES I campi sono i seguenti: bid body info N iidentificativo univoco del blocco T il contenuto del blocco T ripete il titolo del blocco

format N tipo di formato (da tabella FILTER_FORMATS)

PRIMARY KEY bid UNIQUE KEY info

Tabella MENU_CUSTOM

36 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

La tabella MENU_CUSTOM contiene l'elenco di tutti i menu definiti dall'utente oltre ai menu di navigazione 'navigation', 'primary-links' e 'secondary-links'.
Tabella menu_custom I campi sono i seguenti: menu_name title description T T T identificativo interno del menu titolo del menu visualizzato descrizione del menu

La chiave primaria : PRIMARY KEY = menu_name

Tabella MENU_LINKS

Tabella MENU_LINKS
La tabella MENU_LINKS contiene informazioni relative alla struttura del albero del menu con tanti record quante sono le voci del menu. Per ogni voce definita l' url a cui punta (link_path).
Tabella menu_links I campi sono i seguenti: menu_name mlid plid link_path router_path link_title options module hidden external has_children expanded weight depth customized p1 p2 p3 p4 p5 p6 p7 T N N T T T T T N N N N N N N N N N N N N N identificativo del nodo radice dell'albero identificativo del padre di secondo livello identificativo del padre di terzo livello identificativo del padre di quarto livello identificativo del padre di quinto livello identificativo del padre di sesto livello identificativo del padre di settimo livello nome del menu identificativo univoco della voce all'interno del identificativo univoco del padre path a cui punta la voce del menu path a cui punta la voce del menu definito in MENU titolo della voce valori degli attributi in forma serializzata nome del modulo che gestisce il menu =1 la voce del menu deve essere nascosta

=1 la voce del menu punta a una URL esterna al sit =1 =1 la voce ha figli la voce deve essere espansa

ordine della voce all'interno del meni profondita della voce

37 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

p8 p9 updated

N N N

identificativo del padre di ottavo livello identificativo del padre di nono livello

La chiave primaria : PRIMARY KEY = mlid

Tabella MENU_ROUTER
La tabella MENU_ROUTER contiene le informazioni sulle funzioni da attivare per raggiungere la pagina richiesta nel menu
Tabella menu_router I campi sono i seguenti: path load_functions to_arg_functions access_callback access_arguments page_callback page_arguments fit number_parts tab_parent tab_root title title_callback title_arguments type block_callback description position weight file T T T T T T T N N T T T T T N T T T N T percorso paramentrizzato a cui puntare (Es: node/%/edit) funzione di caricamento (load) funzione di caricamento

argomenti della

funzione che controlla l'accesso al menu argomenti della funzione di accesso funzione di visualizzazione della pagina richiesta argomenti della funzione di visualizzazione ordine in cui vengono selezionati i possibili path [vedi menu_get_item()] uso interno ?? ?? titolo della voce di menu funzione di conversione del titolo [t(); check_plain() etc.] ?? ?? ?? descrizione della voce ?? ordine di visualizzazione eventuale file di template da caricare prima di chiamare la page_callback

La chiave primaria : PRIMARY KEY = path

Tabella NODE
La tabella NODE contiene l'elenco di tutti i nodi inseriti nel sistema. Per un sito multilingua ogni traduzione introduce un nuovo nodo che si riferisce alla lingua di traduzione.
Tabella node I campi sono i seguenti:

38 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

nid vid type title uid status created changed comment promote moderate sticky language tnid translate

N N T T N N N N N N N N T N N

identificativo univoco del nodo identificativo nel numero di revisione nella tabella NODE_REVISONS

tipo del nodo. Tabella di codifica NODE_TYPE titolo del nodo identificativo utente del proprietario del nodo =0 non visibile; =1 visibile timestamp della data di creazione del nodo timestamp della data di modifica del nodo identificativo utente dell'ultimo commento =1 il nodo visualizzato in prima pagina =1 il nodo deve essere controllato prima della pubblicazione numero d'ordine del nodo nella prima pagina lingua del contenuto:'it' , 'en', 'fr', identificativo univoco del nodo sorgente per le traduzioni =1 deve essere aggiornata la traduzione. Il nodo sorgente cambiato

La chiave primaria : PRIMARY KEY = nid

Tabella NODE_REVISIONS

Tabella NODE_REVISIONS
La tabella NODE_REVISIONS contiene le informazioni sul contenuto principale dei nodi (body) , sul sommario (teaser) , il titolo (title) e le revisioni eseguite. Inoltre il campo format indica come il contenuto deve essere filtrato, prima di visualizzarlo. Ogni nodo ha quindi pi record indicatii dall'identificativo univoco del nodo stesso (nid) e dall'identificativo della revisione (vid).
Tabella node_revisions I campi sono i seguenti: nid vid uid title body teaser log timestamp format N N N T T T T N N identificativo univoco del nodo identificativo del numero di revisione identificativo utente del proprietario del nodo titolo del nodo per la revisione corrente contenuto del nodo per la revisione corrente sommario del nodo per la revisione corrente

Messaggio di log contenente le modifiche eseguite data di modifica del nodo formato del nodo da tabella FILTERS_FORMAT

La chiave primaria : PRIMARY KEY = vid

39 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

Tabella ROLE
La tabella ROLE indica i ruoli che possono essere assegnati ad un utente. Ad esempio, amministratore, webmaster, etc Mediante i ruoli possono essere nascosti contenuti, blocchi e menu.
Tabella ROLE I campi sono i seguenti: rid name N iidentificativo univoco del ruolo T nome del ruolo

PRIMARY KEY rid UNIQUE KEY name

Tabella URL_ALIAS
La tabella URL_ALIAS definisce la tabella di corrispondenza tra un percorso interno al sistema e un alias del percorso definito dall'utente
Tabella url_alias I campi sono i seguenti: pid src dst language N T T T identificativo univoco del path percorso originale alias del percorso linguaggio associato all'alias del percorso

La chiave primaria : PRIMARY KEY = pid

Tabella USERS
La tabella USERS contiene informazioni sugli utenti
Tabella users I campi sono i seguenti: uid name pass mail mode sort threshold theme signature created access N T T T N N N T T N N identificativo utente nome utente password utente mail utente modo di visualizzazione del commento:threaded o flat modo per l'ordinamento dei commenti non pi usato tema di default firma utente timestamp della data di creazione del nodo timestamp ultimo accesso

40 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

login status timezone language picture init data timezone_name

N N T T T T T T

timestamp ultimo login utente =0 utente bloccato, =1 utente attivo timezone dell'utente lingua di default percorso all'immagine utente email forniti al momento della registrazione serializzazione di un array che rappresenta i campi dela form utente nome timezone tipo Europe/Rome

La chiave primaria : PRIMARY KEY = uid

Tabella USERS_ROLES
La tabella USERS_ROLES indica i ruoli assegnati a ciascun utente. Nella visualizzazione dei blocchi , questo permette di nascondere i blocchi agli utenti senza il ruolo richiesto per la visualizzazione
Tabella USERS_ROLES I campi sono i seguenti: uid N identificativo univoco dell'utente rid N iidentificativo univoco del ruolo

PRIMARY KEY

uid,rid

Editor per Drupal


Riporto alcuni degli editor pi diffusi per Drupal BUeditor FCKeditor HTMLarea Quicktags Texy TinyMCE esempio TinytinyMCE Whizzywig Widgeditor Wymeditor Wysiwyg XStandard YUIeditor

41 di 42

22/01/2010 13:28

Guida a DRUPAL

http://enzoazzolini.it/book/export/html/87

42 di 42

22/01/2010 13:28