Sei sulla pagina 1di 392

Plone Book

Versione italiana

Comunità Plone Italiana


lele@seldati.it

2005-03-14 10:21:24 +0100 (lun, 14 mar 2005)


2

Revisione: 1081
Copyright: OPL

Importante
I sorgenti di questa versione italiana del Plone Book, con la storia dettagliata di tutte le
modifiche apportate a ciascun capitolo, sono quindi disponibili all’URL:
http://docit.bice.dyndns.org/cgi-bin/viewcvs.cgi/Plone/PloneBook/
Indice

3
4 INDICE
Capitolo 1

Capitolo 1: Introduzione a Plone

5
6 CAPITOLO 1. CAPITOLO 1: INTRODUZIONE A PLONE
Indice

Note alla traduzione del capitolo


workflow: controllo di flusso
content management system: sistema di gestione di contenuti
template: modello
Zope Page Template: modelli di pagina Zope

Una azienda senza un sito web è una cosa inimmaginabile, e molte aziende e organizzazioni dispongono di più
di un sito. Magari un sito esterno per comunicazioni ai clienti e uno per la intranet dei dipendenti o un sito per
ricevere direttamente ordinazioni e comunicazioni dai clienti: tutti i siti web hanno il comune problema di come
gestire i loro contenuti. È una attività che spesso richiede alle organizzazioni molto tempo e risorse. Non è facile
infatti creare un sistema sufficientemente potente e flessibile per siti simili che devono poter essere in continuo
movimento e contemporaneamente soddisfare le crescenti necessità aziendali.
Indipendentemente dalle esigenze del sito o dalla quantità di contenuti o di utenti, Plone è una potente soluzione
orientata all’utente che consente di aggiungere e modificare qualsiasi tipo di contenuto via web, che rende dispo-
nibile la navigazione e la ricerca in quei contenuti e che vi applica una politica di sicurezza ed un controllo di
flusso.
Plone permette di mettere insieme quasi ogni tipo di sito web e di aggiornarlo facilmente. Ciò significa costruire
velocemente siti ricchi di contenuti ottenendo un notevole vantaggio competitivo. Infine probabilmente la mi-
glior cosa di questo sistema è che è libero e a sorgente aperto. Con la sua ampia disponibilità di strumenti e
caratteristiche è paragonabile, se non migliore, a molti sistemi di gestione di contenuti proprietari che costano
migliaia e migliaia di euro.
Nel suo intervento alla Open Source Content Management Conference (OSCOM) del 2002 a proposito del sito
di Mindjack (http://www.mindjack.com/events/oscom.html), Mike Sugarbaker ha affermato:

“Non farò un resoconto completo di tutti i framework di content management open source a di-
sposizione. La farò breve: il vincitore è Plone. Questo prodotto trae giovamento dai sei anni di
maturazione di Zope, un framework per applicazioni web: per tutto questo periodo è stato il pac-
chetto più ricco di strumenti, il più professionale, quello più seguito e, sopra tutto, il più eccitante
(buzz).”

Si può vedere il sito web di Plone all’indirizzo http://www.plone.org come si vede in figura 1-1. Per provare
immediatamente e facilmente Plone c’è un sito dimostrativo disponibile all’indirizzo http://demo.plone.org. Lì
in particolare sarà possibile aggiungere eventi, caricare immagini, aggiungere documenti ed elaborarli tramite
l’ambiente di sviluppo che Plone fornisce.

7
8 INDICE

Figura 1.1: Figura 1-1. Il sito web Plone


1.1. CHE COSA È UN CONTENT MANAGEMENT SYSTEM? 9

1.1 Che cosa è un Content Management System?


Una definizione semplicistica di Content Management System (CMS) è sistema di gestione di contenuti. Questa
non è una definizione molto utile e quindi andremo a suddividerla in piccole parti per darne una spiegazione
migliore. Iniziamo con una definizione generica di contenuto: contenuto è una unità di dati con alcune infor-
mazioni extra attaccate ad esso. Tale insieme di dati può essere una pagina web, una informazione su un evento
imminente, un documento di Microsoft Word, una immagine, una registrazione video, o qualsiasi insieme di dati
che abbia un significato per l’azienda che sviluppa il sistema.
Tutti questi elementi sono detti contenuti e possono condividere attributi simili come l’essere modificabili ed
aggiungibili solo da determinati utenti o di essere pubblicati in varie maniere. Un sistema detto controllo di
flusso controlla questi attributi. Il controllo di flusso è la logica definita dagli obiettivi dell’organizzazione e
descrive un sistema per gestire i contenuti.
Storicamente c’è differenza tra un sistema di gestione di documenti rispetto ad un sistema di gestione di contenuti
ma per gran parte i due sistemi convergono. La maggiore differenza sta negli elementi che vengono gestiti;
solitamente viene considerato contenuto qualsiasi unità di informazione mentre documento è riferito a qualcosa
creato e modificato dagli umani con software come Microsoft Office. Pensiamo ad esempio ad un libro: un
libro contiene molte unità di dati e può richiedere una gestione leggermente differente da quella richiesta da un
contenuto. Comunque nella maggioranza dei casi questa è una differenza minima e un prodotto come Plone è in
grado di gestire le piccole unità che compongono pezzi di contenuto più grandi e di riassemblarli.
Nell’ubiquità del web molti CMS sono ora classificati come CMS web sia che si basino su una interfaccia web sia
che abbiano come scopo il sistema di distribuzione su internet o su una intranet. Plone fornisce una interfaccia
di gestione web e un sistema di distribuzione dei contenuti sul web.
La seguente è una definizione di un CMS (http://www.contentmanager.eu.com/history.htm):

Un CMS è uno strumento che consente ad una grande varietà di collaboratori tecnici (centralizzati)
e non-tecnici (decentralizzati) di creare, modificare, gestire e infine pubblicare un gran numero di
contenuti (come testi, oggetti grafici, video e così via) mentre questi sono controllati da un insieme
di regole centralizzate, processi e controlli di flusso che assicurano un’apparenza web validata e
coerente.

1.2 Abbiamo bisogno di un Content Management System?


Sebbene non sia l’unico vantaggio di un CMS il più ovvio è la facilità di coordinamento di un sito web. Con-
sideriamo la situazione in cui una persona, il Webmaster, coordina un sito web, sia esso su una intranet che un
sito esterno. I contenuti arrivano dagli utenti in formati diversi ed il webmaster li converte in pagine web trasfor-
mandoli in Hypertext Markup Language (HTML). Se l’utente deve modificare queste pagine invia le modifiche al
webmaster che modifica le pagine e così via.
Ciò comporta svariati problemi per le organizzazioni, il maggiore dei quali è il fatto che tutti i contenuti passano
da una persona, un autentico collo di bottiglia.
Oltre al fatto che una persona può fare solo una certa quantità di lavoro, se questa persona è ammalata o lascia
l’azienda vi è una grande perdita di produttività ed alti costi per rimpiazzarla. Il processo di pubblicazione
potrebbe divenire assai frustrante con flussi di e-mail tra il webmaster e l’utente che cerca di pubblicare del
contenuto.
Ciò che è necessario è un sistema che faccia le seguenti cose:

Separazione del contenuto di una pagina dalla sua composizione Se l’effettivo contenuto è separato dalla com-
posizione l’autore del contenuto non ha la necessità di conoscere il linguaggio HTML e come la pagina viene
distribuita. Ad un medesimo pezzo di contenuto possono essere applicati infatti molti differenti modelli
10 INDICE

di presentazione, anche formati differenti dall’HTML come il Portable Document Format (PDF) o Scalable
Vector Graphics (SVG). Quando si desidera modificare l’aspetto del proprio sito è sufficiente modificare
un modello piuttosto che l’intero contenuto.
Consentire l’aggiunta e la modifica dei contenuti da parte di certi utenti Se determinati utenti possono ag-
giungere e modificare facilmente i loro contenuti essi non hanno la necessità di inviarli al webmaster o
passarli al gruppo web. Invece l’utente che voglia creare una pagine può farlo ed eventualmente modificarla
successivamente quante volte sia necessario.
Applicare regole su chi può pubblicare cosa e quando Gli affari non consentono probabilmente che chiunque
possa pubblicare contenuti ovunque nel proprio sito web; per esempio il personale del marketing dovrebbe
essere in grado di pubblicare solo nella sezione delle stampe e non in quella dei progetti.
Poter applicare regole di revisione ai contenuti Se una persona del marketing crea un comunicato stampa qual-
cuno del reparto legale dovrebbe visionare i contenuti di quel documento. In questo caso il documento
attraverserà un processo di revisione che assicuri che non venga pubblicato finché tali revisioni non siano
state effettuate.
Poter ricercare ed indicizzare le informazioni in modo intelligente Siccome il CMS può tenere traccia di in-
formazioni strutturate relative al contenuto (come il nome dell’autore, la data di pubblicazione, le date delle
modifiche, categorie, e così via) può produrre elenchi di contenuti per autore, modifiche recenti, e così via.
Consente funzionalità di ricerca avanzate che sono più veloci ed utili della semplice ricerca testuale.

Sebbene questo esempio ritragga interessi che sono più significativi per le grandi organizzazioni, lo stesso ap-
proccio può portare notevoli benefici a organizzazioni di qualsiasi dimensione. Sono infatti le piccole aziende,
che non possono impiegare un webmaster a tempo pieno, che possono ottenere un beneficio decisivo utilizzando
questo sistema. Installando un CMS possono essere risolti questi ed altri problemi.
Il fattore importante di ogni CMS è che fornisca una chiara separazione dei suoi elementi chiave: sicurezza,
controllo di flusso, modelli di pagina (templates), e così via. Per esempio i template che mostrano un elemento
devono essere separati dal contenuto. Questo consente di modificare rapidamente l’aspetto.

1.3 Funzionalità chiave di Plone


Plone è un software a sorgente aperto (open source) licenziato sotto i vincoli della General Public License
(GPL) che è una diffusissima licenza open-source che consente a chiunque il libero (ri)uso del codice sorgente.
Per maggiori informazioni riguardo la licenza GPL si visiti il sito della Free Software Foundation all’indirizzo
http://www.gnu.org. Si può esaminare il codice sorgente di Plone in ogni suo aspetto e modificarlo secondo le
proprie necessità. Non ci sono onorari da pagare o licenze che scadono e tutto il codice è visibile. Da questa
filosofia open-source deriva il fatto che Plone ha una grande base di utilizzatori e legioni di di sviluppatori, esperti
di usabilità, traduttori, tecnici commentatori e designer grafici che sanno lavorare su Plone. Scegliendo Plone non
si viene intrappolati da una azienda ma piuttosto si possono usufruire di servizi da parte di dozzine di aziende.

1.3.1 Pacchettizzato
Plone dispone di pratici programmi di installazione per Windows, Linux e Mac. Assieme a questi installer
vengono forniti anche altri prodotti third-party (compatibili con Plone ma non mantenuti da plone.org n.d.t.)
e add-ons (aggiunte). La qualità nei rilasci di questi prodotti rende facili l’installazione e la manutenzione.
Inoltre ogni nuovo rilascio conserva i path nella migrazione in modo che un sito viene mantenuto attivo e rimane
aggiornato.
1.3. FUNZIONALITÀ CHIAVE DI PLONE 11

1.3.2 Internazionale
L’intera interfaccia utente di Plone è tradotta in più di 20 lingue, incluso il Coreano, il Giapponese, il Francese,
lo Spagnolo, il Tedesco e l’Italiano. È facile inserire una nuova traduzione (vedi capitolo 4).

1.3.3 Usabile
Plone consente una eccellente esperienza da parte dell’utente con un alto livello di usabilità ed accessibilità. Non
si tratta solamente di presentare un buon HTML ma di un aspetto che parte dalle fondamenta Plone. L’interfaccia
di Plone è completamente compatibile con gli standard industriali e governativi (WAI-AAA e U.S. Section 508 ).
Ciò permette, per esempio, alle persone con disfunzioni visive di usare comunque i siti costruiti con Plone.
Questa caratteristica ha un beneficio inatteso e correlato: le pagine sono indicizzate molto meglio dai motori di
ricerca come Google.

1.3.4 Aspetto personalizzabile


Plone separa il contenuto dai modelli effettivamente utilizzati per presentarlo, chiamati in gergo skin. Gli skin
sono scritti con un eccellente sistema di modellazione HTML, lo Zope Page Template (ZPT) e un largo uso del
Cascading Style Sheets (CSS). Anche con una scarsa conoscenza di Plone è possibile applicare skin multipli al
proprio sito, dargli aspetti diversi e personalizzarne completamente l’apparenza.

1.3.5 Registrazione utenti e personalizzazione


Plone offre un completo sistema di registrazione utenti. Gli utenti sono registrati nel sito Plone con i loro no-
meutente e password e qualsiasi altra informazione fosse necessario aggiungere all’utente. È possibile quindi
personalizzare completamente l’interfaccia dell’utente. Inoltre, con degli add-ons, è possibile usare informazioni
preesistenti sugli utenti, provenienti da fonti diverse come database relazionali, Lightweight Directory Access
Protocol (LDAP), Active Directory, e altri. Il capitolo 8 spiega come registrare e configurare gli utenti.

1.3.6 Workflow e Sicurezza


I workflow controllano la logica di elaborazione dei contenuti dell’intero sito. È possibile configurare questa
logica usando strumenti grafici via web. Gli amministratori dei siti possono creare siti complessi o semplici
quanto vogliono; per esempio è possibile aggiungere strumenti di comunicazione come la spedizione di posta o
di messaggi istantanei agli utenti. Il ‘capitolo 9‘_ entra nei dettagli dei workflow.
Per ciascun elemento contenuto in un sito Plone è possibile impostare una lista di controllo degli accessi (Access
Control Lists, o ACL) per decidere chi ha accesso a quell’elemento e come possa interagire con esso. Possono
modificarlo, vederlo o commentarlo? Tutto ciò è configurabile via web (vedi il ‘capitolo 9‘_).

1.3.7 Estensibile
Essendo open-source Plone è facilmente modificabile. È possibile configurare quasi ogni aspetto di Plone per
soddisfare qualsiasi necessità.
Vi sono innumerevoli pacchetti e strumenti per Plone che forniscono un ampio spettro di opzioni valide per i siti
di piccole aziende come per organizzazioni di larga scala. All’indirizzo http://www.plone.org sono disponibili dei
repository che contengono numerose aggiunte (free add-ons). Tramite strumenti di sviluppo come Archetypes
(descritto nel capitolo 13) è possibile generare e modificare facilmente il codice via web o usare strumenti di tipo
Unified Modeling Language (UML). Il capitolo 10 tratta l’integrazione in Plone di soluzioni e servizi aziendali
come LDAP, Apache, Microsoft Internet Information Services (IIS), Macromedia Dreamweaver e così via.
12 INDICE

1.3.8 Personalizzazione dei contenuti


Gli utenti di un sito Plone possono aggiungere qualsiasi tipo di contenuto senza limiti o costrizioni dei dati
aggiunti. Gli sviluppatori di Plone possono creare loro tipi di contenuti tanto che è possibile gestirne quasi di
ogni tipo: l’unico limite è l’immaginazione. Nel Capitolo 11 e nel Capitolo 12 discuteremo come gestire i tipi di
contenuti. Il capitolo 13 introdurrà Archetypes che è un potentissimo sistema per generare nuovi tipi di contenuti
che non richiede programmazione; per esempio è possibile generare nuovi tipi di contenuti da strumenti UML.

1.3.9 Documentazione
Il progetto Plone mantiene la documentazione, incluso questo libro, pubblicandola sotto la licenza Creative Com-
mons. Il miglior posto per iniziare a conoscere la documentazione della comunità è l’indirizzo http://www.plone.org/document

1.3.10 Comunità
Una delle cose migliori di Plone è la comunità di programmatori ed organizzazioni che lo supportano e lo svi-
luppano. Vi sono oltre 60 sviluppatori distribuiti in tutto il mondo che sono coinvolti nel progetto a vari livelli
ed è quasi sempre possibile trovarne uno in linea in grado di aiutarti. Alan Runyan, Alexander Limi e Vidar
Andersen sono quelli che hanno iniziato a scrivere Plone ma subito si sono coinvolti nello sviluppo del progetto
open-source molti altri sviluppatori. L’aspetto attuale di Plone è il frutto dei contributi di codesti sviluppatori.

Esempi di siti Plone

Esistono molti siti Plone; alcuni sono ovvii per il loro aspetto, altri no. Quella che segue è solo un piccolo spettro
dei vari siti:

• Plone (http://www.plone.org)
• Plone Demo Site (http://demo.plone.org)
• Zope.org (http://www.zope.org)
• Liquidnet (http://www.liquidnet.com)
• Design Science Toys (http://www.dstoys.com)
• Give Kids the World (http://www.gktw.org)
• Propane (http://www.usepropane.com)
• Maestro Headquarters (http://mars.telascience.org)

Molti altri siti Plone sono elencati su http://www.plone.org/about/sites, tra cui anche siti che si presentano con
una interfaccia utente molto differente. Senza conoscere qualcosa sul come sono stati sviluppati, sarebbe infatti
molto difficile affermare che questi siti sono basati su Plone.
1.4. COME COLLABORARE ALLO SVILUPPO DI PLONE 13

1.4 Come collaborare allo sviluppo di Plone


Sebbene Plone offra già una impressionante lista di funzionalità, la lista delle richieste è ancora più grande. Per
questa ragione il progetto viene studiato sempre da nuove persone che vi vogliono dedicare il loro tempo.
Fortunatamente, essendo focalizzato sull’utente finale, ha la capacità di servire ad un ampio spettro di discipline.
Sono quindi benvenuti volontari di ogni area piuttosto che solo sviluppatori di codice per il web. Plone necessità
di sviluppatori per l’interfaccia utente, esperti di usabilità, designer grafici, traduttori, scrittori e collaudatori. È
possibile conoscere l’attuale stato dello sviluppo nel sito web di Plone all’indirizzo http://plone.org/development
ed il modo migliore per coinvolgersi è quello di collegarsi alle mailing list o contattare gli sviluppatori tramite i
canali Internet Relay Chat (IRC).
Plone è realizzato con Zope ed il suo Content Management Framework (CMF). Per capire Plone è necessario
capire come funziona Zope ed il CMF e come sia l’architettura sottostante. Per questo motivo, nelle sezioni che
seguono, spiegheremo questi due elementi e come sono integrati in Plone.
Zope è una applicazione open-source, sviluppata dalla Zope Corporation (http://www.zope.org), e fa da server
web. Inizialmente era sviluppato come ambiente di gestione di contenuti (CMS) autonomo ma nel tempo non
rispondeva più alle necessità dei suoi utenti. La Zope Corporation lo ha quindi sviluppato come progetto open-
source. Il CMF fornisce agli sviluppatori gli strumenti necessari per creare complessi CMS: abilita il controllo di
flusso, consente lo skinning ed offre molte altre funzionalità.
Il CMF è un ambiente per creare un sistema: in altre parole fornisce agli sviluppatori gli strumenti per costruire un
prodotto piuttosto che semplicemente dare un sistema precostruito da usare immediatamente. Plone usa queste e
molte altre funzionalità e le organizza per fornire all’utente un prodotto di alta qualità. Plone è uno strato software
che si appoggia al CMF, che a sua volta è un’applicazione che gira in Zope. Comprendere il CMF è la chiave per
capire Plone. Gran parte delle funzioni amministrative prevedono l’uso dell’interfaccia amministrativa di Zope
(ZMI) e quindi lo sviluppo di Plone richiede la comprensione di Zope e dei suoi oggetti.
Questo libro non approfondisce Zope ma da istruzioni sul come raggiungere gli obiettivi in Plone. Leggendo que-
sto libro si avranno sufficenti informazioni per personalizzare e modificare qualsiasi cosa si voglia in Plone. Per
maggiori informazioni su Zope raccomandiamo il Manuale di Zope (The Zope Book ). Originariamente pubblica-
to presso New Riders è stato successivamente messo online e viene aggiornato dai membri della comunità. È sca-
ricabile liberamente dalla rete all’indirizzo http://www.zope.org/Documentation/Books/ZopeBook/2_6Edition.
Sia Zope che il CMF sono tecnologie chiave su cui si basa Plone: senza di esse Plone non potrebbe esistere.
Il gruppo di sviluppo di Plone deve grande riconoscenza a ciascun membro della Zope Corporation per aver
intuito, creato ed offerto sia Zope che il CMF come software open-source. L’elenco delle persone che vorremmo
lì ringraziare e quello della comunità CMF è molto lungo. Grazie quindi a ciascuno che è coinvolto in questo
progetto.
Zope è scritto con Python, un potente linguaggio open-source di programmazione orientata agli oggetti paragona-
bile al Perl o a Tcl. Non è necessario conoscere il Python per usare Plone e neppure per tenerne l’amministrazione
base ma, per personalizzare i prodotti e per gli script, Plone richiede un po’ di Python.
Tommy Burnette, un direttore tecnico di Industrial Light Magic, dice quanto segue a proposito di Python (http://www.python.org/Quotes.htm

“Python gioca un ruolo chiave nella nostra linea produttiva. Senza di esso sarebbe stato molto
difficile realizzare un progetto delle dimensioni di Star Wars: Episode II.”

Se si vuol costruire qualcosa di sofisticato con Plone è utile studiare le basi del Python almeno per un paio di
giorni. Questo non solo permette di personalizzare Plone in profondità ma famigliarizza con gli oggetti e con il
modo con cui questi interagiscono con l’ambiente in Plone. Non è lo scopo di questo libro quello di insegnare
Python e si assume che il lettore ne abbia almeno una conoscenza di base. La conoscenza delle basi Python è
sufficiente per proseguire la lettura di questo libro e consente una agevole personalizzazione dell’installazione
Plone.
14 INDICE

Fortunatamente, Python è un linguaggio di programmazione facile da apprendere; in media, una giornata di


studio è sufficiente ad un programmatore esperto per essere produttivo. Programmatori meno esperti avranno
bisogno di un po’ più di tempo. Installando Plone su Windows o Mac con l’apposito installer assicura l’inclusione
della corretta versione di Python. Per scaricare Python separatamente, per qualsiasi sistema operativo o quasi,
consultare http://www.python.org.
La maniera migliore per imparare Python è quella di provarlo usando l’interprete di serie. Nell’installazione su
Windows è presente un link a Pythonwin, un ambiente integrato per lo sviluppo (IDE), direttamente nel menu di
Avvio; seleziona Avvio - Programmi - Plone - Pythonwin (vedi Figura 1-2).

In Linux e in Mac OS X inserendo il comando python si avvia l’interprete Python:

$ python
Pyython 2.3.2 (#1, Oct 6 2003, 10:07:16)
[GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

Python è un linguaggio interpretato ed è quindi possibile inviare semplicemente linee di codice all’interprete
mano a mano che le si scrivono piuttosto che dover compilare ed eseguire un intero script. Ciò rende l’interprete
un posto di una utilità stupefacente per provare e controllare codice (testing e debugging). Nell’interprete ogni
linea in attesa di un input è prefissata con >>>.
Per esempio il semplice programma Hello, World è come segue

>>> print "Hello, world!"


Hello, world!
>>>

Per uscire dall’interprete premere Ctrl+D (Premere il tasto D mentre si preme Ctrl) se si è in Linux mentre in
Windows premere Ctrl+Z. (Questo servirà anche in seguito in una più avanzata interazione tra Zope e Plone).
Per eseguire dei normali script Python è sufficente passarli all’interprete; per esempio dando il seguente script
chiamato hello.py:

print "Hello, world!"

Puoi eseguirlo con il seguente comando:

$ python hello.py
Hello, world!

Il sito ufficiale di Python http://www.python.org contiene dell’eccellente documentazione compreso un ottimo


tutorial. Anche i seguenti libri forniscono una buona panoramica di Python:

Dive Into Python ((Apress, 2004))


Basato sul popolare tutorial di Mark Pilgrim, questo libro porta il lettore attraverso una rapida introduzione
al linguaggio Python. È un gran bel libro che si rivolge in particolare ai programmatori esperti.
Learning Python, Second Edition ((O’Reilly, 2003))
Questo libro riguarda la versione 2.3 di Python e offre una buona panoramica su Python e su tutte le nuove
funzionalità. È particolarmente adatto per programmatori relativamente nuovi.
1.4. COME COLLABORARE ALLO SVILUPPO DI PLONE 15

Figura 1.2: Figura 1-2. Il prompt di Python su Windows


16 INDICE

Practical Python ((Apress, August 2002))


Questa introduzione molto pratica a Python approfondisce le varie funzionalità del linguaggio. Il lettore
può mettere in pratica le nuove conoscenze immediatamente, seguendo passo passo la creazione di dieci
interessanti progetti, da un bulletin board basato sul web a una applicazione con interfaccia grafica per la
condivisione di file.
Python Essential Reference, Second Edition ((Sams, 2001))
Un libro di riferimento che contiene un’ottima presentazione di tutte le librerie chiave e di tutte le funzioni.
È una scelta eccellente per un programmatore esperto.

Questo libro usa le seguenti convenzioni:

Versione italiana
Attenzione: Nella versione in italiano si sono usate forme leggermente diverse. In partico-
lare è stata usata una ulteriore modalità di evidenziazione del testo la cui renderizzazione
dipende dal CSS. Risultano quindi in grassetto corsivo i nomi estesi delle risorse o altre
parole importanti.

• Italico: I termini nuovi sono italicizzati. (L’appendice C contiene un glossario completo dove sono definiti
tutti gli acronimi). Inoltre, sono italicizzati anche i link che appaiono nell’interfaccia utente.
• Grassetto: Se ci sono delle istruzioni nel testo che includono qualcosa che si deve inserire con la tastiera,
queste parole sono in grassetto.
• Font fisso: Un font a spaziatura fissa indica nomi di file, indirizzi di cartelle (path), codice,
variabili e Uniform Resource Locators (URL).

Questo libro contiene molte immagini (screen shot) di Zope, Python e Plone. Siccome Plone è un prodotto in
rapidissima evoluzione questi screen shot possono variare leggermente dalla versione del software che si sta
usando; sono modifiche di poca importanza e non interferiscono con la comprensibilità del sistema.
Per questo libro sono state usate le seguenti versioni del software ma sebbene scritto con queste in mente, tutto il
software dovrebbe funzionare su queste e sulle successive versioni per un po’ di tempo a venire.
La più recente versione di Plone, al momento della scrittura di questo libro, è la Plone 2.0. È la seconda versione
(major release) del software ed include molte nuove funzionalità rispetto alla versione 1.0, incluso la gestione
dei gruppi di utenti, una nuova interfaccia ed una migliore distribuzione di Zope. È decisamente consigliato di
iniziare i nuovi progetti con la 2.0 piuttosto che usare le precedenti versioni.
La versione 2.0 di Plone dipende dai seguenti software: Zope 2.7, CMF 1.4.2, e Python 2.3.3. Tutti gli esempi di
codice di questo libro sono stati studiati per non dipendere specificamente da queste versioni o da un particolare
sistema operativo. Comunque ci possono essere delle situazioni in cui non è vero, ci scusiamo per eventuali
inconvenienti.
In origine è stato un gruppo di utenti di Plone, smaliziati produttori di documentazione di qualità, a lanciare
l’idea di questo libro. La prima versione è stata rilasciata sul sito di Plone come progetto di documentazione
open source. Tutti i contenuti aggiunti al sito Plone seguono la licenza di libera pubblicazione.
La crescita di interesse attorno a Plone ha creato le condizioni per un libro commerciale e quindi nell’estate del
2003 abbiamo iniziato questo libro. Sono stati riutilizzati alcuni materiali del vecchio libro con il permesso dei
proprietari originali. Con le modifiche a Plone 2 sono stati inseriti molti nuovi materiali. Questo libro è ora pub-
blicato con la Creative Commons license che consente il suo riuso. Non è comunque consentito il riuso commer-
ciale. Per maggiori informazioni vedere la licenza online all’indirizzo http://creativecommons.org/licenses/by-
nc-sa/1.0/.
Capitolo 2

Capitolo 2: Installazione di Plone

17
18 CAPITOLO 2. CAPITOLO 2: INSTALLAZIONE DI PLONE
Indice

Questo capitolo spiega come installare Plone su diverse piattaforme e ad impostare le opzioni delle confi-
gurazioni di base di Plone. Se si vuol provare subito Plone la cosa migliore è andare al sito dimostrativo
http://demo.plone.org; lì è possibile aggiungere e modificare contenuti immediatamente, senza installare nulla.
Differentemente degli altri capitoli, la lettura di questo dall’inizio alla fine potrebbe non avere senso. Abbiamo
suddiviso questo capitolo per sistemi operativi in modo da poter leggere solamente le sezioni che servono per
installare Plone. Plone è installabile su qualunque piattaforma che supporti Zope: Windows, Mac OS X, Linux,
la maggior parte della piattaforme Unix e Solaris.
Per un server Plone, un computer molto potente migliorerà ovviamente le sue prestazioni. Plone è un sistema
complicato che necessita potenza di calcolo e memoria. In generale se si deve fornire un sito molto grande, è
raccomandabile non andare in produzione con una macchina più lenta di 2 GHz e con meno di 1 GB di Random
Access Memory (RAM). Tuttavia, per siti più modesti si lavora bene anche con configurazioni più lente, come 500
MHz e 64 MB di memoria. Per ulteriori informazioni riguardo le prestazioni, la gestione della cache (caching),
e la velocizzazione di Plone si veda il capitolo 14. Per un’installazione base di Plone servono almeno 50 MB di
spazio libero nel disco rigido. Se si hanno già installazioni di Zope o Python, allora ne servirà molto meno; ne
serviranno circa 2 MB. Si deve tener conto anche del database ad oggetti di Plone che può crescere occupando
qualsiasi spazio in quanto questo dipende dalla quantità di dati che si memorizzano.
Per usare Plone è necessario un browser che possa accedere al server. Se gli utenti vogliono registrarsi ad un
sito devono avere abilitato i cookies. L’installazione di Javascript non è necessaria ma migliora l’esperienza
dell’utente. Visto il grande utilizzo in Plone del Cascading Style Sheets (CSS), i browser moderni possono
vedere la vera interfaccia di Plone in modo più ricco ed accattivante; dovrebbe comunque funzionare in qualsiasi
browser razionale.
Browser raccomandati:

• Microsoft Internet Explorer 5.5 e successivi


• Netscape 7.0 e successivi
• Mozilla 1.0 e successivi
• Opera 7.0 e successivi
• Konqueror 3.0 e successivi

• Safari 1.0 e successivi

Plone funziona perfettamente anche nei seguenti browser ma potrebbe differire dall’originale:

• Netscape 4.*x*
• Microsoft Internet Explorer 5.0

19
20 INDICE

• Microsoft Internet Explorer 4.0

• Konqueror 2.*x*
• Lynx (text-based)
• w3m (text-based)
• AWeb
• Links (text-based, con grafica opzionale)
• Tutti i browsers che utilizzano un set minimo dell’Hypertext Markup Language (HTML) e supportano i
cookies, ad esempio i browsers per la maggior parte dei palmari (mobile / Personal Digital Assistant -
PDA).

2.1 Installazione di Plone su Windows


Senza dubbio la maniera più semplice di installare Plone è quella di usare l’Installer Plone per Windows, che ne
automatizza l’installazione in ambiente Windows. L’installazione include altri pacchetti ed opzioni, un database
con accesso via Hypertext Transfer Protocol (HTTP), il setup dei servizi ed i pacchetti di Python per Windows.
L’installer è scaricabile da http://www.plone.org/download.

2.1.1 Utilizzo dell’Installer


Il programma di installazione è stato controllato su Windows 9*x*, ME, NT 3.51+, 2000 e su XP ma può lavorare
anche sulle altre versioni di Windows. Si raccomanda di avere diritti di amministratore nel computer nel quale si
vuole fare l’installazione in quanto l’installer cercherà di avviare un servizio e modificare delle impostazioni nel
file di registro di Windows. Se Zope o Python sono già installati si può installare il sorgente separatamente per
risparmiare spazio sul disco.
Prima di installare Plone, bisogna porre attenzione agli eventuali server web attivi. Per esempio le ultime versioni
di Windows installano e lanciano automaticamente i servizi Microsoft Internet Information Services (IIS), che
ascoltano sulla porta 80. L’Installer avvia Plone sulle porte 80 e 8080. Per verificare se qualcosa sta già
utilizzando la porta 80, il modo più rapido è aprire il browser su http://127.0.0.1/ e vedere se trova una pagina.
Si può sia disabilitare il server web che cambiare le porte di Plone; si veda Configurazione del server web più
avanti in questo capitolo. Se si vuole eseguire Plone dietro IIS o far funzionare sia Plone che IIS nello stesso
server nello stesso momento, il Capitolo 14 può fornire ulteriori informazioni. Al momento, comunque, la via
più facile è semplicemente disabilitare il server web.
Una volta scaricato l’installer, lanciamolo con un doppio click (vedi figura 2-1).

L’installatore presenta i soliti passaggi necessari all’installazione di un software; fare click su Next per continuare
o su Cancel per uscire dall’installazione. L’installer di Plone consente di scegliere dove installare il software; la
cartella di default è c:\Program Files\Plone 2 (vedere Figura 2-2).

Quando si arriva alla schermata relativa alla password, come mostra la figura 2-3, si deve inserire uno username
ed una password. Ciò serve per creare un utente e per creare il sito Plone con quell’user name. Di solito si crea
un utente chiamato admin o qualcosa del genere con questo ruolo. In seguito saranno necessari questo username
e la password, fare in modo di ricordarli; tuttavia se si perde questa password, si può inserirne una nuova in
seguito.
2.1. INSTALLAZIONE DI PLONE SU WINDOWS 21

Figura 2.1: Figura 2-1. La partenza dell’installatore di Plone

Figura 2.2: Figura 2-2. Selezione della directory


22 INDICE

Figura 2.3: Figura 2-3. Nome utente e password

L’installazione richiede circa cinque minuti ma dipende dalla velocità del computer. L’installazione porta a termi-
ne vari obiettivi come la compilazione di tutti i files Python e l’installazione del database. Quando l’installazione
è completata, sullo schermo appare un messaggio di avviso (vedere Figura 2-4).

Per lanciare Plone accedere al controller di Plone tramite Avvio - Programmi - Plone. Il controller di Plone
è un’applicazione per avviare o fermare Plone. Si apre alla pagina Status, che consente di avviare e fermare
facilmente la sessione Plone (vedere Figura 2-5).

Come mostrato nella Figura 2-5, lo schermo mostra lo stato di Plone. Plone non si avvia automaticamente; si
deve fare click su Start per farlo partire. Una volta premutolo si dovrà aspettare un minuto finché la procedura di
startup sia completa (vedere Figura 2-6).

Quando Plone è avviato, è possibile accedere al sito cliccando il pulsante View Plone. Si avvia un browser che
accede al sito Plone; si potrà vedere la pagina di benvenuto di Plone. Notare come l’indirizzo del browser sia
http://localhost/; questo è l’indirizzo per accedere al proprio sito Plone. Cliccando il pulsante Zope Manage-
ment Interface si avvia un browser che accede all’interfaccia di gestione; questa volta l’indirizzo del browser è
http://localhost::8080/manage, che consente l’accesso al server sottostante l’applicazione. Quando si preme il
pulsante Manage e si accede a Plone viene chiesto l’username e la password. Qui bisogna inserire l’username e
la password che si è inserita con l’Installer.
Il controller sa se si è installato Plone come servizio o meno. Se Plone è stato installato come servizio di
Windows, è possibile avviare e fermare Plone utilizzando i normali comandi e maschere di gestione dei servizi.
Se invece Plone non è stato installato come servizio Windows, si vedrà apparire una piccola icona nella barra
delle applicazioni. A questo punto se si vogliono modificare dei contenuti si prosegua al ‘capitolo 3‘_.

2.1.2 Configurare il server su Windows


La configurazione di Plone è in un file di testo e si può facilmente modificare per personalizzare la propria istanza.
È possibile quindi cambiare le porte su cui Plone è in ascolto, i file usati per i log e molte altre opzioni. Le scelte
per alcune funzionalità sono disponibili nell’interfaccia grafica (GUI) del controller. Se si desidera modificare le
2.1. INSTALLAZIONE DI PLONE SU WINDOWS 23

Figura 2.4: Figura 2-4. Schermata finale

Figura 2.5: Figura 2-5. Plone non è in funzione


24 INDICE

Figura 2.6: Figura 2-6. Ora Plone è in funzione

altre impostazioni fare riferimento all’‘Appendice A‘_ dove c’è la lista completa delle opzioni di configurazione.
Per accedere al controller selezionare Avvio - Programmi - Plone - Plone, che avvia il controller.
Come detto in precedenza, la prima pagina che viene mostrata è la pagina di stato (Status page) che consente di
avviare o fermare Plone. Sulla sinistra del controller sono accessibili altre schermate di cui parleremo più avanti.

Modifica delle porte in Windows

La scelta delle porte, come mostrato dalla Figura 2-7, consente di specificare le porte su cui Plone si mette in
ascolto delle connessioni in arrivo con protocolli HTTP, File Transfert Protocol (FTP), Web-based Distributed
Authoring and Versioning (WebDAV).

Come già detto, quando si installa Plone bisogna assicurarsi che non vi siano altri server in ascolto sulla stessa
porta (del server Plone): IILS, Apache e PWS (Personal Web Server) potrebbero essere in ascolto sulla 80. Al
momento in cui scriviamo, in Plone vengono abilitate solo le porte Plone e Zope Management; per intervenire
sulla loro configurazione è necessario modificare un file di testo. Quelle che seguono sono le descrizioni dei
quattro campi della pagina Porte:

Plone (HTTP)
Questo campo specifica tramite quale porta l’utente accede normalmente a Plone. L’impostazione di de-
fault è la porta 80 che è lo standard per un server web. Sebbene non sia necessaria, senza questa porta non
è possibile accedere a Plone tramite un browser web. Se questa porta è abilitata e Plone sta funzionando, è
abilitato anche il pulsante View nella maschera di stato.

Zope Management (HTTP)


Questo campo specifica a quale porta è possibile accedere a Plone come manager. Il valore di default è la
porta 8080. Questa porta consente l’accesso alla Zope Management Interface (ZMI) dalla cartella radice
2.1. INSTALLAZIONE DI PLONE SU WINDOWS 25

Figura 2.7: Figura 2-7. La schermata Ports mostra le porte utilizzate da Plone

(root) di Zope. Ciò è possibile comunque anche dalla porta HTTP ma è comodo e conveniente avere una
porta distinta. Se questa porta è abilitata e Plone sta funzionando, è abilitato anche il pulsante Manage
Plone nella maschera di stato.
FTP Access Questo campo specifica a quale porta è possibile accedere a Plone con il protocollo FTP. Il valore
di default è blank che significa che questo servizio è disabilitato; se si desidera abilitarlo la porta usata
abitualmente è la 21. È utile usare l’FTP soprattutto per trasferire da/a Plone file di grandi dimensioni.
WebDAV Source Questo campo specifica a quale porta è possibile accedere a Plone via WebDAV. Il valore di
default è blank che significa che questo servizio è disabilitato; se si desidera abilitarlo la porta usata
abitualmente è la 8081. (WebDAV è un protocollo che consente l’authoring dei contenuti di Plone da
remoto. Tramite WebDAV è possibile, per esempio, realizzare la mappatura del server Plone come una
lettera di un disco Windows.)

Utilizzo della schermata Emergency User

Il ‘capitolo 9‘_ spiega l’uso della pagina di emergenza (Emergency User page) ma, detto in breve, essa
consente l’accesso di emergenza al sistema se si sono dimenticati l’username e la password.

Lanciare Plone in modalità di debug

Fino a questo momento abbiamo lanciato e fermato Plone in modalità production. È il modo più rapido e quello
raccomandato per l’uso normale di Plone. Per sviluppare add-ons o per risolvere i problemi del debugging
è necessario lanciarlo in debug mode. Questo è la modalità consigliata per il lancio di Plone quando si svilup-
pano nuovi prodotti e skin, come faremo nei prossimi capitoli. Questa non è la modalità predefinita perché, come
si potrà notare, Plone è fino a dieci volte più lento del normale.
Per avviare Plone in modalità debug selezionare Avvio - Programmi - Plone - Plone (Debug Mode) ed apparirà
una finestra con il prompt: tutti i log con le informazioni saranno visualizzati lì (vedere Figura 2-8).
26 INDICE

Figura 2.8: Figura 2-8. Lancio di Plone dalla linea di comando

Per verificare se Plone è funzionante basta avviare un browser e provare l’indirizzo http://localhost/; se Plone è
installato correttamente si vedrà la schermata di benvenuto di Plone.

2.2 Installazione di Plone su Mac OS X, Unix e Linux


I programmi di installazione per Mac OS X, Unix e Linux sono diversi tra di loro, ma la configurazione è
simile. Esistono pacchetti specifici per i differenti sistemi operativi inclusi Mac OS X, Debian, Gentoo, FreeBSD,
OpenBSD, RPM Package Managers (RPMs) per Red Hat, SuSE, e Mandrake. Nelle successive sezioni trattiamo
le più diffuse: Mac OS X, Red Hat e Debian. Per saperne di più sul proprio sistema si consiglia di consultare le
istruzioni di installazione specifiche del sistema operativo che si ha installato.

2.2.1 Installazione su Mac OS X


L’installer automatizza l’installazione di Plone su Mac OS X ed è stato testato sulla versione 10.2.3 e successive.
È necessario avere accesso come amministratore al computer su cui si vuole installare. È possibile scaricare
l’installer da http://www.plone.org/download. Una volta scaricato l’installer fare doppio click sul file per decom-
primere l’archivio e successivamente fare doppio click sul pacchetto così decompresso per iniziare l’installazione.
Sarà mostrato la schermata mostrata in Figura 2-9.

Inserire la password del proprio account Mac OS X per autorizzare l’installazione: l’account deve avere i privilegi
di amministratore per poterlo fare. Se non si hanno i privilegi di amministratore uscire, rientrare con un account
che li abbia e rilanciare l’installer. Si può eventualmente muovere il pacchetto precedentemente scaricato in
/Users/Shared in modo da renderlo accessibile anche con altri account. Avviata l’installazione si vedrà la
schermata mostrata nella Figura 2-10.

L’installatore presenta i soliti passaggi necessari all’installazione di un software; fare click su Continue per
continuare o su Go Back quando necessario; la maggior parte delle scelte sono auto esplicative. Ma laddove
viene mostrata la scelta del volume dove installare Plone è necessario scegliere la partizione in cui è installato
Mac OS X (vedere Figura 2-11).
2.2. INSTALLAZIONE DI PLONE SU MAC OS X, UNIX E LINUX 27

Figura 2.9: Figura 2-9. Autorizzazione all’installazione usando la propria password Mac OS X
28 INDICE

Figura 2.10: Figura 2-10. Schermata di benvenuto dell’installatore


2.2. INSTALLAZIONE DI PLONE SU MAC OS X, UNIX E LINUX 29

Figura 2.11: Figure 2-11. Selezione del volume di boot


30 INDICE

L’installazione richiede circa cinque minuti ma dipende dalla velocità del computer. Quando l’installazione è ter-
minata, l’impostazione predefinita è che Plone non venga avviato. Il file ReadMe.rtf in /Applications/Plone
contiene molte informazioni sul funzionamento e la gestione della propria installazione Plone, incluso come
avviare Plone. Per esempio lanciando il seguente comando si avvierà Plone:

sudo /Library/StartupItems/Plone/Plone start

Per verificare se Plone è funzionante basta avviare un browser e provare l’indirizzo http://localhost:9090/; se
Plone è installato correttamente si vedrà la schermata di benvenuto di Plone. Nel file ReadMe ci sono l’username
e la password che Plone ha impostato per l’accesso al server.

2.2.2 Installazione utilizzando un RPM


I pacchetti RPM sono disponibili per le distribuzioni Red Hat, Mandrake e SuSE. È possibile scaricare l’ultima
versione da http://www.plone.org/download. L’RPM richiede che Python 2.3 sia già installato. Per sapere quale
versione di Python si ha installato nel proprio pc lanciare il seguente comando in una shell:

$ python -V
Python 2.3.2

In questo esempio c’è installato Python 2.3.2: se non lo si ha il pacchetto RPM per Python è disponibile al sito
web di Python all’indirizzo http://www.python.org. Dopo aver scaricato il file installarlo utilizzando i comandi
standard rpm: l’installazione Plone stampa alcune utili informazioni, per fortuna. Ad esempio:

[root@lappi i386]# rpm -ivh Plone2-2.0.0rh-2.i386.rpm


Preparing... ###########################################
[100%]
Making group plone (not altered if already exists).
Making user plone.
~ 1:Plone2 ###########################################
[100%]
Creating initial ’main’ instance...
Instance created. Listening on 127.0.0.1:8080, initial user: ’plone’
with password: ’plone’.
Setup of initial database in ’main’ instance...
/usr/lib/plone2/lib/python/AccessControl/Owned.py:79:
DeprecationWarning: Owned.getOwner(1) is deprecated; please use
getOwnerTuple() instead.
~ DeprecationWarning)
Created initial database content.
look at /etc/plone2/main/zope.conf.
Run then "/etc/rc.d/init.d/plone2 start" to start Plone2.
you may create new Plone instances with mkploneinstance.

Come per il precedente output, per avviare Plone lanciare il seguente:

/etc/rc.d/init.d/plone2 start

Per verificare se Plone è funzionante usare un browser e provare l’indirizzo http://localhost:8080/; se Plone è
installato correttamente si vedrà la schermata di benvenuto di Plone. L’account impostato ha come username
plone e la password plone.
2.3. INSTALLAZIONE DAI SORGENTI 31

2.2.3 Installazione su Debian Linux


Plone è un pacchetto standard in Debian ed è rilasciato con il procedimanto di rilascio standard ed è quindi
scaricabile sia nella versione stable che unstable* in base a come è configurata la propria installazione Debian.
Per installare Plone usare semplicemente il sistema Debian apt per ottenere il pacchetto. Segue un esempio di
installazione:

agmweb:/home/andy# apt-get install plone


Reading Package Lists... Done
Building Dependency Tree... Done
The following extra packages will be installed:
zope zope-cmf zope-cmfcalendar zope-cmfcore zope-cmfdefault
zope-cmfplone zope-cmftopic zope-cmfworkflow
zope-formulator zopectl
Suggested packages:
zope-cmfwiki python-unit zope-devguide zope-book
Recommended packages:
zope-cmfforum zope-localizer
The following NEW packages will be installed:
plone zope zope-cmf zope-cmfcalendar zope-cmfcore zope-cmfdefault
zope-cmfplone zope-cmftopic zope-cmfworkflow
zope-formulator zopectl
0 upgraded, 11 newly installed, 0 to remove and 49 not upgraded.
Need to get 4743kB of archives.
After unpacking 24.9MB of additional disk space will be used.
Do you want to continue? [Y/n]

Premere Y per continuare ed installare i pacchetti richiesti. Per l’avvio e lo stop di Zope viene creato uno script
nella directory init.d denominato zope. Per avviare Zope lanciare il seguente:

/etc/init.d/zope start

L’installer Debian avvia Zope sulla porta non-standard 9673. Siccome l’installer Debian è un po’ inusuale si rac-
comanda la lettura della documentazione del pacchetto in /usr/share/doc/zope ed in /usr/share/doc/zope-cmfplone.

2.3 Installazione dai sorgenti


In alternativa ai programmi di installazione o ai pacchetti, puoi effettuare l’installazione partendo dai sorgenti. Per
chi ha famigliarità con l’installazione da sorgente è abbastanza semplice ma richiede la conoscenza di strumenti
di base come tar. Le sezioni che seguono mostrano come installare su linux.
Si assume qui la famigliarità con operazioni basilari come l’untarring di file e lo spostamento di file. Ciò è
richiesto per ottenere una installazione di Zope funzionante.

Nota
Per installare Zope vedere le istruzioni di installazione che sono disponibi-
li nel file doc/INSTALL.txt scaricato con Zope. Per ulteriori informazioni vedere
http://docit.bice.dyndns.org/static/Zope/ZopeBook/cap_Installazione.html.

Per installare Plone fare i seguenti passaggi:


32 INDICE

1. Scaricare Plone 2 da http://www.plone.org/download, e selezionare il file col sorgente (tarball).

2. Decomprimere l’archivio con il comando:


tar xzf CMFPlone2.0.tar.gz
3. Verificare la creazione della directory denominata CMFPlone-xxx, dove xxx è la versione (per
esempio, CMFPlone-2.0).
4. Spostare il contenuto di quella cartella nella directory Products dov’è installato Zope. Per esem-
pio se la directory Products di Zope è in var/zope spostare il tutto con il comando:
mv CMFPlone2.0/* /var/zope/Products

Dopo aver completato l’installazione riavviare Zope. Una volta riavviato, accedere a Zope aprendo un browser
all’indirizzo http://localhost:8080/manage. È necessario fornire un username ed una password per questo (per
esempio l’username e la password data durante l’installazione di Zope).
Nell’angolo a destra in alto dell’interfaccia ZMI c’è un elenco a cascata dei prodotti che è possibile aggiungere.
Assicurarsi che una delle le opzioni sia Plone Site. Se è così l’installazione è completa (vedere la Figura
2-12).

Figura 2.12: Figura 2-12. Plone Site nella lista di selezione

2.3.1 Installazione dal CVS


L’accesso tramite Concurrent Versioning System (CVS) è raccomandato solo agli utenti esperti e agli sviluppato-
ri. È possibile ottenere informazioni aggiornate sull’accesso al CVS all’indirizzo http://ww.plone.org/development/cvs.
Attualmente il comando di estrazione dal CVS è il seguente:

cvs -d:pserver:anonymous@cvs.sf.net:/cvsroot/plone login


cvs -d:pserver:anonymous@cvs.sf.net:/cvsroot/plone co CMFPlone
2.4. CONFIGURAZIONE DEL SERVER WEB 33

Plone 2 ha un intero stuolo di dipendenze (come DCWorkflow, Formulator, Group User Folder ed altre) che non
si trovano nel CVS di Plone e che implicano quindi la loro ricerca da parte dell’utente. All’avvio Plone stampa
tutti gli eventuali errori per i pacchetti non trovati. Per esempio:

2003-11-21T12:23:11 ERROR(200) Plone Dependency CMFActionIcons not


found. Please download it from http://cvs.zope.org/Products/

2.3.2 Aggiungere un sito Plone


Una volta installato Plone dai sorgenti è necessario creare una istanza di Plone. Per farlo è necessario loggarsi
nell’interfaccia ZMI ed aggiungere un sito Plone. Vi si accede andando all’indirizzo (URL) dell’interfaccia
di gestione che è normalmente http://localhost:8080/manage (questa porta può cambiare in base alla propria
installazione). È necessario fornire un username ed una password per accedere alla ZMI: questa password è
creata durante l’installazione.

Nota
Non fatevi prendere dal panico se avete dimenticato la password di Plone creata al mo-
mento dell’installazione. È possibile crearne una nuova; vedere il ‘capitolo 9‘_ per ulteriori
informazioni.

Aggiungere tutti gli oggetti utilizzando l’elenco a cascata nell’angolo destro in alto come mostrato dalla Figura
2-12. Scorrere l’elenco fino a trovare Plone Site e cliccare Add.
Dopo aver selezionato l’opzione Plone Site una maschera richiede l’inserimento di ulteriori informazioni (vedere
Figura 2-13):

Id È il nome che identifica il sito Plone (inserire, per esempio, Plone o Sito).
Title È il titolo del sito Plone (inserire, per esempio, Il Mio Portale).
Membership source Per il momento lasciare questa opzione come default, Create a New User Folder in the
Portal. Questo consente di avere l’autenticazione dell’utente altrove rispetto al portale. (Vedere il ‘capitolo
9‘_ per più informazioni).
Description È la descrizione del portale che gli utenti vedranno nelle e-mail (inserire, per esempio,
Un sito sulla nuova tecnologia). Non ci si preoccupi per questo, è sempre possibile modificarla
successivamente nelle proprietà del portale.

Dopo aver cliccato su Add Plone Site viene creato un sito Plone. Questo può impiegare un minuto o due sulle
macchine più lente per il gran numero di processi che si attivano. Si viene quindi redirezionati alla pagina di
benvenuto di Plone.

2.4 Configurazione del Server Web


Una volta installato Plone si potrebbe desiderare di configurare il sito Plone in modo che giri su una porta
differente, abbia connessioni FTP, salvi i log in file differenti e così via. Questa sezione tratta di queste impo-
stazioni basilari. Si noti che non stiamo configurando il sito Plone ma stiamo modificando la configurazione del
sottostante server web.

Nota
Se si è installato su Windows con l’apposito installer, la maggior parte di questa configurazio-
ne è possibile tramite un programma con una comoda interfaccia utente; vedere Configurare
il server su Windows in questo capitolo.
34 INDICE

Figura 2.13: Figura 2-13. Aggiunta di un sito Plone


2.4. CONFIGURAZIONE DEL SERVER WEB 35

Zope 2.7 crea un file di configurazione dentro ciascuna istanza installata. Tutte le configurazioni per il server sono
in quel file. Un elenco completo delle opzioni di configurazione è disponibile nell’‘Appendice A‘_. Per trovare
il file di configurazione cercare un file di nome zope.conf nella directory etc della propria installazione
Plone. Alcuni installer (Windows e Mac OS X ad esempio) creano un secondo file di nome plone.conf che
contiene specifiche opzioni di configurazione per Plone. Se la propria installazione contiene un file di nome
plone.conf si usi quel file per effettuare delle modifiche; sarà incluso nel file di configurazione principale.

Nota
Se si è installato in Mac OS X o usando l’installer per Windows si troverà un file extra
(plone.conf) che contiene le definizioni del port usate nel file principale di configurazione
di Zope.

Il file di configurazione è estremamente verboso e contiene un gran numero di utili commenti ed esempi. Se si è
famigliari con i file di configurazione in Unix, come Apache, si avrà famigliarità anche con il file di configura-
zione di Zope. Per modificare la configurazione di Zope aprire il file con un editor per testo e modificare le linee
come richiesto; dopo aver modificato la configurazione è necessario riavviare Zope.
È possibile avviare Plone 2.0 con una versione Zope precedente di alla 2.7 ma Zope 2.7 fornisce maggior stabilità
e nuove funzionalità, inclusa una facile configurazione. Se si sta usando una versione precedente alla 2.7 si dovrà
leggere la documentazione su come modificare la configurazione.

2.4.1 Modifica delle porte


Per cambiare una porta aggiungere la linea dell’indirizzo per quella porta. Per esempio, per avviare Plone sulla
porta 80 piuttosto che su quella di default modificare le successive linee nel file zope.conf:

<http-server>
# valid keys are "address" and "force-connection-close"
address 8080
# force-connection-close on
</http-server>

nel seguente modo:

<http-server>
# valid keys are "address" and "force-connection-close"
address 80
# force-connection-close on
</http-server>

Se si è usato l’installer per Windows o per Mac OS X si troverà la definizione di queste porte nel file plone.conf.
Questi valori vengono successivamente importati nel file di configurazione principale. Perciò per cambiare porta
su un Mac si modificherà il file plone.conf da così:

## PLONE_WEBSERVER_PORT
## --------------------
## This is the port you will access your Plone site from. Set this to a port
## number above 1024 not used for any other server on your computer.
%define PLONE_WEBSERVER_PORT 8080

a così:

%define PLONE_WEBSERVER_PORT 80
36 INDICE

2.4.2 Utilizzo della modalità di debug


Per default Zope 2.7 viene lanciato in modalità di debug. Si noti che Plone gira decisamente più lento in modalità
debug, approssimativamente 10-20 volte più lento. Per eliminare questo comportamento aggiungere questa linea
al file di configurazione:

debug-mode off

Per dare una sensazione migliore agli utenti Windows (la modalità debug rallenta Plone su Windows anche più
che in Linux) la modalità debug è già disabilitata per default. Se si ha un sito Plone avviato e si vuol saper
se è attiva la modalità debug si vada nella ZMI, in portal_migration e controllare le variabili lì elencate;
dovrebbero dire se la modalità debug è abilitata.

2.4.3 Utilizzo dei file di log


Di default ci sono due file di log in Plone: un log degli accessi che consente di produrre statistiche del sito e un
log degli eventi che contiene informazioni di debug dei prodotti Plone. Il log degli eventi è il posto deve trovare
errori e messaggi in Plone. La configurazione di default è simile alla seguente:

<eventlog>
level all
<logfile>
path $INSTANCE/log/event.log
level INFO
</logfile>
</eventlog>

<logger access>
level WARN
<logfile>
path $INSTANCE/log/Z2.log
format %(message)s
</logfile>
</logger>

Qui è dove si può cambiare il path definendo un nuovo file. I valori che vengono scritti dipendono dal livello
inviato con il messaggio: messaggi di maggiore gravità vengono inviati con livelli maggiori. Per default vengono
inviati al log solo informazioni ed il messaggio precedente, ma il valore può essere uno dei seguenti: CRITICAL,
ERROR, WARN, INFO, DEBUG e ALL. Se si vogliono registrare solo gli errori si dovrà modificare level INFO a
level ERROR.
Capitolo 3

Capitolo 3: Aggiungere e modificare i


contenuti

37
38 CAPITOLO 3. CAPITOLO 3: AGGIUNGERE E MODIFICARE I CONTENUTI
Indice

Note alla traduzione del capitolo


member: collaboratore
form: modulo
join: iscriversi
log in: registrarsi
register: conferma l’iscrizione
review (state): in revisione (stato)
submit: proponi
discussion: conferenza, discussione

Aggiungere e modificare i contenuti è una semplificazione della potenza pura che Plone è in grado di sviluppare.
Creare pagine web ricche di contenuti e di funzionalità con Plone è un lampo. Questo capitolo mostra come
lavorare direttamente con Plone avendolo installato localmente . Anche se non si ha Plone installato, nessuna
preoccupazione, si può provare Plone online andando a http://demo.plone.org.
Prima di cambiare o modificare un sito Plone è necessario iscriversi. Se si ha Plone installato si dovrebbero
avere il nome utente e la password inseriti durante l’installazione. Questo utente ha il ruolo di amministratore
che gli consente l’accesso e la modifica di qualsiasi contenuto. La maggior parte degli utenti di un sito Plone
accedono al sito e si iscrivono tramite la procedura di registrazione descritta nella sezione Registrazione utente.
Si può ovviamente vedere un sito Plone anche senza registrarsi ma non sarà possibile aggiungere e modificarne i
contenuti.
In questo capitolo faremo i passi che fa l’utente per creare contenuti in un sito Plone. Prima, come entrare nel sito
e loggarsi, e, dopo averlo fatto, come creare e poi modificare un documento. Per finire vedremo come è possibile
cercare o pubblicare questo contenuto. Detto in breve, questo capitolo tratta di come si usa Plone.

3.1 Registrazione utente


Quando ci si iscrive ad un sito Plone, viene generato un account sul server. Tale account dà il diritto di aggiun-
gere contenuti come immagini, documenti e così via. Per iscriversi al sito premere sul collegamento iscriviti
posizionato nell’angolo in alto a destra (vedere Figura 3-1).

Questo porta al Modulo di iscrizione, che è necessario compilare (vedere Figura 3-2). Siccome questa è la prima
maschera che si incontra in Plone prendiamo nota che:

39
40 INDICE

Figura 3.1: Figura 3-1. Click su iscriviti in alto a destra sulla pagina

• Alcuni campi sono obbligatori; un piccolo quadratino rosso vicino al testo indica i campi richiesti.
• Per la maggior parte dei campi sono presenti, subito sotto il nome del campo, dei consigli su cosa si deve
immettere .

Nota
Siccome molte pagine Plone sono veramente grandi, le immagini di questo libro sono state
ritagliate per mostrare solo le parti chiave (in questo caso il modulo) e non il logo Plone o il
piè pagina. Questi elementi ci sono, ma sono superflui.

Per completare il modulo, inserire i campi che sono ragionevolmente ovvii. I valori dei campi sono questi:

Nome e Cognome Inserire il proprio nome completo. È un campo opzionale.

Nome utente Inserire il nome utente che si desidera usare. Molti scelgono un valore alfanumerico senza spazi,
come bob o gianna97. Questo nome utente viene usato in tutto il sito per fare riferimento a noi. È un
campo obbligatorio.
E-mail Qui è richiesto un indirizzo e-mail valido. Consente all’amministratore del sito di contattarci e di man-
darci una password. È possibile cambiare successivamente questo indirizzo e-mail modificando le proprie
preferenze di collaboratore. È un campo obbligatorio.
Password e Conferma Password È la password che intendiamo usare; dev’essere più lunga di quattro caratteri
e può contenere lettere, numeri ed il carattere di sottolineatura (_). Le password sono case sensitive (in
altre parole UnaPassword non è la stessa cosa di unapassword). È un campo obbligatorio.
Invia una e-mail con la password Spuntare questo campo se si desidera che la password sia spedita via e-mail
all’indirizzo fornito. È un campo opzionale.

Completato il modulo clicchiamo su conferma l’iscrizione per inviare le nostre informazioni. Se abbiamo com-
messo qualche errore, ci verrà mostrato un messaggio di errore in cima alla pagina ed il campo con l’errore sarà
evidenziato. La Figure 3-3 mostra l’invio della password senza aver inserito alcun valore nel campo Conferma
password. Nuovamente notiamo il modo standard dei moduli Plone di mostrarci gli errori.

Se abbiamo completato correttamente il modulo ci verrà subito data la possibilità di accedere registrandoci.
Clicchiamo su accedi per entrare nel sito. Vedremo quanto mostra la Figura 3-4.

Se abbiamo già un nome utente ed una password o stiamo ritornando in un sito dove ci siamo precedentemente
iscritti, possiamo inserire il nome e la password nel box della colonna di sinistra del sito e cliccare su accedi.
3.1. REGISTRAZIONE UTENTE 41

Figura 3.2: Figura 3-2. La pagina di iscrizione


42 INDICE
3.1. REGISTRAZIONE UTENTE 43

Figura 3.4: Figura 3-4. Dopo la registrazione


44 INDICE

3.2 Abilitare i Cookies


Per registrarsi in un sito Plone dobbiamo avere i cookie abilitati. Se si prova ad accedere ad un sito Plone con
i cookie disabilitati si riceve un amichevole messaggio che ci dice che i cookie devono essere abilitati con un
collegamento ad ulteriori informazioni. Per abilitare i cookie, facciamo i prossimi passi, in base a che browser
abbiamo.

Internet Explorer 6.x 1. Select Tools > Internet Options.


2. Click the Privacy tab at the top of the screen.
3. Move the slider to Medium, and click OK.
Internet Explorer 5.x 1. Select Tools > Internet Options.
2. Click the Security tab at the top of the screen.
3. Click Custom Level, and scroll down to the Cookies section.
4. Set Allow Per-Session Cookies to Enable, and click OK.
Internet Explorer 4.x 1. Select View > Internet Options.
2. Click the Security tab at the top of the screen.
3. Click Custom Level, and scroll down to the Cookies section.
4. Select Always Accept Cookies or Prompt Before Accepting Cookies, and click OK.
Mozilla 1.x 1. Select Edit > Preferences.
2. Find Privacy & Security in the menu on the left. If there’s a plus sign (+) to the left of Privacy
& Security, click it.
3. Select Cookies under Advanced.
4. Select Enable Cookies for the Originating Web Site Only or Enable All Cookies, and click OK.
Opera 1. Press F12.
2. Click Enable Cookies.
Netscape Navigator 6.x 1. Select Edit > Preferences.
2. Find Privacy & Security in the menu on the left. If there’s a triangle pointing to the right next
to Privacy & Security, click it.
3. Select Cookies under Privacy & Security.
4. Select Enable Cookies for the Originating Web Site Only or Enable All Cookies, and click OK.

Se ad un certo punto dimentichiamo la password possiamo farcela spedire via e-mail all’indirizzo fornito quando
ci siamo iscritti al sito Plone. Per farci spedire la password clicchiamo sul collegamento Hai dimenticato la tua
password? posizionato nella colonna sinistra del sito. Questo tira su il modulo Ho dimenticato la password come
mostra la Figura 3-5; inseriamo il nome utente per il nostro login e la password ci verrà inviata.

Sfortunatamente se non si ha più accesso a quell’account di posta o non si riesce a ricordare il nome utente,
si dovrà contattare l’amministratore del sito. Usando le tecniche descritte nel ‘Capitolo 9‘_ l’amministrazione
può cambiare l’indirizzo e trovare il nostro account utente. Una volta registrati nel sito possiamo vedere il
collegamento esci nell’angolo in alto a destra. Quando abbiamo finito di lavorare è buona abitudine uscire
dal sito (log out) specialmente se stiamo accedendovi da un computer che può essere facilmente usato da altre
persone.
3.2. ABILITARE I COOKIES 45

Figura 3.5: Figura 3-5. Richiedere una password dimenticata


46 INDICE

3.3 Impostare la cartella personale e le preferenze


Dopo essersi registrati, la barra dei collaboratori (member bar), nell’angolo destro in alto, cambia per mostrare
le opzioni disponibili quali collaboratori del sito (vedere la Figura 3-6).

Figura 3.6: Figura 3-6. Le impostazioni personali nell’angolo in alto a destra sono cambiate

Una di queste opzioni è che ciascun collaboratore ha una sua cartella creata quando si è registrato al sito. Questa
cartella ha impostata una particolare politica della sicurezza tale che solo quel collaboratore (e gli amministratori)
possono aggiungere e modificare il contenuto di quella cartella. Per accedera alla propria cartella personale
clicchiamo sul collegamento cartella personale nella barra personale in alto a destra nel sito. Sempre lì a destra
in alto si può vedere anche un collegamento alle preferenze personali che, cliccato, offre un elenco di opzioni per
la personalizzazione. Per il momento vediamo due opzioni; come cambiare la nostra password e come andare
alle preferenze personali e cambiare le preferenze chiave nel nostro sito.
Il modulo per modificare la password consente appunto di cambiare la propria password. Per completarlo dare
la password attuale e poi due volte la nuova password. Dopo averla cambiata, la modifica è immediata. Non si
deve rientrare registrandosi di nuovo, solo ricordiamoci la password per quando ritorneremo.
Il modulo delle preferenze personali consente di impostare numerose preferenze che variano il modo di vedere
il sito. Queste preferenze sono conservate nel server in modo da ricordarle tra le visite al sito (vedere la Figura
3-7).

Le opzioni sono le seguenti:

Nome e Cognome È il nome completo che si è dato quando ci si è iscritti al sito.


E-mail È l’indirizzo e-mail associato alla propria appartenenza ai collaboratori ed è usato frequentemente in un
sito Plone. Importantissimo, se si perde o si dimentica la propria password, questo è l’indirizzo a cui il
sistema la reinvia.
Editor del contenuto Modificando un contenuto complesso, si desidera l’aiuto di un editor. Se l’amministratore
ne ha reso disponibile qualcuno, lo si può scegliere qui. Verrà usato cliccando la scheda modifica di un
oggetto. Se non si è sicuri lasciare l’impostazione predefinita.
Presenza nell’elenco dei collaboratori Questa proprietà specifica se il nostro profilo viene mostrato nella sche-
da dei collaboratori quando qualcuno cerca l’elenco dei collaboratori.
Modifica i nomi brevi Gli oggetti hanno la proprietà ID, o Nome breve, che viene usata per la rappresenta-
zione interna dell’oggetto. Viene mostrata anche negli elementi dell’indirizzo web e nell’URL Uniform
Resource Locator. L’impostazione predefinita mostra qualcosa del tipo News_Item.2002-11-16.4102 ma
la possiamo semplificare molto cambiando il valore del Nome breve, per esempio con notizie_novembre.

Nota
Quando si modifica il valore del nome di un oggetto, qualsiasi cosa faccia riferimento al
vecchio nome non è più valida e darà la pagina di errore elemento non trovato. È meglio
non cambiare il valore del nome dopo aver sottoposto a revisione o collegato da qualche
parte l’oggetto. Per questa ragione consigliamo di impostare questa opzione a no.
3.3. IMPOSTARE LA CARTELLA PERSONALE E LE PREFERENZE 47

Figura 3.7: Figura 3-7. Modifica delle preferenze


48 INDICE

Ritratto Nelle grandi organizzazioni e nei siti comunitari è utile vedere l’immagine degli altri collaboratori. Il
campo Ritratto consente di caricare una propria immagine. L’immagine dev’essere di 75 per 100 pixel.

Fatte le scelte che si desiderano, cliccare il pulsante conferma le modifiche per inviare le modifiche. Ora che
siamo registrati è ora di aggiungere e modificare dei contenuti.

3.4 Aggiungere e modificare documenti


Come detto ora siamo collaboratori del sito ed è stata creata per noi una cartella dove mettere le nostre co-
se. Naturalmente possiamo inserire contenuti ovunque l’amministratore del sito ci abbia autorizzati a farlo,
l’impostazione predefinita è che ciascun collaboratore possa inserire materiali nella propria cartella personale.

Capire dove aggiungere contenuti


Il posto più facile per aggiungere i primi contenuti è la cartella di collaboratore dell’utente
a cui si accede con il collegamento cartella personale. Sebbene questo sia utile, probabil-
mente non è l’approccio migliore per una soluzione a lungo termine. Principalmente crea
URL lughe (per esempio ../Members/andy/Docum....). Comporta inoltre il fatto che il
nostro contenuto non viene accuratamente riflesso nell’albero di navigazione.
Come vedremo in seguito esistono più soluzioni a questo aspetto; la più comune è quella di
creare una cartella e dare a certi utenti il diritto per accedervi. Per esempio questa cartella
potrebbe essere Aiuto o Notizie. La sezione Usare le cartelle, più avanti nel capitolo,
tratta l’aggiunta delle cartelle mentre il ‘Capitolo 9‘_ tratta l’uso delle aree di lavoro dei
gruppi e della sicurezza.

Ciascun tipo di contenuto che si può aggiungere è distinto e lo si può modificare e vedere in modi differenti. Per
questo motivo, Plone referenzia differentemente ciascun tipo di contenuto; per esempio possiamo aggiungere
immagini, collegamenti, documenti e così via. All’inizio Plone fornisce i seguenti tipi di contenuto:

Documento È un elemento che presenta alcune informazioni statiche all’utente. È il tipo di contenuto più
comunemente aggiunto ad un sito e assomiglia già abbastanza a una tipica pagina web.
Notizia È un documento che deve essere mostrato nella scheda notizie (per esempio un rilascio stampa).
Collegamento È un collegamento ad un altro elemento, che può essere interno come esterno in un altro sito
web.
Immagine È una immagine, come lo sono i file .gif o .jpeg.
Evento È un evento che deve accadere, un meeting, una conferenza o altro evento.
Cartella È come una cartella di un disco rigido; è una cartella dove mettere dei materiali per poterli ritrovare
facilmente in seguito.
Tema È un raggruppamento di altri contenuti. È essenzialmente il salvataggio di un criterio di ricerca che si può
riusare in seguito. Solo gli utenti del sito con questo privilegio possono aggiungere i temi.
File È un altro pezzo di contenuto, come un video, una registrazione audio, un file di testo, un foglio di calcolo,
un file compresso o qualsiasi altro vogliamo caricare.

Andiamo in ciascuno di questi elementi usando il tipo documento come esempio mostrando nei dettagli co-
me aggiungere e modificare facilmente e velocemente i documenti. Mostriamo quindi come costruire un sito
dinamico tramite il browser utilizzando questi tipi base di contenuto, evitando qualsiasi programmazione.
3.4. AGGIUNGERE E MODIFICARE DOCUMENTI 49

Ci sono molti modi di aggiungere e modificare i contenuti in un sito Plone oltre che tramite un browser web. È
infatti possibile accedere via FTP (File Transfer Protocol ), via WebDAV (Web-based Distributed Authoring and
Versioning), o via script, tutto è permesso. Tratteremo come impostare queste cose nel Capitolo 10 mentre per
ora avremo un approccio tramite l’interfaccia del browser web. Nel Capitolo 11 e Capitolo 13 di questo manuale,
spiegheremo di come creare nuovi tipi di contenuti personalizzati che si possano cucire attorno a particolari
bisogni in un sito.

3.4.1 Comprendere i Document Content Types


Piuttosto che dettagliare come aggiungere e modificare tutti i differenti tipi di contenuto disponibili, parliamo in
dettaglio dell’aggiunta di un solo tipo, un documento. Dopo everne aggiunti e modificati alcuni, l’approccio
all’aggiunta diventerà naturale e la modifica ad altri contenuti diventerà facile.
Un documento è una pagina di contenuto, normalmente un autocontenitore di pezzi di testo. Sebbene tutti gli
elementi aggiunti a Plone siano accessibili come pagine web, se c’è un contenuto a cui pensare come pagina web
è questo. La pagina home predefinita di un sito Plone, che abbiamo già visto, la ormai famosa pagina Welcome
to Plone, è un esempio di documento (vedere la Figura 3-8).

3.4.2 Aggiungere un documento


Ci sono due modi per aggiungere dei contenuti usando il browser web. Prima però assicuriamoci di essere
registrati perché solo gli utenti registrati possono aggiungere contenuti. Secondariamente selezioniamo il colle-
gamento alla cartella personale della barra di navigazione in alto a destra. Questo ci porta nella nostra cartella
home, un’area sotto il nostro controllo. Se siamo in grado di aggiungere contenuti ad una cartella questa verrà
mostrata con dei bordi verdi (ed, in cima, le schede per la modifica delle varie proprietà n.d.t) (vedere la Figura
3-9).

Se non si vedono i bordi verdi, non si è in grado di aggiungere contenuti; questo bordo contiene le azioni che si
possono effettuare nella attuale posizione. Nella Figura 3-9 possiamo vedere che la pagina mostra il contenuto
della cartella in quanto questa è la scheda evidenziata. Ci sono altre schede lì come visualizza, condivisione
e proprietà con ulteriori opzioni avanzate. Nell’angolo in alto a destra del bordo verde, si può notare i menù
aggiungi un nuovo elemento e stato. Clicchiamo su aggiungi un nuovo elemento per aprire un elenco a cascata
con gli elementi da aggiungere (vedere la Figura 3-10).

Per aggiungere un documento selezioniamo documento. Alternativamente, se guardiamo nel corpo della pagina
(scheda contenuti n.d.t.) possiamo notare un altro box aggiungi un nuovo elemento. Anche lì clicchiamo la
freccetta per aprire l’elenco degli elementi che possono essere aggiunti e scegliamo quello che vogliamo (vedere
la Figura 3-11).

L’elenco aggiungi un nuovo elemento posizionato nel bordo verde è comodo da usare perché è disponibile per
gran parte del tempo.

Nota
Anche se si ha famigliarità con Zope non si deve mai, mai e poi mai aggiungere contenuti
tramite la ZMI (Zope Management Interface). In base a come abbiamo installato Plone
è possibile che abbiamo già visto la ZMI e magari averla già usata per personalizzare e
sviluppare Plone via web. Comunque l’aggiunta di contenuti con la ZMI crea contenuti
incompleti ... (manca la fine del discorso (n.d.t.)
50 INDICE

Figura 3.8: Figura 3-8. Benvenuto in Plone, un semplice documento


3.4. AGGIUNGERE E MODIFICARE DOCUMENTI 51

Figura 3.9: Figura 3-9. Il nostro contenuto

Figura 3.10: Figura 3-10. Aggiungere un documento con il menù di scelta verde
52 INDICE

Figura 3.11: Figura 3-11. Aggiungere un documento con il menu principale della cartella

3.4.3 Modificare un documento


Una volta cliccato per aggiungere un documento si viene portati direttamente alla pagina di modifica con un
messaggio che ci dice che il documento è stato creato. Se questo non accade, si può cliccare un documento e poi
cliccare la sua scheda modifica. Di nuovo vedremo la scheda evidenziarsi in verde (vedere la Figura 3-12).

Ora possiamo modificare il documento tramite il nostro browser web, utilizzando il modulo fornito. Se guardia-
mo la barra degli indirizzi del browser notiamo che un nome breve per l’oggetto è stato creato per noi, qualcosa
come Document.2003-12-29.43787. Quello che segue è un elenco dei campi e dei loro significati:

Nome breve Il Nome breve diventa parte dell’URL del documento, quindi tenerlo corto e descrittivo, preferi-
bilmente senza spazi. Mantenendo queste regole le URL sono più facili da leggere. Per esempio usiamo
qualcosa come relazione-ascolto-2003. Se non si da un nome, Plone ne mette uno per noi.

Nota
Questo campo non appare se si sceglie no nel campo Modifica i nomi brevi nella pagina
delle preferenze personali.

Titolo È il titolo dell’elemento e viene mostrato nel sito (per esempio in cima alla pagine, nell’interfaccia di
ricerca, nel titolo del browser eccetera). È un campo obbligatorio.
Descrizione È una breve desrizione introduttiva dell’elemento, normalmente non più di venti parole per intro-
durre il documento e fornire un aggancio per ricordarne il contenuto. È utile nelle pagine che mostrano
sommari di documenti, tipo risultati di ricerche e cuntenuti delle cartelle.
Testo del documento Contiene il corpo del documento. Il formato del contenuto è impostato utilizzando il
campo Formato del testo (descritto di seguito)
Formato del testo Abbiamo tre1 opzioni per il formato del testo: Structured Text, HTML, e Plain Text. Questi
tipi di testo sono trattati nella sezione Scegliere il formato del testo. Se non si è sicuri lasciare invariato il
campo e scrivere il corpo del testo normalmente.

Carica un file Se si ha nel proprio computer un documento in un file, lo si può caricare invece che scrivere il
contenuto nel campo Testo del documento. Usiamo il pulsante Sfoglia, in fondo alla pagina, per selezio-
nare un file. I contenuti del file caricato rimpiazzano qualsiasi precedente contenuto del campo Testo del
documento.
3.4. AGGIUNGERE E MODIFICARE DOCUMENTI 53

Figura 3.12: Figura 3-12. Modifica di un documento


54 INDICE

Una volta terminato di lavorare sul documento, clicchiamo il pulsante conferma le modifiche per inviare le nostre
modifiche. Saremo portati nuovamente nella scheda visualizza dove potremo vedere come il documento viene
mostrato agli utenti (vedere la Figura 3-13); per fare altre modifiche scegliere nuovamente la scheda modifica.

Se non si inserisce correttamente qualcosa nella scheda modifica, quando si salva il documento si viene inviati
nuovamente a quella pagina dove gli errori vengono evidenziati. A questo punto le nostre modifiche non sono
state applicate, dovremo correggere gli errori e cliccare nuovamente su conferma le modifiche prima che siano
accettate. La scheda visualizza della Figura 3-13 mostra il documento che abbiamo creato. Vediamo che il titolo,
la Descrizione e il Testo del documento sono tutti mostrati con stili leggermente differenti. In fondo alla pagina
c’è l’elemento byline che contiene informazioni sull’autore del documento e sulla data di creazione della pagina.
Notiamo che se ritorniamo ai contenuti della cartella dopo aver salvato le nostre modifiche, possiamo vedere due
documenti nella nostra cartella: quello già esistente creato per noi e quello nuovo che abbiamo appena aggiunto.
Possiamo modificarli entrambi cliccandoli per aprirli nella scheda visualizza da cui possiamo scegliere la scheda
modifica.

3.4.4 Scegliere il formato del testo


Come già detto in precedenza, possiamo modificare il contenuto del documento in almeno tre formati: structured
text, HTML e plain text. Questo stato di cose alquanto confuso deriva dal tentativo di proporre sistemi semplici per
consentire agli utenti di scrivere contenuti fortemente marcati in pieno testo senza dover usare editor stravaganti.
Sfortunatamente in molti casi questo non funziona proprio; è richiesto allenamento per capire la formattazione.
Il testo strutturato richiede un bel po’ per capirlo in quanto ha una sintassi frustrante e non è ben internazionaliz-
zabile. Se dovessimo raccomandare un formato tra gli altri diremmo l’HTML perché è facilmente compreso e lo
si può produrre utilizzando editor WYSIWYG (What You See Is What You Get) come Epoz.

HTML L’HTML è il formato più standard; se un documento viene inserito come HTML viene reso in quel
formato. Questo HTML non deve essere una pagina completa ma piuttosto un pezzetto. Per esempio:
<p>Questo è una forma in <i>HTML</i> per una dimostrazione.</p>
Idealmente l’HTML dovrebbe essere anche XHTML-valido (Extensible HTML ) in accordo con il resto del
sistema Plone, se non lo è le nostre pagine non rispettano gli standard del Web. Introdurre del testo come
XHTML non è per gente debole di cuore, ma nel ‘Capitolo 9‘_ è possibile vedere come integrare strumenti
di modifica complessi che consentano all’utente di scrivere facilmente contenuti in XHTML. Le seguenti
istantanee mostrano l’uso di Epoz in Plone, così gli utenti non devono conoscere l’XHTML:

1
in realtà abbiamo:
• text/structured
• text/restructured
• text/html

• text/plain
• text/plain-pre
• text/python-source
3.4. AGGIUNGERE E MODIFICARE DOCUMENTI 55

Figura 3.13: Figura 3-13. Salvando il contenuto si viene riportati nella scheda visualizza
56 INDICE

Pieno testo Il pieno testo è semplice. Non esegue grandi conversioni o manipolazioni del testo inserito. L’unica
modifica che fa è che gli a capo vengono convertiti in HTML quando sono resi in modo che funzionino
anche nel browser web. Non avviene alcun’altra modifica. Per esempio:
Qui c’è un esempio a "pieno testo" per una dimostrazione
Testo strutturato Il testo strutturato è un sistema per scrivere documenti a pieno testo in un particolare formato
che può essere successivamente interpretato in vari modi. Per esempio se è necessario evidenziare una
parte del testo può essere scritta come *italico*, il che vuol dire che sarà mostrata in italico. Questa
serie di regole significa che un utente può scrivere facilmente una pagina che contiene informazioni sulla
formattazione. Vedere l’‘Appendice A‘_ per un elenco delle regole del testo strutturato. Quello che segue
è un esempio di testo strutturato:
Questo è una forma di *testo strutturato* per una dimostrazione.

3.4.5 Modificare i metadati di un documento


Ogni parte di contenuto può avere qualsiasi numero di proprietà a lui assegnate. Tali proprietà sono dette metadati
e forniscono informazioni come parole chiave, copyright e coautori per un elemento.
Tutte le proprietà sono opzionali e quindi vengono usate solo se sono richiesti requisiti speciali per quella parte
di contenuto specie perché queste informazioni non vengono generalmente mostrate a chi guarda il contenuto.
Perciò la principale ragione per inserire questi dati è per aggiungere informazioni per scopi come la ricerca o la
categorizzazione del contenuto.
Possiamo accedere alle proprietà di un oggetto scegliendo la scheda verde proprietà. Il modulo delle proprietà
ha i seguenti campi, comuni a tutti i tipi di contenuto:

Consenti la conferenza Permette agli utenti che ne hanno il diritto di discutere su questo documento. Se il
valore è lasciato a Default viene usata la politica di sicurezza del sito per questo tipo di contenuto.

Parole chiave A ciascun elemento possono essere associate parole chiave per ottenere raggruppamento e indi-
cizzazione degli elementi. Per esempio, un articolo su eventi politici recenti può avere le parole chiave:
politica e primo ministro. Le parole chiave sono flessibili e si può usare qualsiasi parola chiave dell’elenco.
Non vi sono parole chiave predefinite in un sistema Plone; gli amministratori del sito possono aggiungere
nuove parole chiave in modo che gli altri utenti possano sceglierle.

Data di accessibilità effettiva La Data di accessibilità effettiva è il primo giorno che un contenuto diventa
disponibile. Possiamo specificare tale data inserendo i valori nel modulo o cliccando sulla piccola icona
del calendario, che lo apre, e scegliere una data (vedere la Figura 3-14).
Data di scadenza La Data di scadenza è l’ultimo giorno che un contenuto è ancora disponibile. Normalmente
i campi Data di accessibilità effettiva e Data di scadenza sono lasciati vuoti.

Lingua È la lingua in cui è scritto il documento


Copyright Sono le informazioni sul copyright del contenuto, campo normalmente vuoto.

Dopo aver completato l’inserimento dei valori di questo modulo clicchiamo conferma le modifiche per inviarli.
Come già detto, normalmente non abbiamo bisogno di modificare i valori questa scheda. Le modifiche a questa
scheda dipendono dalle esigenze del nostro sito e dal tipo di sito che vogliamo costruire.
3.4. AGGIUNGERE E MODIFICARE DOCUMENTI 57

Figura 3.14: Figura 3-14. Inserimento della data di effettiva pubblicazione

3.4.6 Cosa sono le date di effettiva pubblicazione e scadenza?


Qualsiasi elemento in un sistema Plone può avere delle date di accesso e di scadenza, se le vuole chi vi effettua
delle modifiche. Entrambe sono opzionali e lasciare vuoti i campi assicura che questi valori non siano impostati.
Un esempio di un elemento che può contenere un valore in Data di accessibilità effettiva è un rilascio stampa. Nel
caso ideale, la notizia è costruita, preparata e revisionata in Plone. Comunque supponiamo che la notizia debba
essere disponibile sul sito web a mezzanotte, esattamente quando abbiamo programmato d’essere a dormire.
Nessun problema, diamo alla notizia un valore in Data di accessibilità effettiva con orario a mezzanotte. Fino
alla Data di accessibilità effettiva l’elemento non sarà visibile nel calendario, nelle ricerche o in pagine che usano
una ricerca, come l’elenco nella scheda notizie. Comunque, chiunque conosca l’indirizzo del rilascio stampa può
accedere direttamente alla pagine. Una volta passata la data di accesso l’elemento appare in tutte le posizioni
dette prima e si mostra dal vivo al mondo.
L’effetto è analogo nel caso della Data di scadenza. Se abbiamo una offerta speciale che deve fermarsi un
determinato giorno possiamo impostarle una data di scadenza a quel giorno. Dopo tale data l’elemento non sarà
visibile nel calendario, nella navigazione, nelle ricerche e così via.
Le date di accesso e di scadenza non modificano realmente lo stato dell’elemento del controllo di flusso (vedere il
Capitolo 7 per ulteriori informazioni sul controllo di flusso); piuttosto esse cambiano solo dove vengono mostrate.
Possiamo anche impostare le date di accesso e di scadenza nella scheda stato che studieremo nella prossima
sezione.

3.4.7 Pubblicare i documenti


Quando un documento viene creato, gli viene attribuito uno stato iniziale chiamato visibile. L’impostazione
predefinita è che un contenuto non sia automaticamente pubblicato e disponibile al mondo; altri lo possono
vedere ma non appare nelle ricerche o nell’albero di navigazione. È uno stato molto utile perché si può far
puntare altri a quel contenuto ma, siccome non appare nella navigazione e nelle ricerche , non è visibile a meno
che gli utenti non lo conoscano.
58 INDICE

In ogni istante, ciascun elemento dei contenuti del nostro sito Plone è in un determinato stato. Avendo elementi
in stati differenti è possibile applicare differenti gradi di sicurezza a ciascun elemento di contenuto. Per esempio,
a volte, per preparare un elemento si può impiegare una o due settimane e magari più revisioni. Probabilmente
vorremo pubblicare il contenuto in modo che sia visibile da tutti gli utenti e sia mostrato nella navigazione e nelle
ricerche.
Possiamo pubblicare il contenuto utilizzando il menù stato posto nell’angolo in alto a destra del contenuto stesso
(vedere la Figura 3-15).

Figura 3.15: Figura 3-15. Menu di stato

Per pubblicare un oggetto, selezioniamo proponi dall’elenco a cascata. Non possiamo pubblicare direttamente
il nostro contenuto, per default si deve sottoporlo a revisione. Quando un elemento viene sottoposto a revisione
passa allo stato di in revisione. Questo è uno stato intermedio tra visibile e pubblicato. Permette la revisione
del contenuto da parte di utenti del sito con il ruolo di revisore prima che diventi disponibile alla vista a tutto il
mondo. Dopo aver proposto il contenuto si può notare che è nello stato in revisione guardando nel box dell’angolo
in alto a destra. Notiamo inoltre che non c’è più la scheda modifica, come mostra la Figura 3-16.

Figura 3-16. Il contenuto è stato sottoposto a revisione, lo stato è cambiato a in revisione e la scheda modifica
non è più una opzione.

Nota
Se siamo registrati come manager, possiamo notare che abbiamo un’opzione extra nell’e-
lenco a cascata per la pubblicazione di nome pubblica. Consente di mettere il contenuto
direttamente nello stato pubblicato senza ulteriori passi.

Nell’elenco a cascata del controllo di flusso nell’angolo destro in alto, c’è l’ulteriore opzione avanzate che apre
il modulo per cambiare lo stato di un oggetto.
Questo ha i campi descritti in seguito:

Data di accessibilità effettiva È il medesimo campo Data di accessibilità effettiva delle proprietà (vedere la
sezione Modificare i metadati di un documento).

Data di scadenza È il medesimo campo Data di scadenza delle proprietà (vedere la sezione Modificare i
metadati di un documento).
3.4. AGGIUNGERE E MODIFICARE DOCUMENTI 59

Commenti Qualsiasi commento sulle modifiche effettuate che verrà conservato nella history. Per esempio
potremmo inserire Prima bozza; prego controllare il secondo paragrafo.

Cambia stato Rispecchia le scelte disponibili nell’elenco a cascata. Per esempio le opzioni pubblica, proponi e
così via. È disponibile anche una ulteriore opzione, annulla, per non modificare alcunché.

Spuntiamo la scelta che ci interessa e clicchiamo conferma le modifiche per inviare i nostri dati.

Cosa sono gli stati del workflow?

A questo punto stiamo sicuramente chiedendoci cosa sia questo controllo di flusso e cosa significhino gli stati. Il
controllo di flusso (workflow) com’è spiegato nel Capitolo 7, è la capacità di assegnare stati diversi ai contenuti.
Quelli che seguono sono gli stati predefiniti:

Visibile Il contenuto viene creato con lo stato visibile. Tutti gli utenti possono trovare un contenuto visibile con
le funzioni di ricerca e possono accedervi direttamente visitando l’URL dell’oggetto. I materiali nello stato
visibile non sono mostrati nell’albero di navigazione. I contenuti nello stato visibile sono modificabili dagli
autori e dai manager del sito.
In revisione I contenuti in revisione comprendono gli elementi che sono stati proposti per la publicazione dai
collaboratori del sito. Dal punto di vista dell’utente un contenuto proposto equivale ad un contenuto nello
stato visibile. La differenza tra i due è che gli elementi proposti sono segnalati per la revisione; i revisori
del sito vengono avvisati per pubblicare o per respingere gli elementi in revisione. Gli elementi in revisione
sono modificabili solo dai manager e dai revisori.
Pubblicato I contenuti pubblicati sono visibili da tutti i visitatori del sito. Appaiono nelle ricerche e nell’albero
di navigazione. Possono apparire anche in aree specifiche per quei tipi (gli elementi notizia, per esempio, si
possono vedere anche cliccando sulla scheda notizie). Gli elementi nello stato pubblicato sono modificabili
solo dai manager ma ogni possessore può ritirarli (il ritiro riporta un elemento allo stato di bozza pubblica).
(visibile n.d.t.)
Privato Gli elementi nello stato privato sono visibili e modificabili solamante dai possessori e da quegli utenti
che hanno l’accesso alla cartella (dove gli elementi esistono) con il ruolo di manager. Non appaiono agli
altri utenti nelle ricerche o nell’albero di navigazione. Gli elementi privati sono modificabili dai manager.

Come si revisiona il contenuto?

Se siamo revisori, nella colonna di destra della pagina home possiamo vedere un nuovo elenco delle revisioni
al nostro primo ritorno nel sito. È l’elenco degli elementi che sono stati sottoposti a revisione e richiedono
l’approvazione nostra o di un altro revisore (vedere la Figura 3-17).

L’elenco delle revisioni è mostrato sulla destra quando ci si registra come utente con il ruolo di revisore e con-
tiene gli elementi da revisionare. Nel nostro caso ci siamo registrati come admin che era l’utente creato durante
il processo di installazione. Possiamo dire di essere registrati poiché vediamo il nostro nome nella barra di
collaboratore. L’elenco delle revisioni mostra una lista di elementi da revisionare, in questo caso dobbiamo re-
visionare il documento di prova. Clicchiamo sul documento per aprirlo. Ora abbiamo essenzialmente le seguenti
possibilità su questo elemento:

Respingerlo Lo si respinge selezionando respingi dalle scelte dell’elenco a cascata. Questo riporta il contenuto
nello stato visibile assumendo che come revisori non siamo contenti di esso. Normalmente si clicca sulla
opzione avanzate per aprire il modulo dei commenti per aggiungere un commento che spieghi il perché
stiamo respingendolo.
60 INDICE

Figura 3.16: Figura 3-17. L’elenco delle revisioni

Approvarlo Lo si approva selezionando pubblica; ciò sposta il contenuto allo stato pubblicato. Questo rende
pubblicamente disponibile il contenuto.
Nessuna modifica Lasciarlo senza far nulla. Questo lascia il contenuto in un limbo ma a volte succede, per
esempio quando è necessario controllare le informazioni o parlarne con altri. Si dovrà tornare e far qualcosa
con questo contenuto poiché esso continuerà ad apparire nel nostro elenco fino a che non faremo una delle
azioni precedenti.
Modificarlo Modificarlo e poi effettuare una delle precedenti azioni. Come revisori possiamo fare ogni modifica
che desideriamo, quindi siamo liberi di cambiare il contenuto tramite la scheda modifica.

Una volta portato fuori dallo stato in revisione, pubblicandolo o respingendolo, il contenuto non viene più mo-
strato nell’elenco delle revisioni. Ovviamente si assume che dobbiamo avere un revisore nel nostro sito; questo
spesso (anche se non necessariamente), è lo stesso utente che come amministratore ha creato il sito Plone. Nel
Capitolo 8 si tratta di come aggiungere e modificare gli utenti e di come dare ad alcuni di loro il ruolo di revisore.

Come si modifica un documento pubblicato?

Una volta pubblicato un documento, per essere modificato deve essere ritirato. Per farlo selezioniamo ritira dal
menù a cascata del controllo di flusso che lo riporterà nello stato visibile. Una volta ritornato nello stato visibile
lo possiamo modificare e poi rimetterlo in coda per la revisione.
Questo passo, sebbene un po’ noioso, è necessario per assicurare che tutti i contenuti passino per una procedura
di approvazione. Per esempio dobbiamo assicurarci che ogni modifica effettuata ad una pagina sia poi corretta
con l’approvazione del contenuto. Gli utenti con il ruolo di manager possono modificare il contenuto in ogni mo-
mento, quindi loro possono andare a correggere velocemente un gypsos2 senza dover fare i passi della revisione.
Si assume che gli utenti con il ruolo di manager siano sicuri. Come spiegato nel ‘Capitolo 9‘_ come manager
possiamo andare in ogni contenuto e vedere la scheda modifica. A questo punto, clicchiamo su modifica per
modificare il documento e fare le nostre scelte.

3.4.8 Condividere il nostro documento


Questo consiste nell’assegnare ad altri diritti sul nostro documento; ad utenti o gruppi di utenti del sistema. È
una funzionalità avanzata che tratteremo con maggior dettaglio nel ‘Capitolo 9‘_

2
con tale termine si indica, in gergo, un piccolo difetto, come un errore di battitura, o di sintassi.
3.5. AGGIUNGERE E MODIFICARE ALTRI TIPI DI CONTENUTO 61

3.5 Aggiungere e modificare altri tipi di contenuto


Abbiamo appena visto in dettaglio come aggiungere e modificare documenti. Gli altri tipi di contenuto sono tutti
simili. Tutti hanno la stessa o una simile azione per modificarli; è solo la forma ed i dati contenuti che cambiano.
Nelle prossime sezioni, tratteremo di quest’altri tipi di contenuto. Tutti i contenuti che seguono sono sottoposti al
medesimo processo di controllo di flusso, quindi, per essere pubblicati, devono essere trattati nello stesso modo
dei documenti.

3.5.1 Aggiungere e modificare immagini


Le immagini sono pezzi di contenuto grafici; si aggiungono selezionando Immagine dall’elenco a cascata. Quan-
do si aggiunge una immagine, il nome del contenuto cambia con il nome del file immagine. In tal modo se
carichiamo una immagine denominata foto.gif questa diverrà accessibile in Plone come foto.gif. Per aggiunge-
re o caricare una nuova immagine è possibile selezionarla nel nostro disco rigido cliccando il pulsante Sfoglia
(vedere la Figura 3-18).

Solitamente i nomi dei file immagine terminano con estensioni come .gif, .jpg, .jpeg, .png, o .pict. Se il tipo di
immagini caricate sono visualizzabili nel browser, si può farlo senza scaricarle nel computer locale vedendole in
una pagina web dentro Plone. I tipi di immagine più comuni sono .gif*, .jpg e .png, che sono visualizzabili su
gran parte dei sistemi. La Figura 3-19 mostra una immagine con il logo Plone.

No è possibile modificare direttamente una immagine, ma possiamo farlo sul nostro disco rigido utilizzando qual-
siasi programma, come Adobe Photoshop o GIMP (GNU Image Manipulation Program). Fatto questo cliccando
sulla scheda modifica si può caricare la nuova immagine in Plone. Se si fa molto uso della manipolazione di
immagini, ci si riferisca al Capitolo 10 che tratta dell’External Editor, uno strumento che permette di modificare
le immagini usando un programma senza la necessità di caricarle e scaricarle.

3.5.2 Aggiungere e modificare file


Un file è un contenuto arbitrario che può essere caricato dal proprio disco rigido. Per aggiungere un file selezio-
niamo File dall’elenco a cascata. Nella scheda modifica si vede il pulsante Sfoglia che consente di caricare il file
dal disco rigido. Può essere un elemento di qualsiasi tipo, inclusi un file di testo (plain-text file), un documento
Microsoft, un foglio di calcolo Excel, un programma eseguibile, un documento Adobe Acrobat e così via. Quan-
do si aggiunge un file il nome dell’elemento in Plone cambia al nome del file caricato. Quindi, se carichiamo un
file denominato libro.pdf diverrà accessibile in Plone come libro.pdf. La Figura 3-20 mostra un file di testo.

Se il file è riconosciuto come file di testo esso viene mostrato nella pagina web ed è modificabile tramite la scheda
modifica. Altrimenti, se è un file scaricabile, l’utente deve scaricarlo nel proprio disco rigido ed eventualmente
modificarlo lì. Poi potrà ricaricarlo nel sistema. Notiamo che un oggetto file ha una scheda che consente di
scaricare direttamente il file.

3.5.3 Aggiungere e modificare gli eventi


Un evento è qualcosa che accadrà nel futuro o qualcosa che è successo nel passato. Possiamo aggiungere eventi
in Plone che saranno mostrati nel calendario. Per aggiungere un evento scegliere Evento dall’elenco a cascata.
Un evento ha parecchie informazioni in più rispetto ad altri oggetti Plone ma sono in gran parte auto esplicativi
(vedere la Figura 3-21).
62 INDICE

Figura 3.17: Figura 3-18. Caricare un’immagine


3.5. AGGIUNGERE E MODIFICARE ALTRI TIPI DI CONTENUTO 63

Figura 3.18: Figure 3-19. Visualizzare un’immagine


64 INDICE

Figura 3.19: Figura 3-20. Aggiungere un normale file di testo


3.5. AGGIUNGERE E MODIFICARE ALTRI TIPI DI CONTENUTO 65

Figura 3.20: Figura 3-21. Aggiungere un evento


66 INDICE

Come ormai d’abitudine, l’unico campo richiesto è il Titolo; ma, se vogliamo che l’evento sia mostrato nel
calendario è necessario inserire le date di accesso e di scadenza. Gli eventi possono durare più giorni o essere nel
passato, se la data iniziale precede la data finale. Per inserire una data, selezionare la data appropriata dal menù
a cascata o cliccare sulla freccetta per aprire un selezionatore grafico.
Una volta pubblicato, l’evento viene mostrato nel calendario. Passando con il mouse sopra l’elemento nel
calendario, vengono mostrate le date di inizio e di fine dell’evento così come il suo titolo (vedere la Figura
3-22).

Figura 3.21: Figura 3-22. Vista dell’evento nel calendario

3.5.4 Aggiungere e modificare i collegamenti


Il tipo di contenuto collegamento è il principale modo degli utenti per condividere dei collegamenti. Tali
URL possono essere risorse in Internet piuttosto che in una rete locale, una risorsa interna, o qualsiasi cosa a cui
l’utente abbia accesso. Per aggiungere un collegamento selezioniamo Collegamento dal menù a cascata.
Se si sta collegando una risorsa su Internet dovremo prefissare il nostro collegamento con un protocollo dispo-
nibile (per esempio http://). Per esempio se abbiamo visitato una interessante pagina del sito web della BBC e
la vogliamo condividere, possiamo aggiungere un collegamento. Il valore dell’URL diventa il testo nella barra
dell’indirizzo (per esempio http://news.bbc.co.uk), come mostra la Figura 3-23.

3.5.5 Aggiungere una notizia


Le notizie sono generalmente usate per mostrare notizie che interessano il lettore di un sito web. Attualmente
un elemento notizia contiene le stesse informazioni di un documento. L’unica differenza reale è che un
elemento notizia viene mostrato quando un visitatore clicca la scheda notizie, come mostra la Figura 3-24.

Se vogliamo scrivere una pagina web che rimanga importante per un lungo periodo di tempo, come le direttive
per il nostro ufficio, useremo un documento. Se abbiamo bisogno di una pagina che dettagli un nostro nuovo
interessante prodotto e vi attiri l’attenzione, useremo una notizia. Questa notizia è visibile nella scheda notizie
e mano a mano che ci sono cose nuove, slitta lentamente verso il basso nella pagina.
3.5. AGGIUNGERE E MODIFICARE ALTRI TIPI DI CONTENUTO 67

Figura 3.22: Figura 3-23. Aggiungere un collegamento


68 INDICE

Figura 3.23: Figura 3-24. Un elenco di notizie


3.6. ORGANIZZARE I CONTENUTI 69

3.6 Organizzare i contenuti


Fino a questo punto abbiamo visto come aggiungere e modificare contenuti di un sito Plone ma senza una chiara
organizzazione ciò può diventare velocemente un problema. Ci sono essenzialmente due modi di organizzare
i contenuti: cartelle e temi. Una Cartella è il meccanismo più semplice e più potente per organizzare i propri
contenuti e funziona nello stesso modo di una cartella o directory sul disco rigido del computer. Una cartella può
contenere ogni elemento di contenuto; il contenuto può essere copiato e incollato tra cartelle e, ovviamente, le
cartelle possono contenere altre cartelle.
Per organizzare contenuti distribuiti in tutto il sito è disponibile uno strumento più sofisticato anche se meno
usato: il Tema. Un tema ricerca nel nostro sito per trovare tutti gli oggetti che corrispondano ad un certo criterio
consentendo di raggruppare quantità disparate di contenuti.

3.6.1 Usare le cartelle


Una Cartella è uguale ad una cartella o una directory del disco rigido, tranne per il fatto che questa cartella ed il
suo contenuto esistono dentro Plone. La si usa nel solito modo; quando si vogliono categorizzare dei contenuti o
rendere le cose un po’ più chiare, possiamo raggruppare elementi e metterli in una cartella. Per aggiungere una
cartella al nostro sito, selezioniamo Cartella dall’elenco a cascata. Questo aggiunge una cartella e ci porta
alla pagina di modifica delle proprietà per questo tipo. Una cartella ha solo tre semplici attributi che l’utente
può modificare: Nome, Titolo e Descrizione. Abbiamo già parlato di questi attributi per i documenti: non vi sono
differenze per le cartelle.
Le cartelle hanno due schede verdi che presentano due viste leggermente differenti: contenuti e visualizza. Avre-
mo già notato che una scheda contenuti è accessibile in ogni contenuto che abbiamo aggiunto al sito; per esempio
quando modifichiamo un documento la scheda contenuti è lì. La scheda contenuti ci porta sempre nei contenuti
della cartella.

Vista dei contenuti di una cartella

La cartella possiede il concetto di pagina predefinita, che è una pagina che viene mostrata all’utente quando
guarda una cartella. È un concetto preso dai siti web dove, quando si guarda una cartella, ci viene mostrata una
pagina predefinita, se ce n’è una presente; spesso il nome di tale pagina predefinita è index.htm o index.html. Se
una cartella ha una pagina predefinita, quando si clicca sulla scheda visualizza viene mostrata quella pagina. Se
una cartella non ha una pagina predefinita viene mostrato un elenco cartella con tutti i contenuti di quella cartella.
Quando cerca una pagina predefinita da mostrare, Plone cerca nella cartella un contenuto con un certo nome e
mostra questo elemento. Il nome della pagina è abitualmente index.htm o index.html, ma l’amministratore di
sistema può aggiungere o cambiare tali nomi.
Questa visualizzazione dei contenuti di una cartella consente all’utente di realizzare diversi obiettivi, come spo-
stare dei contenuti, rinominarli, cancellarli, pubblicarli e modificare il loro ordinamento. Come mostrato nella
Figura 3-25, possiamo vedere una semplice tabella con i contenuti della cartella. Ciascuna riga dalla tabella
mostra il titolo del contenuto (più una icona), il tipo, le sue dimensioni, quando è stato modificato l’ultima volta,
il suo attuale stato nel controllo di flusso ed i selettori di ordinamento. Sulla sinistra c’è un box di spunta per
selezionare l’elemento se si desidera cambiarlo ed una serie di opzioni verso il fondo pagina: rinomina, taglia,
copia, elimina e cambia lo stato. Queste sono sufficentemente autoesplicative e si possono applicare a più oggetti
al colpo spuntando più box.

Per esempio, per rinominare un pezzo di contenuto, clicchiamo sul box di spunta di quell’elemento e poi clicchia-
mo su rinomina. Così si apre il modulo di rinomina che ci consente di rinominare il nome breve (title) di ciascun
elemento in quell’elenco. Clicchiamo poi su rinomina tutti per rendere effettive le modifiche. I pulsanti taglia
e copia ci permettono di copiare o cancellare contenuti tra differenti cartelle. Il pulsante elimina ci consente di
70 INDICE

Figura 3.24: Figure 3-25. Contenuto della cartella dopo aver aggiunto alcuni tipi di documento descritti in questo
capitolo
3.6. ORGANIZZARE I CONTENUTI 71

eliminare l’elemento da Plone. Proprio uguale al nostro disco rigido, se copiamo, spostiamo o cancelliamo una
cartella, anche tutti i contenuti della cartella vengono spostati, copiati o cancellati.
Una novità in Plone 2 è la possibilità di modificare l’ordinamento predefinito degli elementi di una cartella.
L’impostazione predefinita è che gli elementi di una cartella siano visualizzati nell’ordine con cui sono stati
aggiunti. Se un elemento è più importante e bisogna portarlo in cima, usiamo le freccette nella parte destra della
tabella per spostare l’elemento. Le seguenti funzioni appaiono nei contenuti della cartella solo quando succedono
determinate cose:

• Se il contenuto ha impostata una data di scadenza ed è scaduto, vedremo apparire la parola


scaduto in rosso vicino all’elemento.
• Se il server ha installato l’External Editor, possiamo cliccare sulla matita per modificare in
External Editor (questo viene trattato dal Capitolo 10.
• Se il contenuto è bloccato, vediamo apparire un’icona lucchetto vicino al contenuto

Pubblicare una cartella

Le cartelle sono associate ad un workflow molto più semplice di quello usato per i documenti. In precedenza in
questo capitolo, abbiamo visto come pubblicare un contenuto per renderlo pubblicamente visibile e che questo
consente agli utenti di creare e modificare il più possibile prima di mandarlo dal vivo. Comunque le cartelle sono
leggermente diverse poiché contengono materiali ma non possiedono un proprio contenuto. Per questa ragione
le cartelle non hanno lo stato in revisione. Chiunque può direttamente pubblicare o privatizzare cartelle, quindi
ci sono tre stati: privato. visibile e pubblicato.
Dopo aver aggiunto una cartella, selezioniamo pubblica dall’elenco a cascata. Dopodiché viene mostrata nell’al-
bero di navigazione. Così, per le precedenti regole del controllo di flusso, se non si pubblica una cartella, essa
non viene mostrata nell’albero di navigazione.

3.6.2 Utilizzo dei temi


Un Tema consente di collezionare contenuti da diverse aree di un sito Plone e di metterli in una posizione. I
temi funzionano creando un criterio comune a tutti gli oggetti che intendiamo ottenere. Questo criterio potrebbe
essere: tutte le immagini e tutte le notizie con Plone nel testo. Siccome il tema è un tipo di contenuto piuttosto
complicato, all’inizio solo i manager possono aggiungerne. Se non vediamo Tema nell’elenco degli elementi da
aggiungere non abbiamo i diritti per farlo.
Per aggiungere un tema selezioniamo Tema dall’elenco a cascata. Dopo aver aggiunto il tema possiamo creare
un criterio con la scheda criteri. L’elenco di criteri e tipi è disponibile nell’elenco a cascata in fondo alla
pagina. È un elenco un po’ confusionario; non lo vogliamo trattare qui. Sfortunatamente, cosa sono e cosa
significano quei termini è pesantemente collegato alla tecnologia sottostante come gli indici del catalogo e gli
attributi degli oggetti. Per questa ragione il Capitolo 11 tratta questi argomenti in dettaglio.
Per creare un tema che mostri tutte le immagini, per esempio, abbiamo bisogno di un criterio che faccia una
ricerca in base al portal_type. Per questo selezioniamo un Nome del campo di tipo portal_type, poi String
Criterion (???? da modificare n.d.t.) e quindi clicchiamo aggiungi. Il criterio viene aggiunto in cima alla
pagina; nel campo a destra di portal_type inseriamo Immagine e poi premiamo conferma le modifiche. Ora
abbiamo un criterio per il nostro tema che mostrerà tutto ciò che sia una immagine. Ritornando alla scheda
visualizza possiamo vedere tutte le immagini del sito.
Come detto, i temi sono assai complicati, hanno una pessima interfaccia e sono raccomandati solo agli utenti
avanzati. Molti li hanno trovati utili e questo è il motivo per cui sono ancora disponibili; comunque in futuro
verrà sviluppato un sistema più amichevole.
72 INDICE

3.7 Discutere e trovare i contenuti


Aggiungere e modificare un contenuto è ancora più utile se la gente può trovarlo e poi discuterlo. Il primo modo
di trovare del contenuto è tramite le ricerche e la navigazione. Fortunatamente Plone imposta automaticamente
la ricerca e la navigazione per gli utenti in modo da far loro trovare con facilità i contenuti che abbiamo aggiunto.

3.7.1 Aggiungere dei commenti ai contenuti


Il feedback degli utenti è una parte vitale di qualsiasi sito web. Consentire agli utenti di aggiungere dei com-
menti assicura che quegli utenti possano dare del feedback, correggere errori tipografici, o comunque discutere
il contenuto. Possiamo discutere quasi ogni pezzo di contenuto di Plone, le uniche eccezioni sono le cartelle ed i
temi.
Possiamo abilitare la conferenza (discussione) in due modi. Primo, il possessore del contenuto (altrimenti
noto come la persona che lo ha creato) attiva la funzionalità conferenza cliccando sulla scheda proprietà del-
l’oggetto e scegliendo Abilitata sotto Consenti la conferenza, come mostra la figura 3-26. Secondo, l’opzione
predefinita applica la politica di sicurezza per questo tipo di contenuto come l’ha definita l’amministratore del
sito; l’impostazione di questa opzione per l’amministratore è descritta nel Capitolo 10

Una volta abilitata la conferenza cliccare su aggiungi un commento per discutere del contenuto, il che apre il
modulo per l’aggiunta di un commento (vedere la Figura 3-27).

Inserire il soggetto ed il testo del commento. I testo viene inserito come plain text quindi scrivere come d’abitudi-
ne. I commenti non passano alcun controllo di flusso quindi i commenti appaiono appena vengono aggiunti. Una
volta inserito un commento, si può rispondergli per formare un elenco alberato di commenti su un argomento.
Inoltre i commenti vengono inseriti nella catalogazione dimodoché possono essere ricercati.

Nota
Gli amministratori registrati come manager possono rimuovere qualsiasi replica o interi ar-
gomenti. Disabilitando la conferenza, invece, non vengono rimossi i commenti, ma ne viene
impedita la visualizzazione; riabilitandola, rivedremo ancora i commenti esistenti.

3.7.2 Ricerca dei contenuti


Plone contiene un potente sistema di ricerca basato sullo ZCatalog di Zope. Questo motore di ricerca permette
di catalogare in molti modi i contenuti per poterlo interrogare velocemente e con efficenza. Il Capitolo 10 tratta
nei meandri di come questo funziona e di come può essere interrogato.
Quando si cerca nel contenuto, esso viene mostrato all’utente se è in uno dei due stati: pubblicato o
visibile. In cima al proprio sito Plone un campo di ricerca consente di effettuare facilmente semplici ri-
cerche testuali allo stesso modo di un motore di ricerca (vedere la Figura 3-28). Per esempio inseriemo Giovedì
per trovare il contenuto che contenga la parola Giovedì. Viene mostrato un risultato con tutti i contenuti che
corrispondono; cliccare su un titolo per vederlo.

Il sistema consente anche ricerche più sofisticate con funzionalità molto simili ai principali motori di ricerca. Si
possono chiedere cose più o meno complesse. Per esempio si possono usare le seguenti opzioni:

Globbing Un asterisco significa qualsiasi lettera. Per esempio inserendo Giov* si troveranno Giovedì e Gio-
vanna. Non ne è consentito l’uso all’inizio di una parola.
3.7. DISCUTERE E TROVARE I CONTENUTI 73

Figura 3.25: Figura 3-26. Abilitare la conferenza


74 INDICE

Figura 3.26: Figura 3-27. Aggiungere un commento a un certo contenuto

Figura 3.27: Figura 3-28. Ricerca di Tuesday su Plone.org


3.8. ESEMPIO: CREARE UN SITO WEB PER IL PLONE BOOK 75

Single wildcards Un punto di domanda significa una lettera. Per esempio inserendo ro?a troveremo roba, rosa,
roma e così via. Non ne è consentito l’uso all’inizio di una parola.

And La parola and significa che entrambi i termini dalle due parti di and devono esistere. Per esempio inserendo
Roma and Giovedì nel risultato troveremo gli elementi con entrambi queste parole nel contenuto.
Or La parola or significa che sia l’uno che l’altro dei termini possono esistere. Per esempio inserendo Roma
or Giovedì nel risultato troveremo gli elementi con almeno una di queste parole nel contenuto.
Not La parola not significa che vogliamo un risultato con gli elementi dove la parola non è presente; va prefis-
sata con un and. Per esempio inserendo benvenuto and not pagina ritorneranno le corrispondenze che
contengono benvenuto ma non pagina.
Phrases Una frase è raggruppata tra due quotature (’ ) e significa alquante parole una dopo l’altra. Per esempio
inserendo ’pagina di benvenuto’ troveremo Questa pagina di benvenuto ti introduce in Plone, un sistema
di gestione di contenuti ma non Benvenuto nelle pagina personale del mio sito web
Not phrase Si può prefissare la frase con un meno (-). Per esempio inserendo benvenuto -’pagina di benve-
nuto’ troviamo tutte le pagine con dentro benvenuto ma non quelle con la frase pagina di benvenuto.

Nota
Tutte le ricerche sono case insensitive.

I grandi siti danno risultati delle ricerche giganti e però vengono mostrati solo venti elementi alla volta. Nelle
pagine con il risultato appare una barra di navigazione in cima ed in fondo alla pagina di ricerca. I valori su cui
viene effettuata la ricerca sono il titolo, la descrizione e il corpo del testo (se il tipo di contenuto li ha, come le
notizie e i documenti).

3.7.3 Ricerca avanzata


Si può allungare l’elenco delle ricerche utilizzando la ricerca avanzata che è accessibile da un risultato di una
ricerca standard. Nei vecchi siti Plone c’era una scheda ricerca che portava a questa pagina, è ancora ripristinabile
come spiagato nel Capitolo 4. La scheda di ricerca avanzata consente agli utenti la ricerca mediante l’uso di molti
attributi compreso titolo, parole chiave, descrizione, stato di revisione, data di creazione, tipo di contenuto ed
anche autore così come ricerche di testo (nello stesso modo della ricerca veloce disponibile nell’angolo a destra
in alto), come mostra la Figura 3-29.

3.8 Esempio: creare un sito web per il Plone Book


Per dare un sito Plone di esempio e fornire una serie altri esempi, abbiamo impostato un sito per questo libro. Un
sito Plone standard con solo piccole modifiche. Questo per poter navigare nel libro ed avere un sito di riferimento
dove aggiungere le nuove funzionalità in modo che siano trattate nel libro includendo nuovi modelli, skin, e così
via. Il sito web di questo libro è all’indirizzo http://plone-book.agmweb.ca; ed è stato inizialmente installato su
un server Windows, come descritto nel Capitolo 3. Successivamente però abbiamo trasferito tutto in Linux.
Il sito ha i seguenti scopi:

• dare informazioni sul libro e su come acquistarlo.


• dare facile accesso al software usato nel libro.
• portare esempi di codice e consentire agli utenti di interagire con i modelli del libro.
76 INDICE

Figura 3.28: Figura 3-29. La ricerca avanzata


3.8. ESEMPIO: CREARE UN SITO WEB PER IL PLONE BOOK 77

• contenere gli errata corrige o problemi intervenuti dopo la pubblicazione.

Impostato il sito Plone abbiamo creato le seguenti cartelle base e strutture di pagine:

Home
|_ Software
|_ Chapters
|_ Chapter 1
|_ Chapter 2
...

Per farlo ci siamo registrati con l’utente creato con l’installer, nel nostro caso l’utente admin. Dopo la registrazio-
ne siamo andati nella pagina home, abbiamo cliccato la scheda modifica, scritto il testo per quella pagina home.
Abbiamo creato i collegamenti alle cartelle Chapters e Software. Poi abbiamo cliccato la scheda contenuti ed
abbiamo aggiunto due cartelle, come mostrato in Figura 3-30.

Figura 3.29: Figura 3-30. Il contenuto della cartella con la pagina personale e alcune altre cartelle

Poi siamo andati nella cartella Chapters e abbiamo iniziato ad aggiungere una cartella per ciascun capitolo.
Siccome non abbiamo creato una pagina predefinita, Plone mostra un elenco di tutti i capitoli. Il nome del
capitolo è la descrizione del capitolo (per esempio Introducing to Plone and This Book), ed il nome breve è il
numero del capitolo, che mantiene molto corta e chiara la nostra URL (per esempio /Chapters/3). Abbiamo
lasciato tutto nello stato visibile, quindi non c’è problema nell’aggiunta di contenuti.
Duplicate explicit target name: “appendice a”.
78 INDICE
Capitolo 4

Capitolo 4: Come fare semplici


personalizzazioni

79
80 CAPITOLO 4. CAPITOLO 4: COME FARE SEMPLICI PERSONALIZZAZIONI
Indice

Dopo aver visto come aggiungere e modificare i contenuti, potremmo desiderare di personalizzare il nostro
sito. Questo capitolo spiega come eseguire delle semplici personalizzazioni in Plone utilizzando le opzioni a
disposizione degli amministratori. Per eseguire le personalizzazioni in questo capitolo è necessario essere un
utente autenticato con il ruolo di manager, come discusso nel Capitolo 2.
Queste personalizzazioni sono tutte opzioni di configurazione che possono venir fatte da Web. Piuttosto che
spiegarle tutte in dettaglio, questo capitolo da una panoramica su alcuni argomenti, e spiega come compiere certi
compiti mostrando parte del meccanismo che ci sta sotto. Questi concetti saranno ampliati e spiegati nei seguenti
capitoli del libro.
Il primo posto in cui guardare, e anche il più utile, è il pannello di controllo di Plone, che offre varie possibilità
per l’amministrazione del sito. Tutte i componenti di un sito Plone sono studiati per essere facilmente modificati e
personalizzati; le linguette blu che puoi osservare nella parte alta della pagina possono essere facilmente aggiunte
e rimosse. Un altro esempio sono i box nelle colonne di sinistra e destra, che sono chiamati portlets. Plone ha
molti portlets, ed è possibile con facilità scegliere quali visualizzare.
In ultimo, questo capitolo spiega come personalizzare i fogli di stile a cascata (CSS: Cascading Style Sheets) e le
immagini in Plone. I CSS influiscono su tutto in un sito Plone. In effetti, come vedrai in questo capitolo, i CSS
determinano tutti i colori, le posizioni, e molte delle immagini che vedi. Se sei in grado di modificare il codice
CSS, allora puoi cambiare quasi tutto l’intero look and feel del tuo sito Plone. Tutte le opzioni considerate in
questo capitolo mostrano l’alto livello di controllo che puoi avere suo tuo sito Plone.

4.1 Amministrare siti


Il primo posto che deve essere visitato dagli amministratori del sito è il pannello di controllo di Plone. È
il modo per accedere ad alcune delle funzioni del sito, inclusi il nome e la descrizione del tuo sito Plone,
l’amministrazione degli utenti e dei gruppi, e la visualizzazione degli errori eseguiti dal tuo sito.
Il termine pannello di controllo è generico, e non deve essere confuso con il pannello di controllo della Zope
Management Interface (ZMI), che mostra le opzioni a basso livello della ZMI. Il pannello di controllo di Plone è
più un continuo tentativo di fornire un’interfaccia amichevole alle funzioni offerte dalla ZMI. Poiché il progetto
è in sviluppo, è difficile predire quali funzionalità vi verranno incluse in futuro. Piuttosto ti raccomandiamo di
andare al pannello di controllo e vedere quali funzioni sono correntemente disponibili; se non c’è l’opzione che
ti serve sarai costretto ad andare nella ZMI.
Per accedere al pannello di controllo, autenticati in Plone come utente con il ruolo di manager. Se non hai un
utente con questo ruolo ma sei un amministratore del sito, consulta il capitolo 9 per avere informazioni su come
fare. Se non sei un amministratore e vuoi questo livello di accesso, devi chiedere all’amministratore del tuo sito.
Per accedere al pannello di controllo, clicca plone setup in alto nella pagina (vedi figura 4-1).

Questa operazione aprirà il pannello di controllo (vedi figura 4-2)

81
82 INDICE

Figura 4.1: Figura 4-1. Accedere al pannello di controllo

Figura 4.2: Figura 4-2. Il pannello di controllo di Plone


4.1. AMMINISTRARE SITI 83

Nel pannello di controllo sono disponibili le seguenti funzioni:

Inserimento/rimozione di prodotti Questo link permette di automatizzare l’installazione di prodotti (come


spiegato dettagliatamente nel capitolo 10).
Registro degli errori Questo link permette di accedere la log degli errori occorsi durante l’esecuzione del sito
Plone.

Impostazioni Mail Questo link permette di modificare l’indirizzo SMTP (Simple Mail Transfer Protocol) che
Plone utilizza per inviare e-mail.
Impostazioni del portale Questo link permette di modificare le impostazioni del portale (come discusso nella
sezione Cambiare titolo, descrizione, e indirizzo e-mail di questo capitolo).

Skin Questo link permette di impostare lo skin corrente (come spiegato nel capitolo 7).
Amministrazione utenti e gruppi Questo link permette di modificare utenti e gruppi (come spiegato nel capi-
tolo 8).
Interfaccia di gestione Zope Questo link ti porta alla ZMI.

Attraverso il resto del libro, farò riferimento al pannello di controllo di Plone, se starò parlando di una funzionalità
accessibile da esso; il resto del libro userà invece la ZMI per le modifiche alle proprietà del sito.
84 INDICE

Usare la ZMI
La ZMI è l’interfaccia base che ti consente di accedere alla sottostante interfaccia Zope.
Prima di Plone, la ZMI era il modo principale per accedere, modificare ed amministrare i siti
Zope e i loro contenuti. Era originariamente l’interfaccia Web per il content management
system. Ovviamente, al giorno d’oggi Zope non può essere realmente considerato un con-
tent management system così com’è, ma piuttosto un’applicazione che fornisce la base a
sistemi come Plone. Dopo aver giocherellato un po’ con la ZMI, ti renderai conto perché non
è un’interfaccia adeguata per content management system.
Una cosa che la ZMI fornisce è una semplice interfaccia al sottostrato Plone e all’infra-
struttura Zope. Puoi trovare molte delle caratteristiche base menzionate in questo capitolo
attraverso Plone, ma eventualmente puoi ricorrere anche alla ZMI. Se non hai mai visto
la ZMI prima, ecco alcuni semplici modi per accedervi; la strada più semplice è quella di
autenticarsi come utente con il ruolo di manager, cliccare su plone setup, e poi su Zope
Management Interface. Noterai che l’indirizzo della ZMI è l’URL (uniform resource locator)
del tuo sito Plone con /manage alla fine. La ZMI del tuo sito Plone assomiglierà a questa:

Potresti avere dei problemi con il virtual hosting, capita con gli installer per Windows e Mac.
Il virtual hosting è la possibilità di avere il sito Plone come oggetto root, piuttosto che la root
dell’istanza Zope. Per maggiori informazioni sul virtual hosting, puoi consultare il capitolo
10. In questo caso per arrivare alla root, hai bisogno di accedere alla porta di manage di
Zope. Su Windows, seleziona Start - Plone - Plone - Manage Root. Noterai che l’indirizzo
verrà impostato a http://localhost:8080/manage. Per informazioni sul virtual hosting della tua
istallazione, consulta la documentazione specifica.

Suggerimento
Avendo a che fare con la ZMI, trovo che avere due browser differenti aperti può essere
veramente utile. Ad esempio, io uso Mozilla e Firefox. Inoltre, come amministratore di un
sito, è sempre una buona idea avere due browser differenti per testare che le modifiche
siano compatibili con più di un browser.

Potresti aver bisogno di raggiungere la root della tua istallazione di Zope per due ragioni. In
primo luogo, per poter raggiungere il pannello di controllo di Zope. In secondo luogo, per
poter selezionare il tuo sito Plone per creare, rinominare, e copiare siti Plone. Il pannello
di controllo di Zope ti da informazioni sul database e ti permette l’accesso ai prodotti e agli
add-on (devi potervi accedere per seguire il capitolo 10), come mostrato qui:

4.1.1 Cambiare titolo, descrizione, e indirizzo e-mail


Il titolo, la descrizione e l’indirizzo e-mail di un sito Plone vengono memorizzati come proprietà di un oggetto
nel sito stesso. Puoi accedere a questi campi cliccando il link Portal Settings nel pannello di controllo di Plone
(vedi figura 4-3).
I settaggi del portale sono i seguenti:

Titolo del portale è il titolo del sito che appare nel titolo del browser, nel breadcrumbs, nella navigazione, nelle
e-mail, e così via. Per default è Portal.
Descrizione del portale è la descrizione del portale, usata per ora solo nelle syndication.
4.1. AMMINISTRARE SITI 85

Nome del mittente usato per la posta inviata dal portale questo campo si riferisce a varie funzioni, come la
funzione per il recupero della password dimenticata o la funzione ’segnala ad un amico’. Per default è
Portal Administrator.
Indirizzo del mittente usato per la posta inviata dal portale è l’indirizzo del mittente delle e-mail inviate da
Plone. Per default è postmaster@localhost.
Lingua di default è la lingua di default, data nelle proprietà di un oggetto (??).
Politica delle password i nuovi utenti hanno due possibilità; possono o inserire una password, o inserire una
password che gli verrà recapitata per e-mail (??). In entrambi i casi sono tenuti ad inserire un indirizzo
e-mail, la seconda opzione assicura che l’indirizzo e-mail sia valido.
Abilita la funzionalità External Editor questa opzione abilital’External Editor, uno strumento avanzato per
l’editing. Richiede che l’External Editor sia istallato sul computer dell’utente. Il capitolo 10 lo spiega più
in dettaglio.

Dopo aver selezionato le opzioni desiderate, clicca su Save per confermarle. Tutte le modifiche effettuate da
questa maschera saranno subito attive.

4.1.2 Impostare un Mail Server


Plone invia e-mail utilizzando l’oggetto MailHost, che fornisce un’interfaccia ad un server SMTP e permette agli
sviuppatori Plone di scrivere form e strumenti per l’invio di e-mail. La funzione ’invia ad un amico’ e l’invio
e-mail in caso di password dimenticata usano le impostazioni configurate qui.
La configurazione di default è impostata su un mail server su localhost alla porta 25. Se il server SMTP si trova
altrove in rete, puoi accedere a questa impostazione cliccando su plone setup e poi su Mail Settings. A questo
punto è possibile cambiare il mail server e la porta affiché riflettano la tua configurazione. Sulla mia rete, il
mail server è monty.clearwind.ca sulla porta 1025, cosicché ho impostato il server come mostrato in figura 4-4;
tuttavia, in molti casi, non avrai bisogno di modificare quest’impostazione.

Nota
L’oggetto MailHost è un oggetto Zope accessibile dalla ZMI. Questo oggetto non necessita
attualmente di autenticazione sul server. Se ce n’è bisogno, cambia le impostazioni sul
server.

4.1.3 Registrazione degli errori


Il registro degli errori (error log) cattura gli errori generati da un sito Plone; ci sono caratteristiche come gli errori
di Pagina non trovata (404), errori di mancata autorizzazione, e così via. Non è stato studiato per intercettare gli
errori dalle form. Se per caso qualcuno non inserisce un valore richiesto nel campo di una form, questo non verrà
riportato; questo non viene considerato errore fintanto che non è catturato dal framework di validazione. Questo
errore log è studiato per intercettare gli errori interni del server.
Dall’interfaccia di Plone clicca su Plone Setup e poi su Error Log, per visualizzare gli errori riportati dal sito
Plone. Clicca sull’eccezione nella lista (se ce n’è almeno una) per visualizzare l’errore. La figura 4-5 mostra un
errore capitato compilando erroneamente la form delle impostazioni mail. È una pagina lunga, che include un
traceback Python completo e la request ricevuta.

Questi sono le impostazioni per la form dell’error log:


86 INDICE

Figura 4.3: Figura 4-3. Opzioni del portale


4.1. AMMINISTRARE SITI 87

Figura 4.4: Figura 4-4. Impostazioni del mail server


88 INDICE

Figura 4.5: Figura 4-5. Un esempio di errore


4.2. PERSONALIZZARE L’ASPETTO DI PLONE 89

Numero delle eccezioni di cui tenere traccia Il numero di eccezioni da tenere a video nel registro. Per default
sono 20.

Copia le eccezioni nel registro degli eventi Consente di copiare ogni eccezione in un file di log basato su un
file fisico. Disabilitare questa opzione significa che non verrà tenuta traccia permanente delle eccezioni.
Per default questa opzione è attivata.
Tipi di eccezione ignorati È una lista (una per riga) di tipi di eccezioni da ignorare. Per default sono ignorati
Unauthorized (accesso alla risorsa non autorizzato), NotFound (risorsa non trovata), e Redirect.

Puoi registrare ogni eccezione e visualizzarla a video. Ciò significa che se mentre un utente sta visitando il tuo
sito viene generato un errore, puoi di seguito andare alla pagina dell’error log e vedere cosa è successo. I tre
componenti di un errore sono l’error type (ovvero il tipo di errore), l’error value (che è una stringa che spiega
quando questo tipo di errore capita), e il traceback. I primi due vengono visualizzati al’utente su una pagina
standard di errore (vedi figura 4-6).

Quindi, se un utente riporta un errore, il registro spesso includerà un messaggio con il nome dell’errore e il
suo valore. Se l’utente non ha avuto il permesso di compiere una determinata azione e quindi è stato generato
un errore Unauthorized, oppure è stata raggiunta una Pagina non trovata (404), allora verrà presentata una una
pagina di errore personalizzata piuttosto che quella standard mostrata in figura 4-6. Questi sono i tipi standard di
errore:

Unauthorized Accade quando un utente non ha i privilegi per eseguire una funzione.
NotFound Quando l’elemento richiesto da un utente non esiste.

Redirect È un errore causato da un redirect HTTP (HyperText Transfer Protocol).


AttributeError Quando un oggetto non ha l’attributo richiesto, viene generato questo errore.
ValueError Accade quando un valore dato è incorretto, e non può essere gestito correttamente dalla validazione
o da qualche altro framework.

4.2 Personalizzare l’aspetto di Plone


La sezione seguente descrive le altre personalizzazioni che possono essere fatte ad un sito; qusi tutte richiedono
l’accesso alla ZMI.

4.2.1 Comprendere i Portlet


In un sito Plone, vengono visualizzare per default tre colonne: la colonna di sinistra, la centrale, e quella di
destra. La colonna centrale ospita il contenuto dell’oggetto correntemente visualizzato. È il posto dove risiedono
la maggior parte delle funzionalità utente per l’aggiunta e la modifica di contenuti, la compilazione delle form, e
così via. Le colonne di sinistra e destra contengono invece una serie di box che mostrano informazioni. Ognuno
di quest box è chiamato portlet. Una variabile definisce che portlet devono essere mostrati in un certo momento. Il
modo migliore per capire i portlet è guardare come funzionano i portlet forniti di default con Plone. I parametri
dei portlet si trovano nell’oggetto portal. Per accedervi, entra nella ZMI, assicurati di essere sulla root del
sito Plone, e clicca sul tab delle proprietà. Verrà aperta una lista di proprietà, incluse left_slots, right_slots, e
document_action_slots (vedi figura 4-7).
90 INDICE

Figura 4.6: Figura 4-6. Un esempio di messaggio di errore


4.2. PERSONALIZZARE L’ASPETTO DI PLONE 91

Nota
Nelle precedenti versioni di Plone i portlet si chiamavano slot. È un termine comune che
causa confusione con il termine slot usato nei page template, così è stato sostituito con
portlet nella versione 2. In alcuni punti del codice o ne testo potresti imbatterti nel termine
slot. In questo contesto le parole slot e portlet sono da considerare sinonimi.

La proprietà left_slots fa riferimento ai portlet mostrati nella parte sinistra della pagna, mentre right_slots si
riferisce ai portlet della parte destra. I portlet sono visualizzati nell’ordine in cui sono inseriti nella proprietà,
dall’alto verso il basso; da notare che ogni portlet occupa una riga. Tuttavia, moti portlet hanno al loro interno
del codice che assicura che il portlet venga visualizzato solo quando ha senso che lo sia. Per esempio, è superfluo
che il portlet per il login venga visualizzato se l’utente si è già autenticato. In questo caso, anche se il portlet logi
è incluso nella lista dei portlet, esso viene mostrato solo quando c’è bisogno.
Il valore di ogni portlet è uno speciale valore che rappresenta il percorso di un’espressione Template Attribute
Language Expression Syntax (TALES). Gli sviluppatori possono aggiungere i loro portlet personalizzati al sito,
creando semplici macro e page tempate. I portlet di default sono i seguenti:

left_slots Include i portlet navigation, login, e related (tradurre?).


right_slots Include i portlet review, news, events, recently published, e calendar.

Per default non sono configurati in Plone tutti i portlet disponibili. La sezione seguente descrive uno per uno i
portlet in Plone, e mostra come si presentano. Quindi verrà mostrata l’espressione percorso (come tradurre?) che
deve essere aggiunta alla proprietà slots affinché vengano visualizzati.
Per esempio, per mostrare il portlet del calendario a sinistra, basta inserire here/portlet_calendar/macros/portlet
nella proprietà left_slots e cliccare su Save Changes. Per rimuoverlo dalla proprietà right_slots, è sufficiente
rimuovere la stessa riga dalla proprietà e cliccare su Save Changes.

Calendario

Il portlet calendario è uno dei portlet di default, che mostra il calendario alla destra della pagina di Plone. Questo
portlet mostra gli eventi pubblicati nel mese visualizzato in un piccolo calendario. Il portlet calendario viene
visualizzato indipendentemente dalla presenza di eventi da visualizzare. Puoi configurare il calendario usando il
tool portal_calendar nella ZMI (vedi figura 4-8).

L’espressione da aggiungere è here/portlet_calendar/macros/portlet.

Eventi

Il portlet eventi mostra la lista degli eventi imminenti pubblicati. Anche se abilitato inserendolo nella lista, questo
portlet non apparirà fin tanto ché non ci saranno degli eventi pubblicati da mostrare (vedi figura 4-9).

L’espressione da aggiungere è here/portlet_events/macros/portlet.


92 INDICE

Figura 4.7: Figura 4-7. Le proprietà del portlet di default


4.2. PERSONALIZZARE L’ASPETTO DI PLONE 93

Figura 4.8: Figura 4-8. Il portlet calendario

Figura 4.9: Figura 4-9. Il portlet eventi

Figura 4.10: Figura 4-10. L’icona per aggiungere un elemento ai favoriti


94 INDICE

Favoriti

Nell’angolo in alto a destra di un documento Plone puoi vedere un icona con il logo di Plone. Un utente può
cliccare questo logo per aggiungere un elemento ai favoriti. Il concetto di favorito è molto similare al concetto
di segnalibro o link alle pagine alla quale vuoi in futuro ritornare; La differenza consiste nel fatto che questo
favorito viene memorizzato nel sito Plone. La figura 4-10 mostra l’icona per aggiungere un favorito.

I favoriti vengono aggiunti alla cartella home dell utente, e in seguito mostrati nel portlet favoriti assieme ad un
link per organizzarli (vedi figura 4-11). I favoriti mostrati sono i favoriti che l’utente ha memorizzato, quindi,
anche se abilitato, questo portlet si mostrerà solo se l’utente ha qualche registrato in precedenza qualche favorito.

Figura 4.11: Figura 4-11. Il portlet favoriti

L’espressione da aggiungere è here/portlet_favorites/macros/portlet.

Fatti riconoscere

Il portlet login mostra il form per il login, consentendo ad un utente di autenticarsi fornendo username e password.
Se la password è stata dimenticata, c’è un’opzione che consente di farsela inviare per e-mail. Anche se abilitato,
questo portlet non verrà visualizzato se l’utente si è già autenticato (vedi figura 4-12).

L’espressione da aggiungere è here/portlet_login/macros/portlet.

Navigazione

Il portlet di navigazione mostra una semplice struttura ad albero delle cartelle nella posizione corrente. Fornisce
uno strumento comodo e semplice per la navigazione. Questo portlet è estremamente personalizzabile; sceglien-
do dalla ZMI portal_properties e poi navtree_preperties, poi accedere a delle modifiche che saranno spiegate
nella sezione Modifica del portlet di navigazione (vedi figura 4-13).

L’espressione da aggiungere è here/portlet_navigation/macros/portlet.

Ultime notizie

Il portlet news mostra una lista di link alle news recenti (vedi figura 4-14). Anche se abilitato, questo portlet
verrà mostrato solo in presenza di news pubblicate. Le news di un sito sono ancre raggiungibili cliccando sul tab
news.

L’espressione da aggiungere è here/portlet_news/macros/portlet.


4.2. PERSONALIZZARE L’ASPETTO DI PLONE 95

Figura 4.12: Figura 4-12. Il portlet login

Figura 4.13: Figura 4-13. Il portlet navigazione


96 INDICE

Figura 4.14: Figura 4-14. Il portlet news


4.2. PERSONALIZZARE L’ASPETTO DI PLONE 97

Modifiche recenti

Il portlet degli elementi recenti elenca gli elementi di recente pubblicazione, a partire dall’ultima volta che l’u-
tente si è autenticato (vedi figura 4-15). Se non ci sono elementi di questo tipo, allora il portlet non viene
mostrato.

Figura 4.15: Figura 4-15. Il portlet modifiche recenti

L’espressione da aggiungere è here/portlet_recent/macros/portlet.

Inerenti

Il portlet dei relativi mostra la lista degli elementi correlati all’elemento che si sta visualizzando, come determi-
nato dalle parole chiave ad esso associate. Se l’elemento correlato è un link ad un altro sito web, verrà mostrato
in una lista separata delle risorse esterne al sito. Anche se abilitato, quaso portlet verrà visualizzato sono se sono
presenti elementi relativi da mostrare (vedi figura 4-16).

Figura 4.16: Figura 4-16. Il portlet relativi

L’espressione da aggiungere è here/portlet_related/macros/portlet.

Da esaminare

Il portlet revisione mostra la lista degli elementi nello stato di revisione e che sono in attesa di essere revisionati.
Viene mostrato solo se l’utente autenticato ha il ruolo di revisore e se ci sono elementi in attesa di revisione (vedi
figura 4-17).

L’espressione da aggiungere è here/portlet_review/macros/portlet.


98 INDICE

Figura 4.17: Figura 4-17. Il portlet revisione

Sito web del Plone Book: modifica degli slot

Molti degli slot sulla parte destra non hanno senso per il sito Plone Book. Questo libro non ha eventi, quindi
il calendario non serve. Mi aspetto che vengano ancora aggiunte delle cose al sito, ma saranno veramente cose
minime fino al completamento del sito. Ho deciso quindi di rimuovere completamente tutti gli slot di destra dal
mio sito. Per ottenere ciò sono andato alla root del portale attra verso la ZMI, e ho cliccato sul tab delle proprietà.
Quindi ho cancellato gli slot di destra. I portlet che abitualmente sono ospitati sulla parte destra, navigazione,
login, relativi, mi sono tutti utili, così li ho tenuti.
Così è come si mostrano a questo punto le proprietà dei portlet per il sito Plone book:

Configurare portlet differenti in parti differenti del sito

Il database Zope che sta alla base di Plone ha una funzionalità chiamata acquisizione. Nella sua forma piu’
semplice, significa che quando viene richiesto un elemento, come ad esempio right_slots, Plone ricerca l’oggetto
piu’ vicino che contiene questa proprietà. In questo modo, cercando quali portlet mostrare nella colonna di
destra, normalmente Plone trova l’oggetto radice e considerà la sua proprietà right_slots.
Questo è il motivo per cui puoi cambiare le proprietà nell’oggetto root del portale per cambiare l’intero sito. Si
puo’ notare pero’ che cliccando sul link my folder e andando alla cartella personale, non appare il calendario.
Se clicchi su Members e poi su Properties dalla ZMI, noterai che c’è una proprietà right_slots. Per questa
cartella questa proprietà è una lista vuota. Quando il sito Plone si mette alla ricerca valore di questa proprietà
per quali portlet devono essere presenti nella colonna di destra, si muove lungo la gerarchia di cartelle fino al
raggiungimento della cartella Members. Qui trova un valore per right_slots e lo usa. Fintantoché il valore di
right_slot nella cartella Members è vuoto, guardando contenuti presenti in Members, gli slot di destra saranno
vuoti.
Gli amministratori del sito possono personalizzare la disposizione dei portlet all’interno del sito, aggiungendo e
eliminando proprietà delle cartelle attraverso la ZMI. Basta selezionare l’elemento e cliccare sul tab Properties.
Per aggiungere la proprietà per gli slot a destra o sinistra, usa la form Add, in fondo alla pagina, e assicurati che
il tipo della proprietà sia list.

4.2.2 Modifica del portlet di navigazione


Di tutti i portlet di cui abbiamo parlato, quello per la navigazione è probabilmente il più usato, e quello per
il quale vengono chieste più informazioni. Nel dettaglio, come si può modificare questo portlet e il modo in
cui viene visualizzato? Il portlet di navigazione elenca la cartella corrente e i suoi documenti nello slot di
navigazione. Puoi cambiare questo slot modificando il codice; tuttavia, alcune modifiche possono essere fatte più
semplicemente dalla ZMI. La cosa più importante da tenere presente è che solo gli elementi pubblicati vengono
mostrati nell’albero di navigazione ai collaboratori e agli utenti anonimi. Per modificare le proprietà di questo
albero di navigazione, clicca su portal_properties e poi su navtree_properties nella ZMI.
Questa è un elenco ridotto delle opzioni disponibili:
4.2. PERSONALIZZARE L’ASPETTO DI PLONE 99

showMyUserFolderOnly Mostra sono la cartella utente dell’utente autenticato. In questo modo, se viene se-
lezionata la cartella Members , non verranno mostrate le cartelle di tutti i collaboratori. Questa opzione è
selezionata di default.
showFolderishSiblingsOnly Vengono visualizzate solo le cartelle presenti nello stesso contenitore della cartella
mostrata; alternativamente mostrerà tutti i contenuti. Questa opzione è selezionata di default.
showFolderishChildrenOnly Se questa opzione è abilitata su una cartella, mostra solo le cartelle contenute,
piuttosto che mostrare tutti gli altri tipi di contenuti. Impostando questa opzione, effettivamente vengono
mostrati tutti i contenuti della cartella correntemente selezionata. Questa opzione è selezionata di default.
roleSeeUnpublishedContent Come accennato, un contenuto viene mostrato a collaboratori o utenti anonimi
solo se pubblicato. Aggiungere, in una nuova riga, un nuovo ruolo a questa lista, significa permettergli la
visualizzazione di contenuti non pubblicati. È una cosa indesiderabile, se l’utente poi comunque non ne
ha il permesso di accesso.
croppingLength Determina quanti caratteri del nome mostrare nel albero del navigatore. Per default sono 256.
idsnotToList Sono gli identificativi degli elementi da non mostrare. Ogni id va messo in una riga separata. Per
default questa lista è vuota.

Dopo aver fatto le modifiche a questa form, basta premere Save Changes. L’ordinamento degli elementi nel
navigatore dipende dall’ordinamento degli oggetti nella form di visualizzazione della cartella che li contiene.
Come mostrato nel capitolo 3, utilizzando le frecciette sù e giù, gli utenti possono cambiare l’ordine a proprio
piacere.

4.2.3 Sito web del Plone Book: modifica della navigazione


Per la maggior parte dei siti preferisco un albero di navigazione più completo di quello di default. Vado quindi
nelle opzioni dell’albero di navigazione e deseleziono showFolderishChildrenOnly e showFolderishSiblingsOnly.
In questo modo si ottiene che i contenuti vengano mostrati in modo più carino; per esempio, ecco la cartella
software con qualche elemento selezionato:

4.2.4 Modificare il formato delle date


Lungo le portlet di tutto il sito, Plone rappresenta le date in un formato costante, personalizzabile internamente
usando i formati. Ogni volta che una data viene mostrata in Plone, viene invocato un formato tra due disponibili.
Puoi trovare questi formati accedendo alla ZMI, cliccando portal_properties e poi site_properties. I formati sono
questi:

localTimeFormat È il formato da utilizzare per le date che devono apparire in forma compatta.
localLongTimeFormat È il formato da utilizzare per le date che devono apparire nel formato esteso, mostrando
anche i secondi.

Il formato delle date è basato sul modulo Python time. Informazioni riguarda a questo formato possono essere
trovate all’indirizzo http://www.python.org/doc/current/lib/module-time.html. Per la data compatta, il valore di
default è %Y-%m-%d che significa anno-mese-giorno (ndt: in inglese dalle iniziali year-month-day) rappresentati
come numeri decimali (ad esempio 2003-10-26). Per il formato esteso, il valore di default è invece %Y-%m-%d
%I:%M %p, ovvero anno-mese-giorno ore:minuti am/pm (per esempio, 2003-10-26 07:32 PM).
Ecco un breve sommario delle opzioni disponibili (il nome dei giorni e dei mesi può variare a seconda del Locale
del browser):
100 INDICE

%a Abbreviazione in lingua locale del giorno della settimana (ad esempio Lun)

%A Il nome locale del giorno della settimana (ad esempio Lunedì)


%b L’abbreviazione locale del nome del mese (ad esempio Gen)
%B Il nome locale del mese (ad esempio Gennaio)
%d Il giorno del mese, rappresentato come numero decimale
%H L’ora (orologio a 24 ore) come numero decimale
%I L’ora (orologio a 12 ore) come numero decimale
%m Il mese come numero decimale

%M I minuti come numero decimale


%S I secondi come numero decimale
%y Le ultime due cifre dell’anno, come numero decimale
%Y L’anno completo, in quattro cifre decimali

Se vuoi includere il nome del giorno nel formato compatto della data, devi semplicemente cambiare il formato
della data compatta in %A, %d %b., %Y. L’effetto di questa modifica sarà Lunedì, 20 Set., 2004. Questa data
viene usata nei box a destra e a sinistra dello schermo, nel risultati delle ricerche, nei contenuti per linea, e così
via.

4.2.5 Aggiungere parole chiave e tipi d’evento


C’è uno strumento in Plone, portal_metadata, che permette all’amministratore del sito di definire alcuni meta-
dati per gli elementi. Plone utilizza i metadati definiti nel tool portal_metadata per parecchio scopi.
Ad esempio, quando inserisci un evento, ti viene proposta una lista di possibilit tipi di evento. Puoi fare aggiunte
a questa lista cliccando dalla ZMI su portal_metadata, quindi elements, e poi subject. Vedrai un vocabolario di
eventi che elencano gli oggetti per questo content type (...uhm... controllare la frase...). È semplice modificare o
integrare questa lista, un elemento per riga, per ottenere i tipi di eventi relativi. Questi tipi di evento appariranno
nella machera per l’aggiunta e la modifica di un evento.
Un altro uso del portal_metadata è la selezione delle parole chiave disponibili sul sito. Nella form in por-
tal_metadata/elements/subject, potrai notare un vocabolario per il tipo di contenuto di <default>. Se aggiungi
degli elementi nel campo vocabolario di questa pagina e clicchi su Update, li aggiungerai alla lista delle parole
chiave disponibili per tutti i tipi di contenuto.
Se vuoi che le parole chiave appaiano, diciamo, solo nei documenti, usa la form add (aggiungi) in fondo alla
pagina. Scegli un tipo di contenuti, e aggiungi qualche vocabolo, uno per ogni riga. Questi diverranno parole
chiave che gli utenti possono selezionare solo per questo tipo di contenuto.
Se sei autenticato come utente con ruolo di manager o reviewer, cliccando sul tab proprietà di un oggetto nel-
l’interfaccia di Plone, vedrai il box nuova parola chiave per aggiungere parole chiave ad-hoc. Queste non
appariranno nel vocabolario portal_metadata, ma appariranno in tutti i tipi di contenuti che gli altri utenti
inseriranno.
4.2. PERSONALIZZARE L’ASPETTO DI PLONE 101

4.2.6 Cambiare la pagina predefinita


Come già accennato nel ‘capitolo 3‘_, quando un utente visualizza una cartella, gli viene mostrata, se presente,
la pagina di default contenuta nella cartella. Nelle vecchie versioni di Zope e Plone, il nome di questa pagina
doveva essere index_html. Lo si nota in molti siti Plone, in cui l’indirizzo Web termina con index_html. Se
modifichi questo nome di file con un estensione più comunemente riconosciuta, come index.html, sarà più facile
modificare questi file con editor o strumenti di sviluppo Web.
In Plone puoi definire un elenco di pagine da prendere in considerazione per essere presentate come pagina
di default (vedi figura 4-18). Per default queste pagine sono index_html, index.html, index.htm, e FrontPage.
Puoi configurare questa lista in site_properties/portal_properties/default_page property, seguendo la regola di
un nome per riga. Quando viene richiesta la pagina di default, Plone va alla ricerca di ogni pagina in questa
lista, partendo dalla prima, fino a che non ne incontra una corrispondente. Inoltre, se vuoi cambiare questa
impostazione solo per una cartella, puoi accedere a questa tramite la Zmi, cliccare sulla scheda delle proprietà, e
aggiungere una nuova proprietà lista chiamata default_page.

4.2.7 Come fare affinché l’elenco delle notizie sia la pagina predefinita?
Il funzionamento esatto di questo sistema richiede una certa conoscenza del meccanismo sottostante. Per ora, vai
semplicemente sulla radice del portale e clicca su Properties. A questo punto, sul fondo della pagina, completa
la maschera add new property con queste informazioni, e poi premi il pulsante Add:

Per il campo Name: default_page Per il campo Value: news Per il campo Type: lines

Ora ritorna al sito Plone. Al posto della home page standard vedrai la pagina delle news. Anche la scheda delle
news riporta alla pagina delle news, ma nella prossima sezione ti mostrerò come rimuoverlo.

4.2.8 Modificare le schede del sito


In un sito Plone le varie schede si riferiscono a differenti sezioni o parti del sito. L’uso delle schede è un concetto
familiare nel design dei siti Web, ed è comune in siti tipo Amazon, MSN, e Plone stesso.
Esistono due tipi principali di schede: le schede di portale e le schede di contenuto. Le schede di portale sono
blu e appaiono in alto nel sito Plone. Quelle di default sono home, news e member. La sezione che segue mostra
come personalizzarle. Le schede di contenuto sono verdi, e appaiono quando un elemento può essere modificato.
Le schede di contenuto, come il nome steswso suggerisce, sono relative al contenuto. Il capitolo 11 spiega come
modificarle. Le schede in un sito Plone sono costruite a partire da una collezione di azioni quindi, per capire
come modificarle, è necessaria una panoramica veloce sulla azioni.

Introduzione alle azioni

In Plone ci sono persone che possono compiere azioni differenti, in momenti differenti o in parti differenti del
sito. Queste azioni vengono chiamate actions. Plone le traduce in schede, link, ed elementi di altri generi. C’è
un metodo altamente configurabile per produrre questi elementi di navigazione per un sito.
Ogni azione ha le seguenti proprietà configurabili nella ZMI. Dove configurarle dipende da dove queste azioni
sono immagazzinate. Qui c’è una lista delle proprietà per un’azione di default:

Name È il nome amichevole dato all’azione. Spesso questo nome viene utilizzato nell’interfaccia. Per esempio,
se questa azione sarà utilizzata come scheda, questo nome sarà quello che comparirà come testo nella
scheda.
102 INDICE

Figura 4.18: Figura 4-18. Rendere index.asp la pagina di default preferenziale


4.2. PERSONALIZZARE L’ASPETTO DI PLONE 103

Id L’identificativo univoco dell’azione.

Actions Questa è l’azione vera e propria che deve essere compiuta. Ad esempio, se è un’azione per una sche-
da, l’azione usata sarà un link. Questo campo è un’espressione TALES (vedi il capitolo 5 per maggiori
informazioni).
Condition È la condizione che deve essere verificata affinché l’azione possa essere compiuta. Ad esempio,
usandola come scheda, se questa condizione è verificata, allora lascheda viene visualizzata. Il campo
contiene un’espressione TALES(vedi il capitolo 5 per maggiori informazioni).
Permission Il permesso che l’utente deve possedere per avere questa azione. Questo permesso deve coincidere
affinché l’azione possa essere compiuta (vedi il capitolo 9 per informazioni sulla sicurezza).
Category In questo modo le azioni vengono categorizzate. In Plone questo metodo viene utilizzato per distin-
guere le azioni e poterle utilizzare in differenti contesti dell’interfaccia utente. Per le schede del portale
questa categoria corrisponde a portal_tabs.
Visible Indica se la categoria è attiva. Poiché perloppiù ci si riferisce ad elementi visibili, è stato usato il termine
visible.

Introduzione alle schede principali

Nella sezione seguente modificherai come esempio le schede principali seguendo due vie differenti. Cambierai
il testo della scheda portale in benvenuto, e sposterai la scheda dei collaboratori a sinistra della scheda notizie.
Le azioni per le schede del portale sono immagazzinate nel tool portal_action, quindi per modificarle clicka su
portal_action dalla ZMI. Come mostrato in figura 4-19, verrà aperta una lunga lista di azioni presenti di default.
Ancune di queste ti sembreranno famigliari, poiché rappresentazno parti del sito Plone.

Scendi attraverso le azioni, fino a trovare l’elemento Home, e cambia il suo nome in benvenuto. Quindi scendi
sino al fondo della pagina, e clicka su Save. Ritornando all’interfaccia di Plone, noterai che ora sulla scheda c’è
scritto benvenuto.
L’ordine delle schede da sinistra verso a destra ricalca l’ordine nell delle azioni dall’alto verso il basso. Quindi,
mmuovere una scheda è solo questione di selezionarla attraverso il checkbox, scendere fino al fondo della pagina,
dove sono presenti i pulsanti Move Up e Move Down, per spostare rispettivamente la scheda verso l’alto o verso
il basso della lista. Può essere un pò tedioso, ma continuando a selezionare l’azione e cliccando sui pulsanti
Move Up e Move Down, puoi modificare l’completamente ordine delle schede. Fatto ciò, puoi tornare al portale
e notare come ora le schede appaiano nel nuovo ordine.

Perché il testo viene messo in minuscolo?

Plone cambia in minuscolo (attraverso i fogli di stile) i testi di molte parti del sito attraverso, come ad esempio
le schede. Per disabilitare questa opzione è sufficiente modificare il foglio di stile, come spiegato più avanti in
questo capitolo, nella sezione ’Modificare le immagini e il CSS’.
104 INDICE

Figura 4.19: Figura 4-19. Le azioni sul portale di un sito Plone


4.2. PERSONALIZZARE L’ASPETTO DI PLONE 105

Book Web Site: Aggiungere una nuova scheda


A nice navigation helper is to add a tab or remove one in the portal tabs. Quindi, in questo
riquadro, aggiungerai una scheda che punta alla cartella Software, e rimuoverai le schede
notizie e collaboratori (che nel mio sito non puntano a nulla). Ritorna alla ZMI, e seleziona
portal_actions. Scorri in fondo alla pagina, al form di aggiunta. Ho riempito i campi con i
valori seguenti:
• Software
• software_tab
• string:$portal_url/Software

• View
• portal_tabs
• selected

Oltre a ciò, ho trovato le azioni riferite a news e members e ho deselezionato la proprietà


Visible (ricordandomi di premere Save, ovviamente). Tornando all’interfaccia di Plone puoi
vedere il risultato. Il valore chiave è Action, che è un espressione TALES. Queste espres-
sioni saranno trattate nel capitolo 5. Il valore Action punta all’URL della cartella alla quale
dovrà puntare; nel mio caso è Software, e si trova nella radice del mio sito Plone. Quindi
l’espressione diventa string:$portal_url/Software.

Modificare l’icona di un documento

Guardando un elenco di link o opzioni in un sito Plone, è facile che questo elenco sia prodotto da una serie di
azioni. Se non si tratta di azioni, si tratta di codice, ma molte delle funzionalità dell’interfaccia di Plone sono
generate dinamicamente attraverso settaggi della ZMI. Altri due esempio di azioni sono le azioni del documento,
e le azioni del sito.
Le azioni del sito appaiono nell’angolo in alto a destra e sono i link per cambiare la grandezza del testo. These
links could be anything but just happen to reference some client-side script functions. Questi link sono nuova-
mente configurati in portal_actions, sono solo azioni appartenenti ad una differente categoria. Se dai un’occhiata
a portal_actions, noterai tre azioni in fondo alla pagina. Hanno come categoria site_actions. Per rimuoverle
è sufficiente deselezionare l’opzione Visible. Le icone derivano dallo strumento portal_actionicons, che è una
altro semplice strumente delegato a mappare le icone alle azioni. Guardando portal_actionicons, puoi notare che
normal_text di site_actions corrisponde ad un’icona (vedi figura 4-20).

Similmente, le azioni per il documento presenti in portal_action appartengono alla categoria document_actions.
Anche in questo caso, editando queste azioni puoi modificarne l’ordine, le icone, il testo, e aggiungere o
rimuovere icone dall’interfaccia.

4.2.9 Modificare le immagini e il CSS


Il look and feel di un sito Plone è un grosso argomento che si porta via tre capitoli, i capitoli 5, 6, e 7. La
prossima sezione ne copre le basi, e piuttosto di tentare di spiegare tutto, mostra solo come fare velocemente
alcune modifiche.
Uno skin è una serie di CSS, immagini, template, e script che collaborano per creare il look and feel di Plone.
L’idea alla base dello skin è che puoi lo modificare cambiando in questo modo l’aspetto del sito, senza doverne
toccare i contenuti.
106 INDICE

Figura 4.20: Figura 4-20. Site actions


4.2. PERSONALIZZARE L’ASPETTO DI PLONE 107

Modificare lo skin

Lo skin di default può essere cambiato usando il form dello skin accessibile dal pannello di controllo. Puoi
rappresentare il sito Plone in modi differenti, applicando diverse combinazioni di colori, fogli di stile, template.
La form dello skin ha queste tre scelte:

Aspetto di default E’ lo skin di default da presentare all’utente quando questi accede al sito. Solo uno skin
viene fornito di default, il Plone Default.
Consenti ai collaboratori di scegliere l’aspetto del portale Questa opzione decide se dare agli utenti la possi-
bilità di scegliere lo skin che preferiscono. Con questa opzione abilitata, un utente può andare nelle sue
preferenze e scegliere un altro skin. Per default questa opzione è abilitata.
Persistenza dello Skin nel Cookie Se un utente può scegliersi lo skin, questa opzione fa in modo che questa
scelta venga mantenuta anche ai suoi successivi accessi, mandanendo l’informazione nel cookie. Per
default è disabilitata.

Una volta scelte le opzioni che desideri, bisogna premere Save per renderle effettive. Per aumentare le perfor-
mance del sito, conviene usare la cache per le immagini e i fogli di stile. Per essere sicuro di guardare la nuova
skin come dovrebbe, cancella la cache del browser (in Internet Explorer dovrebbe essere sufficiente premere
Ctrl+F5).

Impostare un logo differente

Cambiare il logo in un sito Plone è un’operazione semplice, ma i passi possono creare un pò di confusione,
quindi devono essere seguiti attentamente.
Per prima cosa è necessario accedere alla ZMI, cliccare su portal_skins, poi su plone_images, e infine su logo.jpg.
Si aprirà una pagina corrispondente a questo oggetto. Dovrebbe assomigliare alla figura 4-21.

Questo oggetto rappresenta il logo, così come viene visto in Zope. Nella figura 4-21 si vedono le informazioni
riguardanti l’immagine, le sue dimensioni, e la posizione all’interno del file system. A metà pagina c’è il pulsante
Customize (personalizza); clickalo. Verrà creata una copia dell’oggetto chiamata logo.jpg nella cartella custom
(vedi figura 4-22).

Nota

Se a questo punto appare un messaggio d’errore del tipo bad request, torna in in por-
tal_skins/custom, e vedrai che c’è già un oggetto chiamato logo.jpg. Clicka su questo
oggetto. Può esserci un solo oggetto chiamato logo.jpg nella cartella custom; l’errore
mostrato è un avvertimento che l’operazione di personalizzazione di questo oggetto è
già stata eseguita. Se vuoi personalizzare l’oggeto originale (in parole povere, ripetere
questi passi), basta cancellare l’oggetto presente in custom.

Questa pagina assomiglia molto alla pagina mostrata in figura 4-21, ma ci sono alcune diffrenze. In primo luogo,
se guardi in alto a destra nella pagina, noterai che meta_type e posizione di questo oggetto sono cambiati. Non
stai più guardando in portal_skins/plone_images/logo.jpg, ma in portal_skins/custom/logo.jpg. In secondo luogo,
noterai la presenza del pulsante Sfoglia, che ti permette di selezionare un’immagine e inviarla, il che significa che
puoi modificarla. Premi questo pulsante per scegliere la tuo nuova immagine, e clicka Save per rendere effettive
le modifiche. In figura 4-23 si vede come ho aggiunto il logo Canadian Plone come esempio.

Ora ritorna all’interfaccia di Plone, e nota come l’immagine sia cambiata. Per essere sicuro di stare veramente
guardando la nuova immagine, cancella la cache del browser (con Internet Explorer puoi premere Ctrl+F5).
108 INDICE

Figura 4.21: Figura 4-21. Il logo di default


4.2. PERSONALIZZARE L’ASPETTO DI PLONE 109

Figura 4.23: Figura 4-23. Il logo di Canadian Plone logo


110 INDICE

Cosa fare quando l’immagine non è in formato JPG?

Zope non basa il tipo MIME (Multipurpose Internet Mail Extensions) sull’estensione, ma piuttosto sul contenuto.
Per questa ragione puoi benissimo inserire un immagine GIF all’interno di logo.jpg, e funzionerà alla perfezione
poiché verrà applicato il MIME corretto image/gif. In ogni caso, potresti coler rinominare l’immagine in logo.gif
o logo.png per fare meno confusione.

Modificare il codice CSS

Il CSS è responsabile la maggior parte del look and feel del tuo sito, incluse le schede, le immagini, i box, e il
layout in generale. Il fatto che il CSS di Plone è totalmente personalizzabile significa attraverso pochi fogli di
stile gli utenti possono personalizzare molto del suo aspetto.
Il capitolo 7 spiega cosa fatto tutti gli elementi; in questa sezione avrai una veloce panoramica su come cambiare
il codice CSS di un sito Plone. Come prima cosa accedi alla ZMI, seleziona portal_skin, quindi plone_styles
e infine ploneCustom.css. In questo modo si aprirà la pagina di questo oggetto, per ora nacora vuoto. Plone
sta utilizzando le proprietà a cascata dei CSS. Poiché l’HTML (Hypertext Markup Language) di Plone importa
prima plone.css e poi ploneCustom.css, ogni modifica successiva sovrascrive il foglio di stile standard. Perché
questa dovrebbe essere una buona cosa? Perché in questo modo puoi creare una serie di modifiche incrementali
in ploneCustom.css senza danneggiare o alterare il foglio di stile centrale di Plone.
Allora, per personalizzare l’oggeetto ploneCustom.css, seleziona portal_skins/plone_styles/ploneCustom.css e
premi il pulsante Customize. Ancora una volta, piuttosto di personalizzare l’oggetto in portal_skins/plone_styles/ploneCustom
puoi notare come ora ti trovi in portal_skins/custom/ploneCustom.css. Poiché gli oggetti di tipo file possono
essere modificati da Web, puoi editare da Web anche questo foglio di stile.
Come esempio, mettiamo un’immagine in mezzo allo sfondo (non è necessariamente il massimo come interfaccia
utente, ma è un esempio chiaro di come personalizzare il codice CSS). Prima di tutto hai bisogno di inserire un
immagine in Plone. Per farlo seleziona portal_skins/custom, premi il pulsante Add e seleziona Image, come
mostrato in figura 4-24.

Figura 4.24: Figura 4-24. Aggiungere una nuova immagine

Come file ho scelto un’immagine trovata sul Web (disponibile anche nel sito web Plone book), ma è possibile
scegliere qualunque immagine. Presta attenzione che l’ID dell’immagine sia background.gif, come mostrato in
figura 4-25.
4.2. PERSONALIZZARE L’ASPETTO DI PLONE 111

Figura 4.25: Figura 4-25. Controllo della nuova immagine

Successivamente, ha bisogno di cambiare il codice CSS affinché punti a questa nuova immagine. Hai già richiesto
la personalizzazione del CSS, quindi basta che torni a portal_skins/custom/ploneCustom.css e cambi il testo in
questo modo:

/* DELETE THIS LINE AND PUT YOUR CUSTOM STUFF HERE */

to the following:

body {
background-image: url(background.jpg);
background-repeat: no-repeat;
background-position: center;
}

Premi il pulsante Save Changes per rendere effettive le modifiche. Quindi ritorna all’interfaccia di Plone. Se
tutto è andato per il verso giusto, dovresti vedere la nuova immagine (vedi figura 4-26).
112 INDICE

Figura 4.26: Figura 4-26. La nuova immagine di sfondo


Capitolo 5

Capitolo 5: Introduzione alla


modellazione in Plone (Plone Template)

113
114CAPITOLO 5. CAPITOLO 5: INTRODUZIONE ALLA MODELLAZIONE IN PLONE (PLONE TEMPLATE)
Indice

Note alla traduzione del capitolo


template: modello di pagina
traversal: attraversamento
context: contesto
namespace: spazio dei nomi

Plone utilizza tre livelli di tecnologie per creare una pagina. Del codice Python e i modelli di pagina3 creano
l’Hypertext Markup Language 4 o HTML che è inviato al browser. Quindi alcuni Cascading Style Sheets 5 (CSS)
applicano le regole di formattazione che producono la pagina con la quale il lettore è adesso famigliare. Questi
due primi elementi, il codice Python e i modelli di pagina, sono l’argomento principale di questo capitolo e del
Capitolo 6.
Per capire come creare e quindi modificare un modello di pagina Plone è necessario prima descrivere alcuni
concetti di base. Alcuni di questi concetti sono caratteristiche particolari di Plone e nonostante introducano
grandi vantaggi è necessario un po’ di tempo per prendervi confidenza.
In questo capitolo cominceremo con descrivere la pubblicazione di oggetti. Spiegheremo come interagire con
gli oggetti all’interno di Plone, quindi descriveremo come costruire espressioni. Una volta che il lettore sarà
familiare con questi due concetti analizzeremo come le pagine di Plone sono realmente assemblate. Alla fine del
capitolo creeremo una nuova pagina all’interno del nostro sito Plone con le tecniche fino lì imparate.
Questo capitolo ha più significato per il lettore che è già familiare con il linguaggio Python. Tuttavia ad ogni passo
verranno spiegati i concetti che stanno dietro al codice quindi, anche se il lettore non conosce Python, dovrebbe
comunque comprendere. Il resto del libro si riferisce a oggetti Template Attribute Language Expression Syntax
(TALES) e Script (Python) quindi il lettore dovrebbe prendersi il tempo di acquisire familiarità con loro in questo
capitolo. Il lettore dovrebbe avere già una piccola introduzione: nel precedente capitolo abbiamo introdotto le
espressioni TALES perché sono usate per generare portlet e action.

3
o page template
4
o linguaggio di demarcazione per ipertesti
5
o fogli di stile

115
116 INDICE

5.1 Comprendere il meccanismo di modellazione sottostante


Tuffarsi direttamente dentro il funzionamento dei modelli di pagina (template) di Plone ci porterebbe facilmente
in confusione e quindi andremo ad analizzare prima il sottostante meccanismo di modellazione. In un mondo
ideale questo dovrebbe essere un qualcosa di cui l’utente non dovrebbe curarsi ma, in pratica, si è osservato che
questo è il primo ostacolo in cui le persone incappano quando provano a studiare l’utilizzo di Plone.
Plone è piuttosto unico in quanto tutto in Plone è un oggetto. Se non si è familiari con il concetto di oggetto
non ci si preoccupi, non c’è molto da sapere: un oggetto è semplicemente una cosa che incapsula un qualche
comportamento. Ogni oggetto ha dei metodi che possono essere richiamati sull’oggetto. Un esempio è un mouse
per computer: un mouse per computer può avere metodi come movimento, click e click destro.
In Plone un documento è un particolare tipo di oggetto. Questo significa che un documento non è semplicemente
un frammento di testo statico ma bensì un qualcosa di un po’ più complicato e più utile. Un documento in Plone
ha, per esempio, un metodo description che restituisce la descrizione che l’utente ha aggiunto per il particolare
documento. Quando si userà il sistema di modellazione si vedrà più in dettaglio come tutto sia un oggetto.
Guardiamo per prima cosa i principi base della pubblicazione di oggetti.

5.1.1 Introduzione alla pubblicazione di oggetti


In Plone si pubblicano oggetti che sono in realtà collocati all’interno di Zope; la maggior parte di essi sono oggetti
che sono memorizzati, appunto, nel database degli oggetti. Il concetto è più complicato rispetto all’ambiente
Standard Common Gateway Interface (CGI) dove uno script viene eseguito passandogli una serie di variabili
relative alla richiesta. Tutto in Plone è un oggetto, tutto in Zope è un oggetto, tutto in Python è un oggetto.
Fino ad adesso si è cercato di evitare di utilizzare la parola oggetto utilizzando al suo posto i termini modello
di pagina, script e elemento ma tutti questi in realtà sono oggetti, semplicemente oggetti che si comportano in
maniera differente.
6
Quando si richiede un Uniform Resource Locator (URL) a Plone viene invocato un oggetto dell’ambiente. Plone
fa questo trasformando l’URL in un path o percorso. Quindi, se l’URL è /Plone/login_form, quello che
Plone fa è scomporre questo URL in un path e cercare ognuno di questi oggetti nel database. Plone troverà un
oggetto Plone e dentro quello un altro oggetto chiamato login_form. Il percorrere questo percorso è detto
attraversamento: essenzialmente Zope risale attraverso questi oggetti e invoca l’ultimo nel path.
Quando Zope chiama l’oggetto login_form, l’oggetto viene eseguito nel suo contesto. Questo termine si
incontra spesso in Plone. È banalmente il contesto corrente dell’oggetto che sta per essere eseguito. Nel nostro
esempio è /Plone. Il contesto varia molto muovendosi all’interno del sito Plone. Se si fosse richiesto l’URL
/Plone/Members/login_form il contesto sarebbe stato /Plone/Members.
Come menzionato il meccanismo di attraversamento è il sistema con cui è possibile accedere agli oggetti in
Plone per via programmatica, allo stesso modo che tramite un URL. Questo è simile ad accedere agli elementi di
un file system: se si vuole accedere ad una foto nella cartella Miei Documenti in Windows si immette una
directory del tipo c:\Documenti e Impostazioni\andrea\Miei Documenti\Fotografia; al-
lo stesso modo per accedere a un oggetto Plone si immetterebbe Members/andrea/Fotografia.jpg.
Questo funziona se si ha una serie di cartelle ed oggetti che assomiglia a questo:

Members
|_ andrea
|_ Fotografia.jpg

Nell’esempio con il file system si attraversa il disco fisso del computer cartella per cartella. In Plone succede la
stessa cosa, solo che Members e andrea sono oggetti.
Una particolarità è che Zope fa distinzione tra maiuscole e minuscole. Mentre in Windows è possibile scrivere
Fotografia.jpg o fotografia.JPG, questo non funziona in Plone: è necessario fornire il nome dell’oggetto con le
5.1. COMPRENDERE IL MECCANISMO DI MODELLAZIONE SOTTOSTANTE 117

stesse maiuscole e minuscole dell’ID dell’oggetto. Per questa ragione è raccomandato cercare di mantenere tutti
gli URL in caratteri minuscoli in modo da ridurre le possibilità di errore da parte degli utenti.
Plone e Zope hanno aggiunto un elemento chiamato acquisizione a tutto questo sistema di pubblicazione. Il
concetto alla base dell’acquisizione è quello di contenimento: gli oggetti sono collocati all’interno di altri oggetti
chiamati contenitori. Nell’esempio precedente l’oggetto andrea è un contenitore all’interno del contenitore
Members all’interno del sito Plone, un contenitore a sua volta (che in definitiva è all’interno del contenitore di
applicazioni Zope).
In un ambiente standard orientato agli oggetti, un oggetto eredita il suo comportamento dall’oggetto padre. In
Plone e Zope un oggetto eredita il suo comportamento anche dall’oggetto che lo contiene. Un oggetto attraversa
la gerarchia di contenimento per determinare i suoi comportamenti.
Quindi, prendiamo l’esempio dell’accesso a Members/andrea/Fotografia.jpg. Cosa avviene se l’og-
getto Fotografia.jpg non esiste nella cartella andrea ma esiste più su nella gerarchia? Bene, l’acquisi-
zione lo troverà per noi. Prendiamo la seguente gerarchia:

Members
|_ andrea
|_ Fotografia.jpg

In questo caso, se si esegue l’URL, Plone seguirà il path fino a andrea e poi cercherà di trovare Fotografia.jpg,
inutilmente dato che non esiste in quella cartella. A questo punto Plone cercherà nella gerarchia di contenimento,
che è la cartella Members, dove troverà e restituirà l’oggetto Fotografia.jpg. Il risultato è che l’utente
vedrà l’immagine, come al solito.
Tuttavia, se si confronta questo con l’esempio precedente, dove l’immagine era contenuta nella cartella andrea,
si trovano alcune differenze fondamentali:

1. il contesto è lo stesso, nonostante l’oggetto si trovi in una diversa cartella. Il contesto è dato dalla
posizione dalla quale l’oggetto è chiamato.
2. il contenitore è diverso: il contenitore di Fotografia.jpg è adesso Members, non andrea.

Quindi, quale è la conclusione di tutto questo? Bene, è possibile mettere un oggetto nella cartella principale del
sito Plone e tutti gli oggetti potranno accedervi perché sarà individuato per mezzo dell’acquisizione.
Anche se questo probabilmente ha un senso, l’aquisizione può essere abbastanza complicata, specialmente guar-
dando attraverso la gerarchia del contesto (può succedere). Per approfondire il funzionamento dell’acquisizione
si consiglia l’eccellente discussione sull’argomento dello sviluppatore di Zope Jim Fulton.

5.1.2 Introduzione alle Template Expressions


Prima di avventurarci nel sistema dei modelli di pagina di Zope è necessario capire TALES. Spesso in un appli-
cazione si ha il bisogno di scrivere espressioni che vengano interpretate dinamicamente. Questi non sono script,
piuttosto si tratta di semplici espressioni di una riga (one liners) che possono fare qualcosa di semplice e facile.
Un’espressione è valutata passando ad essa una serie di variabili locali determinate da cosa sta chiamando l’e-
spressione. Il controllo di flusso passa un set di variabili, il sistema dei modelli di pagina Zope Page Template ne
forniscono di ulteriori. Per il momento useremo esempi in cui è definito un contesto. Si ricorda che, come detto,
il contesto è quello in cui l’oggetto viene eseguito.

6
o “indicatore di posizione uniforme di risorse”
118 INDICE

Finora abbiamo incontrate alcune espressioni TALES, come ad esempio string:${portal_url}/Software. Tutta-
via questo è soltanto un esempio di un’ampia varietà di espressioni. Il principale uso delle espressioni TALES
è nei modelli di pagina di Zope, il sistema di generazione dell’HTML di Plone. Nonostante il loro nome possa
suggerire che siano adatti solo ai modelli di pagina, molti strumenti in Plone utilizzano questa sintassi per fornire
semplici espressioni, come ad esempio le azioni, il controllo di flusso, e la sicurazza. Esistono diverse tipologie
di espressioni, le descriveremo una ad una.

Usare le Path Expression

Le Path Expressions sono le espressioni predefinite e le più comunemente utilizzate. Diversamente da tutte le
altre espressioni esse non richiedono un prefisso per specificarne il tipo. L’espressione comprende uno o più
path. Ogni path è separato dal simbolo di barra verticale (|*). Ogni path è una serie di variabili separate dalla
barra obliqua (/). Ecco qualche semplice esempio:

context/message
context/cartella/title
context/Members/andrea/Fotografia.jpg

Quando l’espressione viene valutata il path viene spezzato in corrispondenza della barra obliqua e quindi a partire
dalla parte più a sinistra il path viene attraversato per trovare l’oggetto, il metodo od il valore. Quindi l’oggetto
viene posto sullo stack attuale e la valutazione passa al valore successivo. Questa procedura è ripetuta fintanto che
non viene raggiunta la fine dell’espressione o un valore corrispondente non viene trovato. Se l’oggetto trovato è
un dizionario Python o un mapping object verrà richiamato l’opportuno valore del dizionario. Una funzionalità
interessante delle path expressions è che l’unico carattere riservato è / quindi i nomi possono contenere spazi e
punteggiatura e continuare ad essere valutati.
Quando la fine dell’espressione è raggiunta l’oggetto viene eseguito (se può essere eseguito). Se si tratta di un
oggetto non eseguibile viene restituita la rappresentazione come stringa dell’oggetto. Se in qualsiasi momento
si verifica un errore nella ricerca (il più comune è che l’attributo richiesto non esista) la valutazione passa all’e-
spressione alternativa, se ce n’è una. Le espressioni alternative si possono specificare separandole con una barra
verticale.
Per esempio:

context/cartellaA/title|context/cartellaB/title

L’esempio precedente produce il titolo di cartellaA o il titolo di cartellaB se la prima non esiste. Questo
procedimento è ripetuto per ogni espressione fintanto che non ci sono più espressioni o fino alla prima di esse
che viene valutata con successo.

Usare le Not Expression

Una not expression è introdotta dal prefisso not:: e semplicemente inverte la valutazione dell’espressione TALES
che segue. Visto che nei modelli di pagina di Zope non esiste un operatore if questo tipo di espressioni possono
essere utilizzate per effettuare un test sulla negazione di una condizione.
Per esempio:

not: context/message|nothing
5.1. COMPRENDERE IL MECCANISMO DI MODELLAZIONE SOTTOSTANTE 119

Usare le Nocall Expression

Automaticamente quando una path expression raggiunge l’ultimo elemento del path essa lo esegue, se possibi-
le. Il prefisso nocall: fa si che questo non avvenga. Le nocall expression sono raramente utilizzate in Plone,
ma qualche volta sono utili. Per esempio possono essere utilizzate per riferirsi ad un oggetto e non alla sua
rappresentazione. Un esempio:

nocall: context/immagine

Usare le String Expression

Le string expression permettono di mischiare testo e variabili all’interno di un espressione. Tutte le string ex-
pression sono introdotte dal prefisso string:. Questa è un funzionalità utile e la si vedrà usata abbastanza di
frequente. Il testo può contenere qualsiasi cosa permessa all’interno di un attributo, il che essenzialmente include
i caratteri alfanumerici e lo spazio. All’interno del testo possono esserci nomi di variabili con aggiunto il prefisso
$. Qualche esempio:

string: Questa è una stringa piuttosto lunga


string: Questo è il titolo: $title

Nel secondo esempio la variabile $title viene valutata. La variabile può essere una qualsiasi path expression.
Se il nome della variabile contiene il simbolo / esso deve essere racchiuso tra parentesi graffe {} per identificare
l’inizio e la fine dell’espressione.
Per esempio:

string: Questo è il titolo di una immagine: ${context/unaImmagine/title}.

Per poter utilizzare il simbolo $ bisogna raddoppiarlo, in questo modo:

string: Il prezzo in $$US è ${context/qualcheCosa/cost}.

Usare le Python Expression

Le python expression valutano una riga di codice Python. Tutte le python expression cominciano con il prefisso
python: e contengono una riga di codice Python.
Per esempio:

python: 1 + 2

Il codice Python viene valutato utilizzando lo stesso modello di sicurezza utilizzato per gli oggetti di tipo Script
(Python), come discusso nel Capitolo 6. Per queste ragioni il codice Python deve essere semplice e limitato a
funzionalità di presentazione dei contenuti, come formattazione di stringhe e numeri o valutazione di semplici
condizioni.
In aggiunta, quasi tutte le altre espressioni TALES menzionate possono essere inserite nel codice python ed
eseguite. La sintassi è la seguente:

• path(string): valuta string come una path expression


• string(string): valuta string come una string expression
• exists(string): valuta string come una string expression
120 INDICE

• nocall(string): valuta string come una nocall expression

Per esempio, l’espressione seguente:

python: path(’context/Members’)

è equivalente a questa:

context/Members

Sono state aggiunte alcune convenienti funzioni per assistere gli sviluppatori. La funzione test accetta tre pa-
rametri: una espressione che esprime la condizione da valutare e le alternative per il caso di condizione vera o
falsa. La condizione viene valutata e viene restituito l’appropriato valore. Per esempio:

python: test(1 - 1, 0, 1)

La funzione same_type accetta due parametri e controlla che essi siano dello stesso tipo. Per esempio:

python: same_type(qualchecosa, ’’)

Alcuni sviluppatori scoraggiano l’uso di Python all’interno dei modelli di pagina di Zope perché questa pratica
implica l’incorporazione della logica dell’applicazione all’interno dei modelli di presentazione. Spesso, come
sviluppatori, per ogni pezzo di codice Python aggiunto, è utile chiedersi se questo pezzo di codice non sia meglio
estrarlo ed inserirlo in un oggetto Script (Python) separato. Questo non significa che ogni pezzo di Python debba
essere rimosso, semplicemente è bene riflettere prima di aggiungerlo.

Sito web del Manuale: Rispolveriamo le Azioni

Nel Capitolo 4 abbiamo aggiunto una azione che punta alla sezione Software del sito in modo che essa appaia co-
me una scheda del portale. Nelle action si è aggiunta questa string expression: string: ${portal_url}/Software.
Ora che abbiamo spiegato il significato della variabile portal_url questa espressione ha un po’ più di senso. Que-
sto è l’URL al portale, che può variare se stiamo usando un sistema di virtual hosting. L’espressione utilizza
l’acquisizione per ottenere l’oggetto portal_url ed inserire il valore risultante nella stringa. Il risultato è che
si ottiene sempre un collegamento assoluto alla cartella Software.

Errori da principianti: mescolare Python e stringhe

I principianti tendono talvolta a mescolare Python e stringhe. Tutte le espressioni sono differenti. In altre parole
non è possibile inserire costrutti simili alle path expression all’interno di una Python expression. Per esempio
l’espressione python: here/Members + “/danae” non ha significato. L’intera espressione è interpretata come
Python quindi Plone proverà a dividere here per Members e incapperà in errori. Questa è invece la circostanza
ideale per usare un string expression, che permette di effettuare la sostituzione delle variabili che possono essere
anche path expression. Quindi si può usare l’espressione string: ${here/Members}/danae.

5.2 Usare il sistema dei modelli di pagina Zope Page Templates


Adesso che abbiamo capito la pubblicazione degli oggetti e le espressioni possiamo veramente addentrarci all’in-
terno del sistema dei modelli di pagina Zope Page Templates. Questo è il sistema che Plone utilizza per generare
l’HTML.
5.2. USARE IL SISTEMA DEI MODELLI DI PAGINA ZOPE PAGE TEMPLATES 121

Sono disponibili molti sistemi di generazione dell’HTML, alcuni dei più conosciuti sono JavaServer Pages, Active
Server Pages, e PHP. Se si utilizzano gli altri sistemi quello dei modelli di pagina di Zope sembra inizialmente
bizzarro ma presto si scopre che è un sistema molto potente.
Il modello più semplice è qualcosa che assomiglia al seguente:

<p tal:content="here/messaggio">Questo è il titolo</p>

Se il valore della variabile messaggio si risolve in Buongiorno, mondo! quando il modello viene interpretato
viene generato il seguente testo:

<p>Buongiorno, mondo!</p>

Tralasciando per il momento alcuni dettagli analizziamo cosa è successo. È stato scritto un comune paragrafo in
HTML ma il contenuto del paragrafo nel sorgente non è quello ottenuto come output. Al marcatore di apertura del
paragrafo è stato aggiunto un attributo tal:content e l’espressione here/messaggio è stata specificata come valore
dell’attributo. Nell’output il contenuto del paragrafo è stato sostituito con il valore della variabile, in questo caso
Buongiorno, mondo!.
Al momento dell’esecuzione il modello viene interpretato e l’attributo tal:content eseguito. Il prefisso tal sta
per Template Attribute Language e permette di utilizzare alcuni comandi, incluso il comando content. Con tutti
questi comandi, che si descriveranno in seguito, è possibile fare praticamente ogni cosa si desideri ai marcatori
HTML. È possibile creare iterazioni, modificare i marcatori, modificare gli attributi, rimuovere marcatori e altro
ancora. Prima che il modello venga interpretato il modello stesso è un documento che rispetta lo standard
7
Extensible HTML (XHTML) quindi in un editor verrà visualizzato come un paragrafo con quel testo.
Tutti i modelli di pagina sono XHTML validi. Questo è uno standard per l’HTML che rispetta le specifiche
Extensible Markup Language (XML)8. Questo significa che esso deve sottostare a queste regole:

• Tutti i marcatori devono essere minuscoli.


• Gli attributi devono sempre essere tra apici. Per esempio <input type=“checkbox” checked=“1” />.
• Gli elementi vuoti devono essere terminati. Per esempio <br /> e non <br>.

Per definire una pagina come XHTML è necessario fornire una dichiarazione del DOCTYPE e specificare lo spazio
dei nomi XML con il marcatore html. Plone utilizza la seguente dichiarazione in cima ad ogni pagina:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

Per maggiori informazioni su XHTML consultare le specifiche.

5.2.1 Un altro sistema di generazione dell’HTML?


Nei primi anni del Web erano i programmatori i creatori dell’HTML ed essi rapidamente misero assieme dei
sistemi per generare automaticamente l’HTML in modo da potersi concentrare sul loro vero lavoro. Con questi
strumenti, come ad esempio i moduli CGI del Perl, i programmatori poterono scrivere complicati programmi
lato server per la gestione dei contenuti.

7
letteralmente “HTML estensibile”
8
letteralmente “linguaggio estensibile di demarcazione”
122 INDICE

Tuttavia, presto ognuno cominciò a scrivere contenuti e questi processi dovevano essere semplificati. Questo ha
determinato la nascita di molti linguaggi dove il codice è mischiato all’HTML, delimitato da speciali marcatori.
I linguaggi interpretavano il codice contenuto tra i marcatori per produrre il risultato desiderato. Come menzio-
nato, alcuni di questi sono Active Server Pages, JavaServer Pages, e persino interi linguaggi di programmazione
basati su questo concetto, come PHP. Zope ha seguito questa tendenza creando il Document Template Markup
Language o DTML.
Questi sistemi prendevano l’HTML e sparpagliavano in esso marcatori personalizzati come ad esempio <% ...
%> o <dtml-... />. Questo sistema divenne popolare perché è di facile comprensione e gli utenti che già cono-
scono le basi dell’HTML possono ben padroneggiare l’idea di qualche marcatore aggiuntivo. I grafici possono
ignorare il contenuto di questi marcatori e lasciare i programmatori ad occuparsi di essi. I programmatori possono
modificare le parti di codice senza modificare i contenuti.
Tuttavia questi sistemi presentano i seguenti problemi:

• I modelli HTML possono diventare difficili da gestire man mano che maggiori contenuti sono aggiunti allo
script. Le pagine diventano rapidamente enormi e difficili da gestire.
• La logica ed i contenuti non sono nettamente separati. Essi possono essere separati con alcuni di questi
sistemi, tuttavia la possibiltà di sparpagliare pezzi di HTML in ogni pezzo di programma è troppo facile.
Spesso contenuti, presentazione e logica diventano un grande ed intricato garbuglio.
• Le pagine non possono essere modificate facilmente. Spesso le pagine o i modelli sono forniti con l’an-
notazione “non toccare questi pezzi...” perché le modifiche potrebbero compromettere il funzionamento
del programma. Gli editor What You See Is What You Get 9 (WYSIWYG) possono essere impostati per
non modificare alcuni marcatori ma altri possono essere compromessi. In grandi organizzazioni utenti con
diversi ruoli devono modificare la medesima pagina.
• Può essere difficile ottenere un risultato predefinito. Prendiamo, ad esempio, una richiesta ad una base
di dati che mostri i risultati in una tabella. Come può un grafico vedere come sarà questa tabella senza
eseguire il codice?

Per queste ragioni è stato creato il sistema di modelli di pagina Zope. I page template rappresentano un innovativo
approccio; invece che fornire un nuovo sistema di escape coding, il codice viene aggiunto agli attributi dei
marcatori esistenti. Non solo il sistema dei Zope Page Templates è libero ed open source, esso non richiede
nemmeno Zope. Al momento esistono realizzazioni di questo sistema in Python, Perl e Java.

5.2.2 Introduzione a modelli di pagina e contenuto


Abbiamo imparato che Plone è un sistema di gestione dei contenuti in cui gli utenti aggiungono contenuti al
sito Plone attraverso il Web. Gli oggetti che rappresentano i contenuti sono conservati all’interno di Plone e
visualizzati al mondo attraverso i modelli di pagina.
Ritornando al precedente esempio dell’accesso a /Members/andrea/Fotografia.jpg discuteremo ora
cosa effettivamente succede al contenuto di Plone. Per prima cosa Plone cerca ed esegue l’oggetto Fotografia.jpg;
l’oggetto viene eseguito perché non è stato specificato nessun metodo specifico da richiamare. Quando un con-
tent type è eseguito un determinato modello viene localizzato ed interpretato. Il contesto per tale modello sarà
l’immagine a cui si vuole accedere ed il modello sarà quello associato all’immagine.
Se è stata richiamata sull’immagine una differente azione, ad esempio Members/andrea/Fotografia.jpg/image_e
l’azione image_edit associata a questo oggetto verrà localizzata e il corrispondente modello verrà restituito.
Il Capitolo 11 tratta di come questo avviene in maggiore dettaglio.

9
letteralmente “quello che vedi è quello che ottieni”
5.2. USARE IL SISTEMA DEI MODELLI DI PAGINA ZOPE PAGE TEMPLATES 123

In tutti i modelli di pagina, all’interno di Plone, si troveranno riferimenti a here o context. Questo è il contesto
del contenuto a cui si sta accedendo. In un modello è possibile quindi riferirsi a context/questo o quello e questo
o quello verrà localizzato relativamente al pezzo di contenuto, non al modello. Andiamo quindi a creare il nostro
primo modello in Plone.

5.2.3 Creazione del primo modello di pagina


Il metodo standard per creare un modello di pagina è utilizzare la Zope Management Interface (ZMI)10. Sfor-
tunatamente la ZMI è scomoda da usare per uno sviluppatore, visto che questo implica modificare il modello
tramite una area di testo nel proprio browser Web. L’area di testo fornisce limitate funzionalità rispetto alla mag-
gior parte degli editor; manca di funzionalità quali la numerazione delle righe, l’evidenziazione delle sintassi, e
così via. Nel ‘Capitolo 9‘_ si vedrà come utilizzare l’External Editor per modificare i contenuti; questo permette
di modificare i contenuti del sito Web in un editor locale come Macromedia Dreamweaver o Emacs. Nel Capi-
tolo 6 si vedrà come far leggere a Plone i modelli di pagina dal disco fisso come file, si potrà quindi utilizzare
qualsivoglia strumento per modificarle.
Per creare un modello di pagina, si acceda alla ZMI, si selezioni portal_skins, successivamente si selezioni
custom e quindi di si scelga l’opzione Page Template dal menù a tendina come in figura 5-1. Si prema quindi
Add e si vedrà la pagina mostrata in figura 5-2.

Figura 5.1: Figura 5-1. Scelta dell’opzione Page Template

Si immetta test come ID per il modello di pagina. Si prema dunque il pulsante Add and Edit che porterà alla
pagina di amministrazione mostrata in figura 5-3. Si può quindi modificare il modello tramite il Web utilizzando
l’area di testo e premere il pulsante Save Changes per memorizzare le modifiche.

Nota
Nelle versioni di Plone precedenti Plone 2 in tutte i modelli di pagina era definita la variabile
here, equivalente alla variabile context. Se si trova here in qualsiasi parte di un modello di
pagina il suo significato è lo stesso di context. La nuova variabile context è stata aggiunta
per maggior chiarezza e per allineare i modellidi pagina agli oggetti Script (Python).
124 INDICE

Figura 5.2: Figura 5-2. Aggiunta un modello di pagina

Figura 5.3: Figura 5-3. Modifica del modello di pagina


5.2. USARE IL SISTEMA DEI MODELLI DI PAGINA ZOPE PAGE TEMPLATES 125

Alla pressione del pulsante Save Changes il modello di pagina viene interpretato. Se è stato commesso qualche
errore nel modello lo si vedrà evidenziato in cima alla pagina. La Figura 5-4 mostra un errore: un marcatore h1
non è stato chiuso. (Come precedentemente menzionato i modelii di pagina devono contenere codice XHTML
corretto).

Figura 5.4: Figura 5-4. Errore nel modello di pagina

Una volta che si è correttamente salvato il modello di pagina, è possibile accedere alla scheda Test per vederlo
interpretato. Nella Figura 5-5 si vede come l’intestazione sia stata sostituita dall’ID del modello e come il
paragrafo principale adesso includa l’ID del modello di pagina.

La finestra di amministrazione di un modello di pagina ha anche le seguenti importanti funzionalità:

Title: il titolo per il modello, è opzionale. Se si modifica, nel precedente esempio, si nota come nella scheda
Test l’HTML risultante sia diverso.

Content-Type: il tipo di contenuto del modello, solitamente text/html.


Browse HTML source: restituisce il modello di pagina non interpretato come testo HTML, così come appari-
rebbe se il modello venisse aperto in un editor HTML.
Test : mostra il modello di pagina interpretato.
Expand macros when editing: opzione che fa si che il sistema provi ad espandere le macro. Si raccomanda di
mantenere questa opzione non selezionata nella maggior parte dei casi. Le macro sono una funzionalità
avanzata e verranno discusse nel Capitolo 6.

Adesso che si è creato un modello di pagina, lo modificheremo un po’. Questo dimostrerà gli argomenti esposti
sin qui in questo capitolo. Per esempio se si vuole provare a far eseguire al modello di pagina l’operazione 1+2
aggiungeremo al modello la seguente riga:

<p>1+2 = <em tal:content="python: 1+2" /></p>

Quindi accediamo alla scheda Test per verificare se funziona. Si dovrebbe ottenere quanto segue:
126 INDICE

Figura 5.5: Figure 5-5. Generazione della pagina

1+2 = 3

Per vedere un esempio di attraversamento del percorso (path traversal), mostriamo il logo del sito Plone. È
possibile includere il logo del sito Plone aggiungendo un’espressione di questo tipo al modello di pagina:

<p tal:replace="structure context/logo.jpg" />

Questo crea l’HTML appropriato per includere l’immagine e la mostrerà nella pagina.

5.3 Capire la sintassi di base dei modelli di pagina


Adesso che abbiamo visto come creare un modello di pagina spieghiamo la sua sintassi di base. È possibile
dividere la sintassi dei modelli di pagina in poche differenti componenti, che descriveremo nei paragrafi seguenti.

5.3.1 Introduzione alle variabili Built-in


Abbiamo visto la sintassi delle espressioni, ora studiamo le variabili che sono passate ad esse quando il modello
di pagina viene interpretato. Quanto segue avviene accedendo all’immagine Fotografia.jpg nella cartella
Members/andrea, attraverso l’URL /Members/andrea/Fotografia.jpg/.

container questo è il contenitore in cui il modello di pagina è stato localizzato. Solitamente in Plone si trat-
ta della cartella portal_skins. Si dovrebbe evitare di utilizzare questa variabile perché l’oggetto
portal_skins può fare cose inaspettate al significato del contenitore (per esempio potrebbe riferirlo
alla cartella andrea).
context questo è il contesto nel quale il modello viene interpretato. In Plone questo è l’oggetto che è corrente-
mente visualizzato, se si sta visualizzando un oggetto del portale (per esempio un riferimento all’oggetto
Fotografia.jpg).

10
letteralmente “interfaccia di amministrazione di Zope”
5.3. CAPIRE LA SINTASSI DI BASE DEI MODELLI DI PAGINA 127

default qualche espressione ha dei particolari valori predefiniti, documentati separatamente per ogni espressio-
ne. Questa variabile è un puntatore a quel particolare valore.

here equivalente a context.


loop equivalente a repeat.
modules questo è il contenitore per i moduli importati. Per esempio modules/strings/atoi è la funzione
atoi del modulo Python strings. Include tutti i moduli che è sicuro importare all’interno del sistema
dei modelli di pagina di Zope. Per maggiori informazioni vedere il paragrafo Scripting Plone con Python
nel Capitolo 6.
nothing equivalente di None in Python.
options opzioni passate al modello di pagina, definite solo quando il modello è richiamato da uno script o
attraverso un altro metodo, non attraverso il Web.
repeat l’elemento ripetuto; si veda l’elemento tal:repeat nel paragrafo Introduzione alla sintassi delle espres-
sioni TAL di questo capitolo.
request richiesta inviata dal client (tutti i valori della richiesta sono visionabili utilizzando lo script test_context
sotto riportato). Tutti i parametri passati attraverso i metodi GET o come POST sono ordinati in un
dizionario per un facile accesso. Qualche esempio:
request/HTTP_USER_AGENT # il browser usato dall’utente
request/REMOTE_ADDR # l’indirizzo del computer dell’utente
request/someMessage # il valore di qualche messaggio, nella
# stringa di interrogazione

root : l’oggetto principale Zope. Per esempio root/Control_Panel restituisce il pannello di controllo di Zope.
template: il modello correntemente interpretato. Per esempio template/id da l’ID del modello attualmente
visualizzato.
traverse_subpath : contiene una lista degli elementi che devono ancora essere attraversati. Questa è una varia-
bile avanzata e si raccomanda di utilizzarla solo una volta compreso il meccanismo di attraversamento ed
acquisizione.
user: l’oggetto utente corrente. Per esempio user/getUserName da il nome utente dell’utente corrente.
CONTEXTS : l’elenco di molte di queste variabili.

Nota
Con l’eccezione di CONTEXTS tutte queste variabili possono essere ridefinite a piacimen-
to in un’espressione tal:define. Tuttavia questo può portare confusione in tutti quelli che
utilizzeranno il codice e non è quindi raccomandato.

Il modello di pagina test_context mostra tutti valori di queste variabili oltre che alla posizione di alcuni
oggetti (vedere il Listato 5-1). Può essere utile per scovare eventuali errori o comprendere meglio il significato
delle variabili. Aggiungiamolo come modello di pagina chiamata test_context quindi accediamo alla scheda Test
per vedere il risultato.
Listato 5-1. test_context
128 INDICE

<html>
<head />
<body>
<h1>Debug information</h1>
<h2>CONTEXTS</h2>
<ul>
<tal:block
tal:repeat="item CONTEXTS">
<li
tal:condition="python: item != ’request’"
tal:define="context CONTEXTS;">
<b tal:content="item" />
<span tal:replace="python: context[item]" />
</li>
</tal:block>
</ul>
<h2>REQUEST</h2>
<p tal:replace="structure request" />
</body>
</html>

Il modello di pagina test_context produce il risultato mostrato in Figura 5-6.

5.3.2 Introduzione alla sintassi delle espressioni TAL


Il Template Attribute Language (TAL) fornisce tutti i pezzi necessari alla creazione di una rappresentazione
dinamica. TAL definisce otto istruzioni: attributes, condition, content, define, omit-tag, on-error, repeat and
replace.
Siccome i modelli di pagina sono documenti XML validi tutti gli attributi TAL devono essere in lettere minuscole
e ogni elemento può aver associato ogni istruzione una solo volta. Negli esempi che seguono si sono inseriti
dei ritorni a capo all’interno delle definizioni degli elementi per migliorare la leggibilità del codice; questo non
compromette la validità del codice ed è abbastanza comune nei sorgenti di Plone. Tuttavia è opzionale e non è
richiesto.

tal:attributes: modificare gli attributi di un elemento

L’istruzione tal:attributes permette di rimpiazzare uno o più attributi di un elemento. Un’istruzione contiene
il nome dell’attributo da modificare e, separata da uno spazio, l’espressione che specifica il suo valore. Per
esempio:

<a href="#"
tal:attributes="href context/absolute_url">
Qui c’è il Link
</a>

Questo assegna all’attributo href del collegamento il valore del risultato dell’interpretazione di here/absolute_url.
L’attributo href è stato già definito su questo elemento in modo che un grafico, aprendo questa pagina, ve-
da un elemento corretto (anche se il collegamento potrebbe non avere senso fintanto che il modello non viene
interpretato). Un esempio di risultato dato della valutazione del modello è il seguente:

<a href="http://plone.org/Members/andy/book">Qui c’è il Link</a>


5.3. CAPIRE LA SINTASSI DI BASE DEI MODELLI DI PAGINA 129

Figura 5.6: Figura 5-6. Un esempio di tutte le varibili definite in uno script
130 INDICE

Dato che ogni elemento può avere più attributi, tal:attributes permette di modificarne uno o più simultaneamente
specificando più espressioni. Per modificare più attributi in un sol colpo le espressioni vanno separate con un
punto e virgola (;). Se gli attributi o i valori da inserire contengono un punto e virgola esso va quotato inserendone
un’altro immediatamente dopo (;;). Per esempio, per modificare entrambi gli attributi href e title dell’elemento
procediamo come segue:

<a href="#"
tal:attributes="href context/absolute_url;
title context/title_or_id">Link</a>

Un esempio di risultato ottenuto è il seguente:

<a href="http://plone.org/Members/andy/book" title="Plone Book">Link</a>

Le istruzioni tal:attributes e tal:replace sono mutuamente esclusive in quanto replace elimina l’elemento su
cui agisce. Se il sistema dei modelli di pagina di Zope si accorge che su un elemento sono state utilizzate le due
istruzioni mostra un messaggio di avvertimento e ignora l’attributo tal:attributes. Se l’espressione indicata per
il valore di un attributo restituisce il valore default allora nessuna modifica è apportata. Per esempio:

<a href="#"
tal:attributes="href python:request.get(’message’, default)">
Link
</a>

In questo esempio si utilizza la funzione get dell’oggetto request. Se la richiesta avanzata alla pagina contiene la
variabile message allora il primo valore viene utilizzato, se la variabile message non è presente viene utilizzato
il secondo valore, default. Quindi solo specificando il parametro message la modifica ha luogo.

tal:condition: valutare condizioni

L’istruzione tal:condition permette di verificare una condizione prima di intepretarne un elemento. Per esempio:

<p tal:condition="request/message">
C’è un messaggio
</p>
<p tal:condition="not: request/message">
Nessun messaggio
</p>

Il paragrafo con il testo per un messaggio viene visualizzato solo se la variabile request ha un un attributo
message ed il suo valore è vero (per esempio: la lunghezza della stringa è maggiore di zero). Avere la possibilità
di verificare una condizione è inutile se non può essere verificata la condizione opposta; questo è possibile grazie
all’espressione not:. Il prefisso not: inverte l’espressione, così not: request/message è interpretato come vero
solo se l’attributo message della variabile request è falso (per esempio: la lunghezza della stringa è zero). In
questo caso l’attributo message dell’oggetto request deve comunque esistere.
In TAL sono interpretati come falsi:

• il numero zero
• qualsiasi numero complesso o float che indica zero (per esempio 0.0)
• stringhe di lunghezza nulla (per esempio “”)
5.3. CAPIRE LA SINTASSI DI BASE DEI MODELLI DI PAGINA 131

• una lista o una tupla vuote

• un dizionario vuoto
• il valore None di python
• il valore nothing di TALES

mentre sono interpretati come veri:

• il valore default

• qualsiasi numero diverso da zero


• stringhe di lunghezza non nulla
• stringhe composte di soli spazi (per esempio “ ”)
• qualsiasi altra cosa

tal:content : aggiungere del testo

L’istruzione tal:content è probabilmente la più usata in un modello di pagina. Questa istruzione è anche una
delle più semplici, rimpiazza il contenuto di un elemento con il valore specificato. Per esempio:

<i tal:content="context/title_or_id">Qualche titolo</i>

Il risultato di esempio è il seguente:

<i>Un determinato titolo</i>

Il testo Qualche titolo è rimpiazzato con il valore dell’espressione context/title_or_id. Se il testo da inserire
contiene elementi HTML essi verranno quotati; il prefisso structure permette di inserire elementi HTML senza
che essi siano quotati. Per esempio:

<i tal:content="structure here/title_or_id">Do not escape HTML</i>

Se l’elemento a cui è applicato l’attributo tal:content contiene altri elementi, tutti essi verranno rimpiazzati.
Gli attributi tal:content e tal:replace sono mutuamente esclusivi; non possono essere assegnati entrambi allo
stesso elemento, verrà segnalato un errore se si prova a farlo. Se il valore dell’attributo tal:content è default il
contenuto dell’elemento non viene modificato.

tal:define: definire variabili

L’istruzione tal:define permette di creare variabili che potranno essere utilizzate all’interno del modello. Per
esempio:

<p tal:define="title here/title_or_id">


... <i tal:content="title">Titolo</i> ...
</p>
132 INDICE

In questo esempio la variabile title è creata assegnandovi il risultato dell’espressione here/title_or_id; successi-
vamente la variabile title è utilizzata in un’istruzione tal:content. Se non diversamente specificato la variabile
è creata solo localmente con visibilità limitata all’elemento corrente. Nel precedente esempio, quindi, solo gli
elementi interni al marcatore p possono utilizzare la variabile title. È possibile ridefinire la variabile dovunque
all’interno dell’istruzione o utilizzarla in altri elementi quante volte si necessita.
Per creare una variabile utilizzata globalmente è possibile utilizzare il prefisso global. Questo permette di acce-
dere alla variabile da qualsiasi parte del modello, non solamente all’interno dell’elemento che la definisce. Per
esempio:

<p tal:define="global title string:Foo bar">


... <i tal:content="title">Titolo</i> ...
</p>
<i tal:content="title">Anche qui abbiamo un titolo</i>

Inoltre Plone incorpora un gran numero di definizioni globali in modo che gli utenti possano usarle semplice-
mente nei loro script. Siccome ognuna di queste definizioni può essere soggetta a modifiche si raccomanda di
utilizzare tali variabili con occulatezza. Queste definizioni mettono a disposizione un gran numero di variabili
globali. Per esempio, per ottenere il titolo del sito Plone, è possibile semplicemente usare quanto segue:

<p tal:content="portal_title" />

È possibile trovare queste definizioni nella ZMI selezionando portal_skins, quindi plone_templates ed infi-
ne global_defines. Si trova un elenco completo di tutte le definizioni e una spiegazione del loro significato
nell’‘Appendice A‘_.

tal:omit-tag: rimuovere elementi

L’istruzione tal:omit-tag è poco comune. Essa permette di rimuovere un marcatore. Dato che il sistema di
modelli di pagina di Zope richiede l’uso di marcatori HTML, pagine complicate possono richiedere spesso l’uso
di molti elementi che possono portare all’aggiunta di marcatori non necessari. Utilizzando questa istruzione il
marcatore a cui è applicata è rimosso lasciandone solo il contenuto. Per esempio:

<p tal:omit-tag="">Questo è un testo</p>

Il risultato è il seguente:

Questo è un testo

In questo esempio viene visualizzato Questo è un testo mentre il marcatore è stato omesso. Opzionalmente
come argomento può essere specificata un’espressione. Se l’espressione viene interpretata come falsa allora
l’istruzione tal:omit-tag non ha effetto. Per esempio, questo non fa nulla:

<p tal:omit-tag="nothing">Questo è un testo</p>

Un’alternativa all’istruzione tal:omit-tag è l’uso dello spazio dei nomi tal come illustrato nel paragrafo Consigli
utili del Capitolo 6.
5.3. CAPIRE LA SINTASSI DI BASE DEI MODELLI DI PAGINA 133

tal:on-error: effettuare la gestione degli errori

L’istruzione tal:on-error fornisce un metodo per gestire gli errori. Essa agisce in modo simile all’istruzione
tal:content, anch’essa produce la sostituzione del contenuto dell’elemento a cui è applicata, ma è attivata solo
quando accade un errore.
Il seguente è un esempio:

<p tal:content="request/message"
tal:on-error="string: Nessun messaggio">Testo messaggio</p>

Se c’è un errore interpretando l’espressione request/message allora l’attributo tal:on-error è attivato. Questo
causa il rimpiazzo del contenuto dell’elemento con il testo Nessun messaggio.
Sfortunatamente l’istruzione on-error è piuttosto limitata. Non può distinguere tra differenti errori e permette
di specificare una sola istruzione da interpretare. Questa limitazione è voluta per evitare un abuso di questa
istruzione. La gestione degli errori deve essere effettuata nella logica dell’applicazione.
Fortunatamente, per tutti gli argomenti delle istruzioni, è possibile fornire un’alternativa alla prima espressione,
se essa viene interpretata con qualcosa diverso da vero o falso (in altre parole, se si incorre in un errore). Ogni
alternativa è separata da una barra verticale (|), più alternative possono essere fornite per un’istruzione. Se si fa
affidamento su variabili definite nella richiesta inoltrata si aggiunga sempre un’alternativa |nothing alla fine per
assicurarsi che non venga segnalato un errore di tipo AttributeError.
Per esempio:

<p
tal:content="request/message"
tal:condition="request/message|nothing">
C’è un messaggio
</p>
<p tal:condition="not: request/message|nothing">
Nessun messaggio
</p>

Questo secondo esempio è più prolisso ma preferibile per un paio di ragioni:

• il grafico può vedere sia l’alternativa per la condizione positiva, sia quella per la condizione negativa
• è possibile gestire gli errori in maniera più complessa che semplicemente visualizzando una stringa

tal:repeat: realizzare iterazioni

L’istruzione tal:repeat permette di iterare su oggetti ed è una delle istruzioni più complicate. Un’istruzione
contiene il nome della variabile alla quale assegnare l’elemento corrente per ogni iterazione, separata da uno
spazio dall’espressione che restituisce i valori su cui iterare.
Un esempio di iterazione:

<table>
<tr tal:repeat="row context/portal_catalog">
<td tal:content="row/Title">Titolo</td>
</tr>
</table>
134 INDICE

In questo esempio l’espressione here/portal_catalog restituisce un elenco di risultati. Siccome l’iterazione


comincia sull’elemento che specifica la riga della tabella, per ogni elemento nell’elenco dei risultati viene creata
una nuova riga nella tabella. Similmente a tal:define ad ogni iterazione un nuovo elemento dell’elenco viene
assegnato ad una variabile locale (in questo caso la variabile row). Questo esempio mostra una riga per ogni
elemento dell’elenco dei risultati.
È possibile accedere ad alcune utili variabili all’interno dell’istruzione tal:repeat. Queste varibili sono accessibili
attraverso l’oggetto repeat, che viene aggiunto al namespace. Per esempio, per accedere all’indice corrente, si
utilizza il seguente codice:

<table>
<tr tal:repeat="row context/portal_catalog">
<td tal:content="repeat/row/number">1</td>
<td tal:content="row/Title">Titolo</td>
</tr>
</table>

La lista completa delle variabili accessibili tramite l’oggetto repeat è la seguente:

index l’indice di iterazione, a partire da zero.


number l’indice di iterazione, a partire da uno.
even questa variabile è vera se l’indice di iterazione è pari (ad esempio 0, 2, 4, ...).
odd questa variabile è vera se l’indice di iterazione è dispari (ad esempio 1, 3, 5, ...).
start questa variabile è vera per la prima iterazione.
end questa variabile è vera per l’ultima iterazione.
lenght il numero totale di iterazioni.
letter l’indice di iterazione espresso con una lettera minuscola (ad esempio a-a, aa-az, ba-bz, ... za-zz, aaa-
aaz, e così via), a partire da uno.
Letter versione maiuscola della variabile letter
roman l’indice di iterazione espresso in numeri romani (ad esempio i, ii, iii, iv, v, e così via), a partire da uno.

Attraverso l’oggetto repeat sono accessibili anche le variabili first e last, piuttosto insolite e raramente utilizzate.
Queste due variabili permettono di memorizzare informazioni sui dati nell’iterazione. Utilizzando i valori che si
vogliono memorizzare in un’espressione un valore booleano è restituito.
Questo ne è un esempio:

<ul>
<li tal:repeat="val context/objectValues">
First: <i tal:content="repeat/val/first/meta_type" />,
Last: <i tal:content="repeat/val/last/meta_type" />:
<b tal:content="val/meta_type" />,
<b tal:content="val/title_or_id" />
</li>
</ul>
5.3. CAPIRE LA SINTASSI DI BASE DEI MODELLI DI PAGINA 135

tal:replace: aggiungere del testo

L’istruzione tag:replace è simile all’istruzione tal:content, con una differenza: rimuove il tag.
Per esempio:

<p tal:replace="context/title_or_id">Some title</p>

Questo visualizza il risultato dell’espressione context/title_or_id ma rimuove il tag p dal risultato. È equivalente
al codice che segue:

<p
tal:content="here/title_or_id"
tal:omit-tag="">Some title</p>

Se l’elemento a cui è applicato l’attributo tal:replace contiene altri elementi allora tutti gli elementi contenuti
verrano rimpiazzati. Non è possibile utilizzare l’istruzione tal:replace assieme all’istruzione tal:attributes o
all’istruzione tal:content; sono mutuamente esclusive e viene segnalato un errore se si provano ad assegnare allo
stesso elemento.

5.3.3 Introduzione all’ordine di esecuzione


L’ordine con cui le istruzioni TAL sono scritte non è l’ordine in cui esse sono interpretate perché esse sono real-
mente elementi XML (e l’XML non rispetta l’ordine degli attributi). L’ordine in cui le istruzioni sono interpretate
è il seguente:

1. define
2. condition
3. repeat
4. content
5. replace
6. attributes
7. omit-tag

Non è possibile utilizzare le istruzioni content e replace sullo stesso elemento perché esse sono mutuamente
esclusive. Utilizzando l’istruzione attributes sullo stesso elemento insieme replace o omit-tag non ha signifi-
cato in quanto gli attributi vengono rimossi. L’attributo on-error non è menzionato nell’elenco perché esso è
interpretato non appena si incappa nel primo errore in qualsiasi degli elementi elencati.

5.3.4 Esempio: visualizzare informazioni sull’utente


Per illustrare gli argomenti sin qui trattati procediamo adesso con la creazione di un modello di pagina che esegue
un semplice compito: mostrare le informazioni che riguardano un utente del sistema.
In questo esempio un’azienda utilizza internamente Plone come intranet. Ogni dipendente è registrato all’interno
di Plone e possiede una login; tuttavia non c’è una semplice pagina che mostri i dipendenti o come contattarli.
Creeremo una semplice pagina di informazioni sull’utente che mostri l’indirizzo e-mail, l’home page, una foto,
e l’ora dell’ultimo login.
136 INDICE

Il primo prototipo di questa pagina è facilmente realizzato con TAL, TALES e un po’ di conoscenza delle funzio-
nalità di base degli strumenti Content Management Framework (CMF). Sfortunatamente, visto che le Application
Management Interfaces (API) per questi strumenti sono abbastanza complesse, parte del codice risulterà più lun-
go di quanto non dovrebbe essere. A questo livello non ci si preoccupi troppo dell’API; verrano descritte più
approfonditamente nel ‘Capitolo 9‘_. Si dia per il momento l’API per scontata e ci si concentri sul TAL.
Per prima cosa creiamo un modello di pagina; selezioniamo portal_skin, quindi custom*, aggiungiamo un
modello di pagina dandogli “ID“ **user_info modificandolo infine come indicato di seguito. Per il listato
completo del modello di pagina consultare l’‘Appendice A‘_. Esaminando il listato completo si vede che esso
comincia con i marcatori html e body.
Per comodità si raggruppano le principali definizioni in un marcatore div:

<div
tal:omit-tag=""
tal:define="
userName request/userName|nothing;
userObj python: here.portal_membership.getMemberById(userName);
getPortrait nocall: here/portal_membership/getPersonalPortrait;
getFolder nocall: here/portal_membership/getHomeFolder
">

In questo marcatore div ci sono quattro definizioni: una per ottenere il nome utente ricevuto attraverso la richiesta
del client e una per convertire il nome utente in un oggetto di tipo utente. Le ultime due definizioni assicurano di
avere dei riferimenti validi ai metodi che restituiscono la foto dell’utente e la sua cartella personale; queste sono
nuovamente delle definizioni di convenienza che servono per rendere il codice che segue più semplice. Utilizzare
un marcatore div, o qualche altro marcatore simile a questo, che raccolga una serie di definizioni, è una procedura
comune all’interno del sistema dei modelli di pagina di Zope. Esso semplicemente mantiene ordine all’interno
del codice.
Successivamente inseriamo due semplici condizioni per assicurarci che un utente sia definito:

<p tal:condition="not: userName">


Non è stato selezionato alcun nominativo.
</p>
<p tal:condition="not: userObj">
Il nominativo selezionato non esiste.
</p>

Se nessun nome utente è stato specificato nella richiesta, allora l’espressione request/username|nothing assegna
alla variabile userName il valore nothing e quindi il test fallisce. In più se il nome utente non è valido la variabile
userObj risulterà None e un messaggio di errore verrà visualizzato per entrambe queste condizioni.
Adesso siamo pronti per visualizzare le informazioni sull’utente:

<table tal:condition="userObj">
<tr>
<td>
<img src=""
tal:replace="structure python: getPortrait(userName)" />
</td>

Siccome è possibile visualizzare le informazioni relative all’utente solo se un utente è stato trovato, ce ne as-
sicuriamo con una semplice condizione applicata alla tabella: tal:condition=“userObj”. Per visualizzare una
foto dell’utente, utilizziamo il metodo getPortrait precedentemente definito. Questa funzione restituisce l’HTML
5.3. CAPIRE LA SINTASSI DI BASE DEI MODELLI DI PAGINA 137

completo necessario a visualizzare l’immagine: per questo il marcatore structure assicura che esso sia corretta-
mente visualizzato. In aggiunta vogliamo visualizzare alcune proprietà come name ed email. Il codice seguente
visualizza una di queste, restituendo la cartella home:

<li
tal:define="home python: getFolder(userName)"
tal:condition="home">
<a href=""
tal:attributes="href home/absolute_url"
>Cartella personale</a>
</li>

Per prima cosa si utilizza un define per assegnare l’oggetto che rappresenta la cartella personale dell’utente alla
variabile home. In un sito Plone creare una cartella personale per gli utenti è opzionale, quindi è necessario
controllare che la cartella esista prima di visualizzare un collegamento ad essa. Fortunatamente, a causa dell’or-
dine di esecuzione delle istruzioni TAL, la definizione viene interpretata prima della condizione. Con questo si
visualizza un collegamento alla cartella utilizzando l’attributo absolute_url dell’oggetto.
Il modello di pagina prosegue con altre righe relative alla visualizzazione di altre utili ed eccitanti proprietà
dell’utente. Come la maggior parte delle cose in Plone la chiave risolutiva è trovare le giuste chiamate alle API
per poi elaborarne i risultati in base alle necessità.
Infine la pagina termina chiudendo tutti i marcatori che vanno chiusi. Se tutto va bene è possibile consul-
tare la pagina accedendo all’URL http://sitoplone/user_info?userName=[nomeutente] dove
[nomeutente] va sostituito con un nome utente che esiste nel sito Plone.
Al momento questo modello di pagina abbastanza limitato. Solo un utente con il ruolo di manager può vedere
questa pagina, può visualizzare solo i dati relativi ad un solo utente per volta e le informazioni per l’utente sono
piuttosto poche. Nel Capitolo 6 vedremo come espandere questo esempio e come aggiungere la possibilità di
riutilizzare qualche componente e la possibilità di tradurre il testo in altre lingue.
Duplicate explicit target name: “appendice a”.
138 INDICE
Capitolo 6

Capitolo 6: Introduzione a modellazione e


scripting avanzato in Plone

139
140CAPITOLO 6. CAPITOLO 6: INTRODUZIONE A MODELLAZIONE E SCRIPTING AVANZATO IN PLONE
Indice

Nel capitolo precedente abbiamo trattato come funziona il sistema dei modelli di pagina Zope Page Template. Per
comprendere i modelli di pagina, nel Capitolo 5 abbiamo trattato anche la gerarchia degli oggetti, l’acquisizione,
e il Template Attribute Language Espression Syntax (TALES). Usando il codice del capitolo precedente, siamo
ora in grado di generare pagine web dinamiche. In quel capitolo abbiamo mostrato anche un modello di pagina di
esempio che mette insieme il codice, trattato la costruzione dei fondamenti del sistema di modellazione di Plone
e fornite le informazioni chiave necessarie per usarlo.
Ora è tempo di muoversi all’interno delle caratteristiche più avanzate dei modelli di pagina e più genericamente
della modellazione in Plone. Presentiamo, prima, il Macro Expansion Template Attribute Language (METAL)
ed lo spazio dei nomi I18N per l’internazionalizzazione. Come lo spazio dei nomi TAL, anche questi offrono
funzionalità allo sviluppatore del sito. Per coloro che muoiono dalla voglia di sapere precisamente come sia
assemblata una pagina Plone, la sezione Guardare dentro Plone usando METAL offre molte risposte.
Fino ad ora abbiamo mostrato come sia possibile usare semplici espressioni Python nei modelli di pagina. Ov-
viamente, talvolta un’espressione Python di una-riga non è sufficiente. Così nella sezione Scrivere codice Python
per Plone, mostreremo come portare Python al successivo livello e come aumentare la potenza del nostro codice
Python.
Infine, tratteremo un esempio comune, mostrando come mettere insieme un modulo in Plone. Questo esempio
utilizza i concetti imparati nei capitoli precedenti, integrandoli tutti assieme mostrando precisamente come Plone
si occupa dei moduli.

6.1 Capire la modellazione avanzata in Plone


Uno degli aspetti belli dei modelli di pagina è che funzioni diverse sono chiaramente separate in spazi di nomi
diversi. Nel capitolo precedente, abbiamo visto lo spazio dei nomi TAL. Quello non è l’unico spazio dei nomi
disponibili nei modelli di pagina ; altri due spazi dei nomi sono fondamentali in Plone.
Il primo è METAL. Come il nome, abbastanza lungo, suggerisce, è simile a TAL in quanto è un linguaggio di
attributi e lo si inserisce negli attributi degli elementi. Comunque, il suo scopo primario è far si che sia possibile
riusare pezzi di codice provenienti da altri modelli di pagina, reso possibile con l’utilizzo degli slot e delle macro.
Il secondo è I18N, che permette di tradurre il contenuto dei modelli di pagina. Questo è usato in Plone per
localizzare l’interfaccia in più di 30 lingue e per molti utenti è una delle caratteristiche fondamentali di Plone.
Come vedremo, la possibilità di localizzare testo interessa tutti gli utenti, anche quelli che costruiscono un sito
monolingua. Inizieremo con METAL.

6.1.1 Guardare dentro Plone usando METAL


Finora abbiamo visto come usare TAL per creare dinamicamente parti di pagine. Questo in realtà non permette
di fare modellazione molto complessa. Non c’è un vero meccanismo per posizionare un’intestazione standard in

141
142 INDICE

alto a ciascuna pagina, se non usando un etichetta TAL. METAL è un metodo per consentire un preprocessing dei
modelli e di offrire alcune funzioni più potenti di TAL. Ogni funzione METAL inizia con il prefisso metal:.

metal:define-macro

Il comando metal:define-macro permette di definire un elemento da citare in un altro modello. Il nome della
parte referenziata è il nome della macro. Ciò che segue è un esempio che definisce boxA come una parte che si
desidera usare altrove:

<div metal:define-macro="boxA">
...
</div>

Quell’elemento div è ora una macro che può essere citata in altri modelli. La macro si riferisce solamente
alla parte della pagina citata dall’elemento che, in questo caso, è il marcatore div. È quindi piuttosto comune
inserire svariate di queste definizioni di macro in una singola pagina, rispettando il formato Hypertext Markup
Language (HTML), come nel seguente esempio:

<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
i18n:domain="plone">
<body>
<div metal:define-macro="boxA">
...
</div>
<div metal:define-macro="boxB">
...
</div>
</body>
</html>

Essendo uno dei obiettivi primari dei modelli di pagine, questa pagina contiene codice HTML valido che può
essere modificato da un designer. Quando la macro è chiamata, il codice HTML esterno al marcatore div verrà
scartato.

metal:use-macro

Il comando metal:use-macro usa una macro che è stata definita con define-macro. Quando un modello definisce
una macro usando il comando define-macro, essa è accessibile agli altri modelli attraverso una proprietà macros.
Per esempio, se si vuole estrarre la macro portlet del modello portlet_login, si può fare come segue:

<div metal:use-macro="context/portlet_login/macros/portlet">
Qui verrà inserito lo slot informativo
</div>

Questo recupererà la macro e ne inserirà il risultato al proprio posto. Come mostrato, il comando use-macro
prende un’espressione path che punta al modello e poi alla macro specificata nel modello stesso.
6.1. CAPIRE LA MODELLAZIONE AVANZATA IN PLONE 143

Esempio: Usare le macro use-macro e define-macro

Come esempio, quello che segue è un modello chiamato time_template. Questo modello mostra la data e
l’ora corrente sul server Plone. Questa è una funzione veramente utile e che per comodità di riutilizzo può essere
inserita in una macro. Questo è il modello di pagina dell’esempio che contiene la define-macro:

<html>
<body>
<div metal:define-macro="time">
<div tal:content="context/ZopeTime">
Data e ora
</div>
</div>
</body>
</html>

Se il nostro modello è stato chiamato time_template, allora possiamo citare questa macro in un altro
modello. Possiamo ora referenziare questa macro in diversi modelli. Questa è un modello di esempio:

<html>
<body>
<div metal:use-macro="context/time_template/macros/time">
Se c’è un messaggio qui viene inserita la macro.
</div>
</body>
</html>

Quando questo modello è restituito, l’HTML prodotto da Plone avrà un come questo:

<html>
<body>
<div>
<div>2004/04/15 17:18:18.312 GMT-7</div>
</div>
</body>
</html>

metal:define-slot

Uno slot è una sezione di una macro che l’autore di un modello si aspetta venga sostituita da un altro modello.
Si può pensare come ad un buco nel nostro modello di pagina dove, ci aspettiamo, qualche altra cosa lo riempia.
Tutti i comandi define-slot devono essere contenuti all’interno di una define-macro. Per esempio:

<div metal:define-macro="master">
<div metal:define-slot="main">
...
</div>
</div>
144 INDICE

metal:fill-slot

Questo riempie uno slot che è stato definito con il comando define-slot. Una macro fill-slot deve essere definita
con il comando use-macro. Quando la parte define-macro è chiamata, la macro cercherà di riempire tutti gli slot
definiti con gli appropriati fill-slot. Ecco un esempio di fill-slot:

<div metal:use-macro="master">
<div metal:fill-slot="main">
Qui verrà inserito lo slot main
</div>
</div>

Esempio: usare macro e slot

Ritornando all’esempio precedente, ora lo miglioreremo un pochino. Se vogliamo mettere un messaggio persona-
lizzato che preceda l’ora, allora aggiungeremo uno slot all’inizio del time_template, dentro la define-macro.
Lo slot è chiamato time ed è il seguente:

<html>
<body>
<div metal:define-macro="time">
<div metal:define-slot="msg">Time slot</div>
<div tal:content="context/ZopeTime">
Data e ora
</div>
</div>
</body>
</html>

Ora, nel modello di pagina chiamante, possiamo richiamare la fill-slot:

<html>
<body>
<div metal:use-macro="context/time_template/macros/time">
<div metal:fill-slot="msg">L’istante è:</div>
Se c’è un messaggio qui viene inserita la macro.
</div>
</body>
</html>

Il risultato finale è vedere la time-slot rimpiazzata come segue:

<html>
<body>
<div>
<div>L’istante è:</div>
<div>2004/04/15 17:18:18.312 GMT-7</div>
</div>
</body>
</html>
6.1. CAPIRE LA MODELLAZIONE AVANZATA IN PLONE 145

Come Plone usa macro e slot

Le macro e gli slot sono simili dal momento che entrambi estraggono contenuti da altri modelli ed inseriscono
contenuti, ma lo fanno in maniera differente. La differenza è evidente nel modo in cui vengono usati. Le macro
sono elementi di un modello che vengono chiamate esplicitamente, invece gli slot sono buchi in un modello che
aspettano che di essere riempiti da altri modelli. Per esempio, nel caso dei portlet Plone come il calendario, la
navigazione e così via sono macro che vengono esplicitamente chiamate.
Infatti, se nella Zope Management Interface (ZMI) guardiamo il file cliccando su portal_skin, poi su plo-
ne_template ed infine cliccando main_template, vedremo che l’intera pagina consiste di macro e di slot. A
questo punto, probabilmente c’è un po’ di confusione, ma quando questo viene chiamato, esegue una serie di
macro e mette insieme tutto. Ciò permette all’utente di modificare facilmente qualsiasi parte di un sito Plone
sovrascrivendo tale macro, come vedremo nel prossimo capitolo. Per esempio:

...
<div metal:use-macro="here/global_siteactions/macros/site_actions">
Site-wide actions (Contact, Sitemap, Help, Style Switcher etc)
</div>

<div metal:use-macro="here/global_searchbox/macros/quick_search">
The quicksearch box, normally placed at the top right
</div>
...

Continuando la lettura di main_template, si incontrano alcune definizioni di slot. Brevemente ricorderemo


come viene realizzata una pagina di Plone. Quando un oggetto è mostrato, viene visualizzato un modello di quella
vista per quel contenuto. Quando si vede un’immagine, è mostrato il modello image_view, e quel modello
controlla come l’immagine viene mostrata. Per far questo, il modello riempe lo slot main. Se guardiamo nel
modello image_view, vedremo che contiene il seguente codice:

<div metal:fill-slot="main">
...
</div>

Se ritorniamo di nuovo al main_template, vedremo che contiene una definizione define-slot per lo slot main:

<metal:bodytext metal:define-slot="main" tal:content="nothing">


Page body text
</metal:bodytext>

Ciascun tipo di contenuto possiede un diverso modello, e ciascun modello definisce come usare differentemente
lo slot main. Cosicchè, ciascun tipo di contenuto assume un aspetto personale e particolare definito da un mo-
dello. Solo un elemento è scomparso dall’equazione. In qualche modo quando viene chiamato image_view, il
modello sa di dover usare main_template. Nel modello image_view, viene usata la macro proveniente da
main_template. Questo è definito nel seguente HTML:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"


lang="en-US"
metal:use-macro="here/main_template/macros/master"
i18n:domain="plone">

In questo caso, il main_template ha lo slot main riempito dallo slot definito come main nel modello che
viene reso. Ciò che segue è la cronologia di come viene costruita la pagina quando si guarda un’immagine:
146 INDICE

1. image_view

2. main_template
3. image_view
4. main_template
5. define-slot=“main”
6. fill-slot
7. image_view
8. fill-slot

9. main_template
10. main_template

Questo permette a Plone di essere flessibile in termini di come ciascuna pagina è definita. Per esempio, main_template
definisce più di uno slot; c’è anche un slot per inserire codice Cascading Style Sheets (CSS):

<metal:cssslot fill-slot="css_slot">
<metal:cssslot define-slot="css_slot" />
</metal:cssslot>

Se una vista ha bisogno di un proprio insieme di istruzioni CSS, potremo definire questo slot nella vista, e verrà
riempito quando reso. Alcune delle macro in main_template definiscono a loro volta degli slot che vengono
riempiti dallo stesso main_template in modo tale che se necessario possano essere ridefiniti. Comunque,
questa è una tecnica avanzata che potrà essere usata solo una volta che ci saremo impadroniti dei fondamentali.

6.1.2 Introduzione all’internazionalizzazione


Plone sta sforzandosi di mantenere sempre un gran numero di traduzioni di alta qualità. Il fatto che Plone offra
un’interfaccia utente accessibile in più di 30 lingue è un punto fondamentale per la sua commercializzazione.
11
Questo vuol dire anche che I18N è una caratteristica basilare dei modelli. Il namespace I18N è uno spazio
dei nomi come TAL o METAL che possiedono specifiche etichette.
Questa sezione mostra ciò di cui gli utenti hanno bisogno di conoscere circa i modelli. In un modello potete
aggiungere un marcatore i18n ad un elemento per permettere la traduzione di un attributo o del suo contenuto.
Esistono sei etichette: attributes, data, domain, source, target e translate. La configurazione di base consiste
nell’avvolgere il brano di testo che desiderate tradurre ed aggiungere gli attributi i18n adatti. Per esempio, se
vogliamo tradurre il seguente:

<i>Del testo</i>

esso diverrebbe come:

<i i18n:translate="etichetta_del_testo">Del testo</i>

Ogni localizzazione offre una traduzione di Del testo, e lo strumento di traduzione individua la stringa tradotta
e la mostra all’utente. Quando si effettua la traduzione, ogni stringa per essere tradotta deve avere un unico ID
che la contraddistingue. Per esempio, una stringa come Ricerca potrebbe avere un ID etichetta_oggetto_ricerca.
Questo ID permette alla stringa di essere identificata unicamente e la traduzione di essere riutilizzata.
6.1. CAPIRE LA MODELLAZIONE AVANZATA IN PLONE 147

i18n:translate

Questo traduce i contenuti di un elemento, con un ID opzionale passato come un’etichetta. Per esempio, il
seguente creerà una stringa con ID stringa_titolo:

<h1 i18n:translate="stringa_titolo">Questo è un titolo</h1>

Questo esempio mostra un testo statico che non subisce variazioni. Comunque, in alcune situazioni il pezzo di
testo potrebbe essere preso da un database o da un oggetto e potrebbe essere dinamico. Lasciando l’etichetta
translate vuota, l’ID della stringa viene calcolato a partire dal valore del campo. Nell’esempio seguente, se il
titolo ritornato dall’espressione path here/title fosse Alice nel Paese delle meraviglie, allora questo titolo verrà
passato allo strumento di traduzione. Se non esiste alcuna traduzione, verrà restituito il valore originale:

<h1
tal:content="here/title"
i18n:translate="">
Questo è un titolo.
</h1>

Il comando di traduzione è probabilmente uno dei marcatori i18n più comunemente usati, e lo vedremo in tutti i
modelli di Plone. Non solo consente di tradurre parti statiche del nostro sito, come etichette di modulo, messaggi
di aiuto, e descrizioni, ma anche le parti più dinamiche del sito che possono cambiare spesso, come i titoli delle
pagine.

i18n:domain

Questo setta il dominio per la traduzione. Per prevenire conflitti, ogni sito potrebbe avere multipli domini o
gruppi di traduzioni; per esempio, potrebbe esserci un dominio per Plone ed uno per la nostra applicazione
personalizzata. Plone usa il dominio plone che è il dominio di default di Plone:

<body i18n:domain="plone">

Non si tratta di un comando che useremo spesso; comunque, se stiamo scrivendo un’applicazione personalizzata,
potremmo trovare utile avere un dominio per evitare conflitti con altri dominii.

i18n:source

Questo setta il linguaggio sorgente del testo da tradurre. Non è usato in Plone:

<p i18n:source="en" i18n:translate="">Del testo</p>

i18n:name

Questo fornisce una via per preservare elementi in un grande blocco di testo così che il blocco di testo possa
essere riordinato. In molte lingue, non vengono solamente cambiate le parole ma anche l’ordine. Se dobbiamo
tradurre un intero paragrafo o una frase che contiene piccoli pezzetti che non dovrebbero essere tradotti, allora
possono essere passati attraverso:
148 INDICE

<p i18n:translate="messaggio_libro">
The
<span
tal:omit-tag=""
tal:content="book/color"
i18n:name="age">Blue</span>
Book
</p>

Questo produrrà il seguente messaggio:

The {color} Book

Se il linguaggio tradotto costringesse ad un diverso ordine, le parole possono venire spostate e comunque si
otterrebbe il contenuto dinamico posizionato nel posto giusto. In italiano, questo avrebbe bisogno di essere
tradotto in questo modo:

Il Libro {color}

i18n:target

Questo imposta la lingua di destinazione della traduzione. Non è usato in Plone.

i18n:attributes

Questo permette la traduzione di attributi all’interno di un elemento, piuttosto che il contenuto. Per esempio, un
marcatore image ha l’attributo alt che mostra una visualizzazione alternativa dell’immagine:

<img
href="/qualcheimmagine.jpg"
alt="Un certo testo"
i18n:attributes="alt alternate_image_label" />

Attributi multipli devono essere separati con un punto e virgola, nello stesso modo di tal:attributes.

i18n:data

Questo offre un modo di tradurre qualsiasi cosa oltre che le stringhe. Un esempio è un oggetto DateTime.
Un’etichetta i18n:data richiede una corrispondente etichetta i18n:translate così che sia disponibile un ID di
messaggio valido. Per esempio:

<span i18n:data="here/currentTime"
i18n:translate="timefmt"
i18n:name="time">2:32 pm</span>... beep!
6.1. CAPIRE LA MODELLAZIONE AVANZATA IN PLONE 149

Figura 6.1: Figura 6-1. Plone.org in francese


150 INDICE

Translation Service

Ora che abbiamo trattato i marcatori, tratteremo del meccanismo per eseguire la traduzione. Di suo Plone dispone
di un meccanismo I18N. Questo permette di internazionalizzare l’interfaccia utente così che messaggi, schede,
e moduli possono essere tutti tradotti. A questo livello non trattiamo il reale contenuto che gli utenti aggiungono.
Se si aggiunge un documento in inglese e si vede la pagina richiedendola in francese, troveremo il documento
inglese con il testo francese di contorno (vedere Figura 6-1).

Plone legge le intestazioni HTTP che un browser spedisce al client richiedendo una determinata lingua. Se il
nostro browser è in inglese, allora non vedremo granché.
Per cambiare le impostazioni della lingua in Internet Explorer, si faccia come segue:

Nota
manca qualche cosa ....

Una volta fatto questo, scegliamo i nostri siti Plone favoriti e visitiamoli col browser.
Le traduzioni di Plone sono effettuate attraverso uno strumento chiamato Placeless Translation Service (PTS).
Possiamo localizzare lo strumento PTS nel pannello di controllo di Zope; in fondo alla pagina vedremo un
opzione per il Placeless Translation Service. Clicchiamolo, ed apriamo tutte le traduzioni che esistono. Queste
traduzioni sono lette direttamente dal File System; clicchiamo una traduzione per vedere le informazioni sul
linguaggio, come il traduttore, la codifica, ed il percorso del file. Tutti i file in realtà sono conservati nella
directory i18n della directory CMFPlone.
Le traduzioni sono eseguite usando due file, un file .po ed un file .mo12. Per esempio, plone-de.po contiene
le traduzioni per il tedesco (de è il suffisso per il tedesco). Il file .mo è la versione “compilata” del file .po e
sono usati da Plone per un miglior rendimento. Non abbiamo mai bisogno di guardare nel file .mo, così che
potremo proprio ignorarlo.
Il .po è il file che può essere modificato per una traduzione. Se apriamo questo file in un editor di testo, vedremo
una serie di linee che iniziano con il testo msgid o msgstr. Al di sopra di msgid v’è attualmente il codice dove
si presenta il comando i18n, così che si possa risalire a quale pezzo della pagina si sta traducendo. Per esempio:

#: from plone_forms/content_status_history.pt
#. <input attributes="tabindex tabindex/next;" value="Apply"
class="context" name="workflow_action_submit" type="submit" />
#.
#: from plone_forms/personalize_form.pt
#. <input attributes="tabindex tabindex/next;" tabindex=""
value="Apply" class="context" type="submit" />
#.
msgid "Apply"
msgstr "Anwenden"

Nelle due parti del precedente modello di pagina, la parola Apply, sarà tradotta in Anwenden per gli utenti
tedeschi. Quello che viene tradotto è determinato dai marcatori i18n che sono stati inseriti nei modelli di pagine,
come precedentemente visto. Se vogliamo cambiare questa traduzione o aggiungere la nostra personale varia-
zione, allora dobbiamo solamente cambiare il file .po. Se nessun msgstr viene trovato, allora viene restituita
la traduzione inglese di default. Una volta che fatto questo cambiamento, riavviamo Plone. Quando accade ciò,
Plone ricompilerà questi file nella versione .mo e la nostra traduzione sarà aggiornata.
6.1. CAPIRE LA MODELLAZIONE AVANZATA IN PLONE 151

Per Plone, l’opzione predefinita è sempre quella di usare il file di traduzione inglese se non viene fornito nessun
linguaggio ovvero nessuna traduzione sia disponibile. Infatti, il file plone-en.po è vuoto, in modo che nes-
suna traduzione sia disponibile. Perciò, Plone fa la ricaduta finale (fallback), non effettua traduzione, e mostra
il testo nel modello di pagina. Il testo in tutti i modelli di pagine è in inglese visto che la maggior parte degli
sviluppatori parlano inglese. Il vantaggio di ciò è che non v’è traduzione in inglese.
Perciò, si può fare una nuova traduzione copiando il file plone.pot in un nuovo file col nome plone-xx.po.
Il valore di xx deve essere uguale al codice del paese della nostra traduzione. Possiamo trovare un elenco di
codici di linguaggio presso http://www.unicode.org/onlinedat/languages.html. Una volta avviata la traduzione,
aggiustiamo i valori all’inizio del file, incluso il codice di linguaggio e iniziamo a tradurre. Se abbiamo realizzato
un nuovo file di linguaggio, allora il team di Plone I18N sarà felice di accettarlo e aiuterà a completarlo. La
mailing list del team di Plone è presso http://sourceforge.net/mailarchive/forum.php?forum_id=11647.
Tradurre il contenuto che le persone via via aggiungono è davvero un compito complicato: si sta lavorando ad una
soluzione, ma non c’è ancora nulla di definitivo. L’approccio migliore è al momento usare due prodotti, Plone-
LanguageTool e i18nLayer ; entrambi possono essere trovati nel progetto Collective di SourceForge. Comunque,
entrambi sono prodotti per sviluppatori molto esperti per comprenderli pienamente ed integrarli; speriamo che
qualche cosa come questi vi sia nella prossima versione del libro.

6.1.3 Esempio: Visualizzare informazioni su più utenti


Nel ‘capitolo 5‘_ abbiamo usato semplice comandi TAL per mostrare più in dettaglio le informazioni di un
utente. Quel modello ha alcuni limiti; uno è che mostra solamente un utente per volta. Abbiamo visto come
con un semplice tal:repeat sia possibile ripetere dei contenuti, ma ora useremo una macro per realizzare questa
pagina in forma più modulare.
Cambieremo il modello di pagina user_info così da elencare ogni membro del sito. Invece di cercare un
username che venga passato alla richiesta, verrà usata la funzione listMembers che restituisce un elenco dei
membri del sito:

<div metal:fill-slot="main">
<tal:block
tal:define="
getPortrait nocall: here/portal_membership/getPersonalPortrait;
getFolder nocall: here/portal_membership/getHomeFolder
">
<table>
<tr tal:repeat="userObj here/portal_membership/listMembers">
<metal:block
metal:use-macro="here/user_section/macros/userSection" />
</tr>
</table>
</tal:block>
</div>

Noteremo che ora il codice di user_info è molto più breve. L’utente ritornato da listMembers è passato
in tal:repeat. Per ciascun utente, vi sarà una riga di tabella e poi una macro per mostrare informazioni all’utente.

11
La sigla I18N è la contrazione del termine inglese internationalization, prendendo le due lettere agli estremi
e saltandone appunto 18.
12
In realtà, le versioni recenti di PTS sono in grado di utilizzare direttamente i file .po e non c’è più motivo di
doverli compilare nel formato .mo. [N.d.T.]
152 INDICE

In quella riga di tabella, la variabile userObj, definita localmente, ora contiene le informazioni dell’utente. Di
certo, ora avremo necessità di creare una macro chiamata userSection in un modello di pagina: nell’esempio la
macro è contenuta nel modello user_section. Questo modello contiene tutto il codice che era tra i marcatori
row nella tabella. Di nuovo, possiamo trovare un listato completo per questo modello di pagina nell’‘Appendice
B‘_:

<div metal:define-macro="userSection"
tal:define="userName userObj/getUserName">
...

L’unico vero cambiamento è che la use-macro nel modello main deve essere rimossa da una nuova macro
definita in modo che questa macro possa essere definita. Poiché l’username non viene più passato esplicitamente,
abbiamo bisogno di ottenere l’username dell’oggetto utente usando il metodo getUserName. Per esaminare la
pagina risultante, visitiamo l’indirizzo http://sitoplone/user_info, e dovremmo vedere un elenco di utenti.
La pagina ora è di facile uso, mostrando diversi utenti contemporaneamente. Il codice è più modulare, avendo
posizionato le informazioni dell’utente in una macro separata che può essere modificata indipendentemente.
Questa pagina ancora non è perfetta ma sarà migliorata nei capitoli successivi.

6.1.4 Esempio: Creare un nuovo Portlet con gli annunci di Google


Nel capitolo 4 abbiamo affermato come sia facile modificare i portlet in un sito Plone; aggiungere un nostro
portlet personale non è molto più difficile. Per scrivere un nostro slot personale, dovremo creare un nuovo
modello di pagina con una macro all’interno. Poi un’espressione TALES che punta alla macro verrà aggiunta
all’elenco dei portlet, visualizzando il portlet nella pagina.
Il modello di base per un portlet è il seguente:

<div metal:define-macro="portlet">
<div class="portlet">
<!-- Enter code here -->
</div>
</div>

Tutto quello di cui abbiamo bisogno di fare è inserire del codice appropriato nel portlet. Google nel 2003 ha
reso disponibile un sistema di annunci testuali per poterli posizionare nel proprio sito. Gli annunci sono basati
su quello che Google ritiene essere interessante per il nostro sito, basandosi sui risultati delle ricerche effettuate
sul sito stesso. Il sistema di Google è disponibile presso http://www.google.com/adsense. Per visualizzare gli
annunci (ed essere pagati per questo), dobbiamo registrarci sul sito web di Google, dove ci verrà chiesto di
scegliere i colori e lo stile. Siccome metteremo questo in uno slot, raccomandiamo la dimensione “skyscraper”.
Fare una copia dello JavaScript che il sito fornisce.
Dopo di che, dovremo creare un portlet:
portal_skins/custom
googleAds
googleBox
<!-- Digitiamo il codice qui -->
Il risultato finale dovrebbe essere qualche cosa come il listato 6-1; comunque, la nostra versione dovrebbe avere
un valore valido per google_ad_client, piuttosto che yourUniqueValue. Questo valore informa Google quale
sito ordina questo annuncio e chi dovrà essere pagato. Abbastanza curiosamente, non inserendo un ID valido in
quella posizione, Google mostrerà felicemente gli annunci ma non ci pagherà!
Listato 6-1. Visualizzatore degli annunci da Google
6.2. SCRIVERE CODICE PYTHON PER PLONE 153

<div metal:define-macro="portlet">
<div class="portlet">
<script type="text/javascript"><!--
google_ad_client = "yourUniqueValue";
google_ad_width = 120;
google_ad_height = 600;
google_ad_format = "120x600_as";
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>

</div>
</div>

Quindi, per includere questo sul nostro sito, come mostrato nel capitolo 4, aggiungiamo il portlet seguente al
nostro elenco di portlet:

here/googleAds/macros/portlet

6.2 Scrivere codice Python per Plone


In Plone esistono almeno quattro livelli differenti per creare logica. Il livello più semplice di uso di Python in
Plone sono le espressioni Python TALES che abbiamo trattato nel capitolo precedente. Un’espressione Python,
comunque, permette di inserire solamente una riga di codice; spesso vorremo fare qualche cosa di più complesso.
Anche più comune è il problema di non voler assolutamente mischiare la logica all’interno del modello. Po-
sizionare logica nel nostro modello è in generale una cattiva abitudine; ogni volta che si può spostare qualche
cosa che non sia esplicitamente la logica di presentazione fuori dal modello, ci si risparmia un bel mal di testa.
Separare logica e presentazione permette di far lavorare facilmente persone diverse su diverse parti del progetto,
e migliora il riuso del codice. Gli altri livelli di aggiungere scripting in Plone avvengono più o meno nel seguente
ordine:

Template attribute expressions Questo offre espressioni ed un modo di inserire piccoli frammenti di logica o
dei semplici percorsi in vari posti.

Script (Python) objects Questi sono semplici script che sono eseguiti in Plone in ambiente ristretto.
External method objects Questi sono moduli più complicati che non vengono eseguiti in ambiente ristretto.
Python products Questo è il modo fondamentale con cui sono scritti internamente CMF e Plone; questo of-
fre accesso a qualsiasi cosa in Plone. I prodotti Python sono un oggetto avanzato e sono trattati nel capitolo
14.

Dopo un’espressione, il livello successivo di complessità è un oggetto Script (Python). Questo oggetto permette
diverse linee di codice Python, e può essere chiamato da un’espressione. Quando un oggetto Script (Python)
viene eseguito, si incorre in un piccolo sovraccarico extra per il fatto che Plone deve attivare quell’oggetto.
Comunque, questo sovraccarico è minimo perché v’è un compromesso fra chiarezza, separazione e rendimento.
Il nostro consiglio è di mettere, se possibile, molta logica all’interno di Python e di tenere semplici e puliti i
modelli di pagina. È facile reinserirlo, in un secondo tempo, se vi sono problemi di rendimento, ma almeno
capiremo quello che sta accadendo.
154 INDICE

6.2.1 Uso degli oggetti Script (Python)


Un oggetto Script (Python) è probabilmente ciò che tradizionalmente si pensa in Plone come ad uno script. È un
frammento Python che si può scrivere e quindi chiamare da altri modelli o direttamente attraverso il web. Plone
possiede in realtà moltissimi script per effettuare varie funzioni fondamentali. Uno Script (Python) è, in termini
di potenza, una via di mezzo fra un’espressione ed un External Method.
Per aggiungere un oggetto Script (Python), andiamo nella ZMI, selezioniamo Script (Python) nel menu di scelta,
e clicchiamo Add, come dimostrato in figura 6-2.

Figura 6.2: Figura 6-2. Aggiungere un oggetto Script (Python)

Diamo allo script un ID come test_py e poi clicchiamo Add and Edit. Questo aprirà la pagina di modifica
dell’oggetto Script (Python) come mostrato in figura 6-3.

Possiamo modificare direttamente lo script attraverso il web. Se facciamo un errore di sintassi, verrà evidenziato
dopo aver cliccato Save Changes, come mostrato in figura 6-4.

Se non vi sono errori nel nostro Script (Python), possiamo cliccare la scheda Test per vedere quello che sarà
l’output. In questo caso, l’esempio è piuttosto noioso; stampa il testo seguente:

This is the Script (Python) "test_py" in


http://gloin:8080/Plone/portal_skins/custom

Uno script inoltre ha le seguenti opzioni:

Title Il modulo di modifica ha un opzione Title che fornisce un titolo allo script. Questo verrà mostrato nella
ZMI, così sarà più facile ricordare ciò che fa.
Parameter List Questo è un lista di parametri che lo script prende, come variableA o variableB=none. Que-
sto, infatti, è l’elenco standard di parametri che ci si aspetta in una funzione standard Python. Alcuni para-
metri, comunque, sono sempre definiti in questo oggetto; possiamo vederli cliccando la scheda Bindings.
In questa scheda, già vediamo un elenco delle variabili contenute dall’oggetto che ora dovrebbero avere
nomi familiari.

In seguito vi sono le variabili associate allo script accessibili da un oggetto Script (Python):
6.2. SCRIVERE CODICE PYTHON PER PLONE 155

Figura 6.3: Figura 6-3. Modificare un oggetto Script (Python)


156 INDICE

Figura 6.4: Figura 6-4. Un deliberato errore di indentazione nell’oggetto Script (Python)
6.2. SCRIVERE CODICE PYTHON PER PLONE 157

context Questo è l’oggetto dal quale viene chiamato lo script.

container Questo è l’oggetto contenitore dello script.


script Questo è l’oggetto Script (Python) stesso; l’equivalente in Zope Page Templates è template.
namespace Questo è per quando questo script viene chiamato dal Document Template Markup Language
(DTML); che è un qualche cosa che non succede in Plone.
traverse_subpath Questo è il percorso Uniform Resource Locator (l’URL) dopo il nome dello script che è una
caratteristica avanzata.

Ora mostreremo un semplice esempio che unisce questi argomenti nel sistema dei modelli di pagina di Zope,
usando l’esempio di un’espressione Python, fornita nel capitolo precedente, che somma due numeri. Come
abbiamo visto, si può costruire un modello di pagina come segue:

<p>1 + 2 = <em tal:content="python: 1 + 2" /></p>

Il seguente è l’equivalente che utilizza uno oggetto script (Python). Cambiiamo lo script test_py alla linea
seguente:

return 1+2

Come si è visto all’inizio del capitolo precedente, richiamiamo un oggetto fornendo il suo percorso in un’espres-
sione. Quindi, in un modello di pagina, ora possiamo fare qualcosa del tipo:

<p>1 + 2 = <em tal:content="here/test_py" /></p>

L’oggetto test_py è acquisito nell’espressione path e chiamato e quindi ritorna indietro al modello Python e
lo stampa. Ora abbiamo richiamato uno script dal nostro modello! Questo è evidentemente un esempio piuttosto
semplice, ma a nostro giudizio vi sono una grande quantità di cose che possiamo fare con uno oggetto Script
(Python) che giustamente non è possibile fare in un modello di pagina.
In un oggetto Script (Python), si possono specificare titolo, parametri, ed impostare i binding usando la notazione
## all’inizio dello script. Quando salviamo uno script con questo testo in cima, Plone rimuoverà questa linea e
cambierà gli appropriati valori nell’oggetto. Questa sintassi viene molto utilizzata, in questo libro, negli oggetti
Script (Python) per essere sicuri che si abbia il titolo corretto ed i parametri. Quindi, possiamo riscrivere lo script
precedente come segue:

##title=Returns 1+2
##parameters=
return 1+2

Script in Plone

Scrivere codice in Plone è un soggetto piuttosto complicato perché non appena siamo capaci di scrivere script
in Plone, vorremmo prendere in considerazione l’Application Programming Interface (API) di tutti gli oggetti e
degli strumenti che possiamo voler usare. Spiegare le API va oltre lo scopo di questo libro; mostreremo invece
come fare semplici compiti usando gli oggetti Script (Python). Una volta che avremo preso confidenza con loro,
descriveremo ulteriori specifiche funzioni API.
I modelli di pagina possono accedere in modo semplice ai dizionari e alle liste Python. Ma spesso non si hanno
dati in una di queste forme convenienti, così si ha bisogno di saltare all’interno con un oggetto Script (Python),
formattare esattamente i dati, e poi passarli di nuovo al modello di pagina.
158 INDICE

Il formato più conveniente dei dati è un lista di dizionari che permette di combinare in una funzione la potenza
di un tal:repeat e di una path expression. Come esempio, vediamo una funzione che prende un lista di oggetti.
Ciascun oggetto è in effetti un oggetto in una cartella. Per ognuno di questi oggetti, dobbiamo controllare se
l’oggetto è stato aggiornato negli ultimi cinque giorni. Il listato 6-2 mostra un piccolo utile portlet che abbiamo
messo insieme per un sito che cerca di localizzare questo tipo di informazioni e di evidenziarli con precisione.
Listato 6-2. Ritornare oggetti più vecchi di cinque giorni

##title=recentlyChanged
##parameters=objects
from DateTime import DateTime

now = DateTime()
difference = 5 # as in 5 days
result = []

for object in objects:


diff = now - object.bobobase_modification_time()
if diff < difference:
dct = {"object":object,"diff":int(diff)}
result.append(dct)

return result

In questo oggetto Script (Python) abbiamo presentato un paio di concetti nuovi. Prima, importiamo il modulo
DateTime di Zope usando la funzione import. Il modulo DateTime, trattato nell’Appendice C, è un modulo che
fornisce accesso alle date. È abbastanza semplice, ma se creiamo un nuovo oggetto DateTime senza parametri,
allora troveremo la data e l’ora corrente; questa è la variabile now. Quando si sottraggono due oggetti DateTime,
viene restituito il numero di giorni. Si può confrontare questa differenza con quella richiesta dall’utente e, se
è più grande, aggiungerlo alla lista dei risultati. Il risultato è un lista di oggetti dizionario, come mostrato nel
listato 6-3.
Listato 6-3. Il Risultato del listato 6-2

[
{
’diff’: 1,
’object’: <PloneFolder instance at 02C0C110>
},
{
’diff’: 4,
’object’: <PloneFolder instance at 02FE3321>
},
...

Così ora che abbiamo il risultato nell’ordine corretto, abbiamo bisogno di un modello di pagina che passi la lista
di oggetti e processi il risultato. Un esempio di ciò è il seguente:

<ul>
<li tal:repeat="updated python: context.updateScript(context.contentValues())

Questo modello ha una chiamata tal:repeat in cima che richiama lo script (in questo caso, chiamato update-
Script). A questa funzione viene passato un valore, una lista di contentValues, dal contesto corrente. Prece-
dentemente si è chiamato l’oggetto Script (Python) usando un’espressione path; si può fare questo con con-
text/updateScript. Comunque, non si possono passare parametri attraverso lo script che è stato chiamato con
6.2. SCRIVERE CODICE PYTHON PER PLONE 159

questa sintassi, così deve essere invece utilizzata una espressione Python, che è python: context.updateScript().
La funzione contentValues ritorna la lista di ogni oggetto contenuto in una cartella. Successivamente, guardiamo
al codice per ogni iterazione:

<a href="#"
tal:attributes="href updated/object/absolute_url"
tal:content="updated/object/title_or_id">
The title of the item</a>
<em tal:content="updated/diff" /> days ago
</li>
</ul>

Come mostrato, possiamo iterare attraverso questa lista di valori, e possiamo usare allora espressioni path per
accedere prima al valore ripetuto (update), poi all’oggetto (object), ed infine ad un metodo di questo oggetto
(title_or_id). Questo è un esempio di utilizzo di una logica complicata processata e passata ad un oggetto Script
(Python).

Python in ambiente limitato

Diverse volte abbiamo menzionato che gli oggetti Script (Python) e le espressioni Python TAL vengono tutti
eseguiti in restricted Python. Quello del Python limitato è un ambiente che ha alcune funzioni rimosse. Queste
funzioni possono essere potenzialmente pericolose in un ambiente web come è Plone. La ragione originale è
che si possono avere utenti non fidati (ma autenticati) che scrivono codice Python sul nostro sito. Se apriamo un
account in uno dei diversi host web liberi per Zope, troveremo che si possa fare questo. Comunque, se abbiamo
dato a persone il diritto di farlo, non vogliamo che loro abbiano accesso a certe cose come il File System.
In Python limitato, alcune funzioni comuni di Python sono state rimosse per ragioni di sicurezza, dir ed open
non sono disponibili. Questo vuol dire che, gli oggetti Script (Python), non possono essere introspettivi, e che
l’accesso al File System è limitato. Sono disponibili all’utente alcuni moduli Python. La maggior parte di loro
sono solo per sviluppatori esperti; per ulteriori informazioni, si veda la documentazione attinente o il codice del
modulo:

string Questo è il modulo Python per le stringhe (http://Python.org/doc/current/lib/module-string.html).


random Questo è il modulo Python casuale (http://Python.org/doc/current/lib/module-random.html).
whrandom Questo è il modulo Python whrandom. Si dovrebbe usare quasi sempre random (http://Python.org/doc/current/lib/module-
whrandom.html).
math Questo è il modulo Python relativo alle funzioni matematiche (http://Python.org/doc/current/lib/module-
math.html).
DateTime Questo è il modulo proprio di Zope per le date.
sequence Questo è un modulo Zope per ordinare facilmente delle sequenze.
ZTUtils Questo è un modulo Zope che offre varie utilità.
AccessControl Questo dà accesso al modulo Access di Zope.
Products.PythonScripts.standard Questo dà accesso alle funzioni standard di processo delle stringhe DTML
come html_quote, thousands_commas e così via.

Se vogliamo importare un modulo che non è nella lista precedente, possiamo trovare allora eccellenti istruzioni
nel modulo PythonScript. Lo troveremo presso Zope/lib/Python/Products/PythonScripts/module_access_examples
Comunque, un procedimento più semplice è disponibile usando un External Method.
160 INDICE

6.2.2 Uso degli oggetti external Method


Un External Method è un modulo Python scritto nel File System e che può accedere a Plone. Siccome è scritto
nel File System, non viene eseguito in modalità lim itata di Python, e perciò è conforme alle impostazioni di
sicurezza standard di Plone.
Questo vuol dire che si può scrivere uno script che fa qualsiasi cosa si voglia e lo si chiama poi da un modello di
pagina. Compiti comuni includono l’apertura e la chiusura dei file, accedere ad altri processi o a file eseguibili,
ed eseguire compiti che Plone o Zope non possono effettuare con semplicità in qualche altro modo. Per ovvie
ragioni, quando stiamo scrivendo uno script che può fare questo, abbiamo bisogno di essere sicuri che non stiamo
facendo qualcosa di pericoloso, come leggere file di password del nostro server o cancellare un file che non si
voglia cancellare.
Per aggiungere un External Method, andiamo nel File System della nostra istanza home e cerchiamo la directory
Extensions. In questa directory, aggiungiamo un nuovo file Script (Python); per esempio, come mostrato in
Figura 6-5 abbiamo aggiunto test.py nella cartella del nostro computer Windows.

Ora possiamo aprire test.py e modificare il suo contenuto, scrivendo qualunque codice Python si voglia. L’unico
accorgimento è che dobbiamo avere una funzione di entrata che richieda almeno un argomento, self. Questo
argomento è l’oggetto dell’External Method di Plone che aggiungeremo fra breve. Ciò che segue è un esempio
di funzione di ingresso che legge il file README.txt fuori dalla stessa directory Extensions e lo restituisca
all’utente (dovremo cambiare il percorso per puntare al nostro file):

def readFile(self):
fh = open(r’c:\Program Files\Plone\Data\Extensions\README.txt’, ’rb’)
data = fh.read()
return data

Ora che abbiamo fatto questo, abbiamo bisogno di mappare un External Method a questo script. Questo è un og-
getto Zope, così ritorniamo alla ZMI, clicchiamo portal_skin e poi clicchiamo custom. Finalmente, selezioniamo
External Method dal box a cascata Add New Items. Quando si aggiunge un External Method, si ha bisogno di
dare il nome del modulo (senza il .py) e la funzione di ingresso, così che in questo caso avrà un modulo come in
Figura 6-6.

Dopo avere cliccato Save Changes, si può premere la scheda Test per vedere quello che succede quando viene
eseguito. In questo caso, dovremmo trovare una linea o due di testo. Siccome abbiamo il modulo Plone External
Method, si può accedere ad esso da un modello di pagina nello stesso modo come con qualsiasi altro oggetto.
Una path expression a here/test_external farebbe ciò in questo caso. Per esempio:

<h1>README.txt</h1>
<p tal:content="here/test_external" />

La vera forza è che si può passare codice da un ambiente non limitato di Python senza alcuna restrizione e da là a
qualsiasi funzione che si vuole, senza doversi preoccupare della sicurezza. Anche se questo può sembrare come
una funzione leggera, i metodi esterni non sono molto usati in Plone perché la logica più complessa è usualmente
posta all’interno di un oggetto Product mentre la logica semplice è invece posta in un oggetto Script (Python).
Se ci si trova ad usare molto oggetti External Method, si prenda in considerazione uno degli strumenti discussi
nel Capitolo 12.
6.2. SCRIVERE CODICE PYTHON PER PLONE 161

Figura 6.5: Figura 6-5. Un nuovo External Method, test.py


162 INDICE

Figura 6.6: Figura 6-6. L’External Method aggiunto di recente


6.3. CONSIGLI UTILI 163

6.3 Consigli utili


Poiché i modelli di pagine sono validi Extensible Markup Language (XML) e possono essere usati indipendente-
mente da Zope o da Plone, abbiamo molti utili script per ripulire il codice nei modelli di pagine e per effettuare
controlli di sintassi. Questi sono strumenti supplementari e controlli; Zope attualmente compie tutti i controlli
necessari quando carica un modello di pagina. Per un progetto come Plone, può essere utile eseguire controlli
automatici sul nostro codice o possiamo verificarlo localmente prima di inviare le modifiche.
Per eseguire questi controlli, avremo bisogno di poter abilitare questi strumenti a modificare localmente e di avere
Python istallato sul nostro computer. Per ulteriori informazioni sull’External Editor, un metodo per modificare
in locale codice remoto, si veda Capitolo 10.

6.3.1 Introduzione allo spazio dei nomi XML


I modelli di pagine usano lo spazio dei nomi XML per generare codice. I programmatori possono usare le re-
gole del namespaces XML per rendersi la vita più facile. All’inizio di un modello di pagina, si può vedere una
dichiarazione dello spazio dei nomi nel marcatore iniziale:

<html xmlns="http://www.w3.org/1999/xhtml"...

Questo pone il namespace predefinito a Extensible HTML (XHTML). Per qualsiasi elemento in esso contenuto,
se nessuno spazio di nomi viene definito, viene usato di base tale spazio dei nomi. Per esempio, riconosciamo
che l’elemento successivo è XHTML perché non ha prefisso:

<body>

Normalmente per gli elementi e gli attributi TAL e METAL, abbiamo aggiunto il prefisso tal: e METAL: per
definire il namespace. Il codice seguente è qualche cosa di cui ora dovreste avere familiarità:

<span tal:omit-tag="" tal:content="python: 1+2" />

Questo restituirà 3. Comunque, ciò che segue è un’alternativa:

<tal:number content="python: 1+2" />

Usando il prefisso tal:, abbiamo definito lo spazio dei nomi predefinito per questo elemento intero come tal. Se
nessun altro prefisso è dato, viene usato lo spazio dei nomi tal. Nell’esempio, usando il marcatore span, lo
spazio dei nomi predefinito è XHTML, così dobbiamo specificatamente definire il prefisso tal: quando si usa la
scheda Content.
Si noti che il nome di un elemento è descrittivo e non può essere nessuna cosa già definita dal nomespace tal (per
esempio, conten*t o *replace). Perché tal:number non è un valido elemento XHTML, il marcatore attuale non
verrà visualizzato, ma il contenuto verrà marcato con un inutile omit-tag. Questa tecnica è molto usata in Plone
per realizzare codice che sia più piccolo, più facile da correggere, e più semantico.

6.3.2 Presentare codice pulito


HTML Tidy è un eccellente strumento per esaminare e ripulire il codice HTML che può eseguire alcuni compiti
utili. Esistono versioni di HTML Tidy per molti sistemi operativi; possiamo scaricarlo da http://tidy.sourceforge.net.
Per gli utenti Windows, trovato l’adatto download per la nostra versione Windows, decomprimiamo il file
tidy.zip e collochiamo il file tidy.exe nel nostro PATH (di default la nostra cartella Windows, come
C:\WINNT).
164 INDICE

HTML Tidy può mostrare se vi sia qualche errore XHTML nel nostro modello di pagina. Per questi scopi, una
opzione del comando (flag) può fare la differenza: -xml. Questo richiede ad HTML Tidy di processare il file come
XML e riportare qualsiasi errore XML. Dato l’esempio di modello “bad” mostrato nel listato 6-4, possiamo vedere
alcuni errori. Non solo è codice non indentato, ma si sono omesso elementi di chiusura e abbiamo annidamenti
invalidi.
Listato 6-4. Un esempio di modello di pagina “bad”: bad_template.pt

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<p>
<div>
This is bad HTML,
XHTML or XML...<a tal:contents="string: someUrl"></a>
</p>
<img>
Further it isnt indented!
</body>
</html>

Se eseguiamo il Listato 6-4 tramite HTML Tidy, vedremo gli errori nel modello ed otterremo un codice gradevol-
mente indentato, come mostra il Listato 6-5.
Listato 6-5. L’output prodotto da HTML Tidy

$ tidy -q -i bad_template.pt
line 11 column 1 - Warning: <img> element not empty or not closed
line 10 column 1 - Warning: missing </div>
line 10 column 39 - Warning: <a> proprietary attribute "tal:contents"
line 11 column 1 - Warning: <img> lacks "alt" attribute
line 11 column 1 - Warning: <img> lacks "src" attribute
line 9 column 1 - Warning: trimming empty <p>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="generator" content=
"HTML Tidy for Linux/x86 (vers 1st August 2003), see www.w3.org" />

<title></title>
</head>

<body>
<div>
This is bad HTML, XHTML or XML...<a tal:contents=
"string: someUrl"></a> <img />Further it isnt indented!
</div>
</body>
</html>
6.3. CONSIGLI UTILI 165

Le lagnanze su attributi di proprietà riservati possono essere un po’ noiose. Per controllare che il nostro modello
di pagina sia XML valido, aggiungiamo l’opzione - xml. L’output è meno verboso e indica solo i marcatori
mancanti:

$ tidy -q -xml bad_template.pt


line 15 column 1 - Error: unexpected </body> in <img>
line 16 column 1 - Error: unexpected </html> in <img>

6.3.3 Eseguire i controlli sulla sintassi


Quando modifichiamo un modello di pagina nella ZMI, Zope compie un controllo di sintassi sul documento
per cose come i marcatori non validi. Se un marcatore è invalido, un errore sarà mostrato sul modello mentre
viene compilato attraverso il web. Se, come noi (e come mostrato nel Capitolo 7), scriviamo la maggior parte
dei nostri modelli di pagina nel File System, allora è veramente utile avere un controllo di sintassi semplice per
un modello di pagina. Il Listato 6-6 è uno Script (Python) che risiede nel nostro File System ed viene eseguito
indipendentemente da Zope.
Per eseguirlo, dobbiamo avere un interprete Python, ed il modulo Python PageTemplate deve essere importabile.
Per rendere importabile PageTemplate nel nostro interprete Python dobbiamo aggiungere la il path della cartella
Products della nostra installazione Zope ai percorsi Python path. Abbiamo diversi modi di fare ciò (trattato
in ‘Appendice B‘_).
Listato 6-6. Controlli di Errore sul modello di pagina

#!/usr/bin/python
from Products.PageTemplates.PageTemplate import PageTemplate
import sys

def test(file):
raw_data = open(file, ’r’).read()
pt = PageTemplate()
pt.write(raw_data)
if pt._v_errors:
print "*** Error in:", file
for error in pt._v_errors[1:]:
print error

if __name__==’__main__’:
if len(sys.argv) < 2:
print "python check.py file [files...]"
sys.exit(1)
else:
for arg in sys.argv[1:]:
test(arg)

Per ciascun file passato allo script, la ZMI compila il modello di pagina e vediamo se c’è qualche errore TAL.
Prendendo il file bad_ template.pt dal listato 6-4, troveremo un errore:

$ python zpt.py /tmp/bad_template.pt


*** Error in: /tmp/bad_template.pt
TAL.TALDefs.TALError: bad TAL attribute: ’contents’, at line 10, column 39

In questo caso, abbiamo evidenziato una non corretta sintassi di tal:content come tal:contents. Questo errore è
qualche cosa che HTML Tidy non evidenzia. Sfortunatamente, il processo si ferma al primo errore di sintassi. Se
166 INDICE

vi sono diversi errori, solamente il primo è evidenziato, ricordiamoci allora che dobbiamo ricontrollare più volte
la sintassi.

6.4 Usare i moduli


I moduli sono una parte integrale di qualsiasi sito, e quasi ognuno ha bisogno di creare un metodo per realizzare
e modificare moduli nel proprio sito Plone. Con l’ambiente dei moduli Plone, si può cambiare la validazione
che hanno i moduli di processo, da dove prendono l’utente e così via. Questo ambiente non è specificamente
progettata solo per moduli autonomi che compiano semplici lavori, come richiedere una password, effettuare il
login e così via. L’ambiente si applica anche a tutti i tipi di contenuto, con l’obiettivo di modificarli, cosa che
tratteremo in un secondo tempo in questo libro nel Capitolo 11 e Capitolo 13.
Tutti i moduli di base hanno almeno due componenti che abbiamo già visto: un oggetto Page Template per
mostrare il modulo all’utente, ed uno oggetto Script (Python) per analizzare i risultati e eseguire l’azione sui
risultati.
La struttura di controllo del modulo presenta alcuni nuovi tipi di oggetto che sono equivalenti ai tipi che abbiamo
visto in questo capitolo. Questi sono l’oggetto Controller Page Template, l’oggetto Controller Script (Python),
ed l’oggetto Controller Validator. Questi nuovi oggetti hanno i loro equivalenti oggetti, come mostrato in Tabella
6-1. Questi nuovi oggetti possiedono ulteriori proprietà ed agiscono in modo lievemente diverso dagli oggetti
equivalenti.
Tabella 6-1. Nuovi tipi di oggetto che il Controller fornisce

Tipi di oggetti Oggetti Zope equivalenti


Controller Fileystem Page Template Page Template
Controller Python Script Python Script
Controller Validator Python Script

Per aggiungere uno di questi oggetti usando la ZMI, andiamo al box a cascata, e selezioniamo il nome.
L’ambiente del modulo di controllo crea una sequenza di eventi per un modulo che un utente può successivamente
definire. Ciò che segue è la sequenza di eventi che accadono quando si esegue un modulo:

Attenzione!
manca qualcosa nel file cap6.rst -- | Ugo

Quando questa sequenza di eventi accade, un oggetto state viene passato e contiene informazioni sullo stato
dell’oggetto, il successo di qualunque validazione e qualsiasi messaggio sia stato restituito.
Nelle sezioni seguenti rivedremo questi passi per mostrare come un modulo può essere validato e poi mostreremo
un esempio completo nella sezione Un esempio di posta elettronica: spedire una e-mail all’amministratore

6.4.1 Creare un modulo campione ed associare uno script


L’inizio di questo processo è un modulo. Sebbene questo sia in realtà un oggetto Controller Page Template, è
scritto usando codice TAL standard. Per aggiungerne uno, selezioniamo Controller Page Template dall’ormai
famigliare box a cascata e diamogli un ID test_cpt.
Un modulo Plone è un pezzo di codice davvero lungo se vogliamo utilizzare tutte le opzioni disponibili. Questo
pezzo di codice è riprodotto completamente nell’‘Appendice B‘_ ed è il codice usato nell’esempio successivo:
6.4. USARE I MODULI 167

<form method="post"
tal:define="errors options/state/getErrors"
tal:attributes="action template/id;">
...
<input type="hidden" name="form.submitted" value="1" />
</form>

Osservando questo codice, dovreste notare che per poter funzionare nell’ambiente, esistono alcune piccole dif-
ferenze fra questo e quello che si può considerare un modulo standard. Primo, il modulo è impostato per poter
inserire se stesso; questo non è opzionale. Secondo, esiste una speciale variabile nascosta; form.submitted.
L’oggetto Controller Page Template controlla la variabile request per il valore form.submitted per vedere se il
modulo sia già stato proposto (submit). Se, invece, vi è stato solo l’accesso, - per esempio attraverso un link
– questo non è opzionale. All’inizio del modulo, viene impostata la variabile errors. Il dizionario errors viene
creato dall’oggetto state che è stato passato al modello. L’oggetto state è un oggetto comune, in questo sistema,
a tutte i modelli e script.

Creare i validatori

Una volta che l’utente ha cliccato il pulsante Submit sul nostro modulo, i dati saranno inviati ai validatori per
essere validati. La validazione è opzionale. I dati non hanno bisogno di essere validati, ma chiaramente qual-
siasi applicazione dovrebbe fare ciò. La scheda Validator per un oggetto Controller Page Template ci da un
collegamento alla possibile validazione.
Uno script di validazione è identico ad un normale oggetto Script (Python) con una variabile aggiuntiva, state.
La variabile state è necessaria per poter passare i risultati della validazione. Il Listato 6-7 mostra un semplice
script di validazione per controllare se è stato fornito un numero.
Listato 6-7. Convalidare che sia stato fornito un numero

##title=A validation script to check we have a number


##parameters=
num = context.REQUEST.get(’num’, None)
try:
int(num)
except ValueError:
state.setError("num", "Not a number", new_status="failure")
except TypeError:
state.setError("num", "No number given.", new_status="failure")
if state.getErrors():
state.set(portal_status_message="Please correct the errors.")
return state

Questo oggetto state contiene informazioni basilari su ciò che è successo durante il processo di validazione.
L’oggetto state conserva gli errori per ciascun campo, lo stato, e qualsiasi altro valore. Per esempio, se il numero
dato non può essere restituito come numero intero, imposta lo stato a failure e ritorna un messaggio d’errore per
il campo usando il metodo setError. In un secondo momento questo messaggio d’errore verrà mostrato per il
campo. Alla fine dello script, qualsiasi errore restituito finora è recuperato attraverso il metodo getErrors.
Per aggiungere lo script precedente, clicchiamo portal_skin, clicchiamo custom, e scegliamo il Controller Va-
lidator dal box a cascata. Diamogli l’ID test_validator. Ora possiamo ritornare alla scheda Validation del
nostro oggetto Controller Page Template e possiamo aggiungere un puntatore a questo script di validazione,
come mostrato in Figura 6-7.
168 INDICE

Figura 6.7: Figura 6-7. Aggiungere il test_Validator all’oggetto Controller Page Template
6.4. USARE I MODULI 169

Abbiamo un paio di opzioni per la validazione. Nell’esempio li abbiamo ignorati visto che non sono attinenti,
ma ciò che segue è la lista delle opzioni:

contextType Questo è il tipo dell’oggetto context, all’occorenza, questo modello viene eseguito dentro. Questa
è una scorciatoia al tipo di contenuto dell’oggetto context. Se vogliamo eseguire solo questa validazione
su un collegamento, allora possiamo mettere questo valore a Link.
button Questo è il pulsante, che, all’occorenza, viene cliccato per sottoporre il modulo. Possiamo avere diversi
pulsanti su un modulo (per esempio, un pulsante Submit ed uno Cancel). Ciascuno di questi pulsanti può
poi mappare una diversa azione; cliccando Cancel si può andare in un posto, e cliccando Submit andare in
un altro.
validators Questo è un lista di validatori separati da una virgola, che sono gli oggetti Controller Validator che
il modello acquisirà. Nell’esempio precedente, usiamo l’ID per il validatore: test_validator.

Nota
Quando si scrivono script di validazione, usiamo l’oggetto Controller Validator invece di
unoggetto Script (Python). Gli oggetti Controller Validator sono proprio ordinari oggetti Script
(Python) con un’addizionale scheda ZMI Actions.

Specificare azioni

Le Actions sono le azioni finali dopo che i validatori sono stati eseguiti, e dipendono dallo stato che viene resti-
tuito dalla validazione. La scheda Actions per un oggetto Controller Page Template mostra tutte le azioni per il
modello di pagina in questione. Possiamo specificare azioni con lo stesso genere delle opzioni di specializzazione
come descritto precedentemente attraverso un modulo web, come mostrato in Figura 6-8.

Abbiamo le seguenti quattro opzioni per l’attuale azione risultante:

redirect_to Questo reindirizza all’URL specificata nell’argomento (un’espressione TALES). L’URL può essere
assoluta o relativa.

redirect_to_action

Questo reindirizza all’azione specificata nell’argomento (un’espressione TALES) per il corrente og-
getto contenuto (per esempio, string:view). In questa fase non abbiamo trattato ancora azioni, ma
qualsiasi oggetto contenuto ha azioni come view ed edit. Il Capitolo 11 tratta le azioni per un
oggetto.

traverse_to Questo traversa l’URL specificata nell’argomento (un’espressione TALES). L’URL può essere as-
soluta o può essere relativa.
traverse_to_action Questo traversa l’azione specificata nell’argomento (un’espressione TALES) per il corrente
oggetto contenuto (per esempio, string:view).

Un esempio di ciò è che se il riempimento del modulo avviene con successo, attraversiamo un oggetto Controller
Python Script che abbiamo scritto il quale processa il risultato del modulo. Se la pagina da un errore, torniamo
ad attraversare il modello e visualizzamo l’errore.
La differenza tra un reindirizzamento ed un attraversamento è che il reindirizzamento è una redirezione dell’HTTP
spedito al browser dell’utente. Il browser lo processa e manda quindi l’utente alla pagina successiva. Quindi,
le’azioni di reindirizzamento perdono tutti i valori passati dalle richieste originali. Se abbiamo bisogno di esa-
minare i contenuti del modulo originale, questo non è l’approccio migliore. Invece, raccomandiamo di usare le
opzioni di attraversamento. Il risultato è lo stesso; solo che la scelta di attraversare esegue tutto sul server. Così
facendo preserva le variabili request e permette di esaminarle con gli script.
170 INDICE

Figura 6.8: Figura 6-8. Aggiungere un’azione


6.4. USARE I MODULI 171

6.4.2 Un esempio di posta elettronica: spedire una e-mail all’amministratore


Vedremo ora un vero esempio ed utilizzeremo il resto di questo capitolo per costruirlo. Un’esigenza comune
è un modulo personale che spedisce un e-mail al Webmaster. Costruiremo questo tipo di modulo nelle sezioni
seguenti. Lo script completo, il modello di pagina, ed il codice associato sono disponibili nell’‘Appendice B‘_.
Se non vogliamo realmente digitare tutto questo, possiamo vedere questo esempio on-line sul sito Web del libro;
ed inoltre possiamo scaricarlo come file compresso dal sito Web del libro Plone (http://plone-book.agmweb.ca)
e dal sito web Apress (http://www.apress.com), così possiamo installarlo da soli e possiamo provarlo. Questo
esempio ha solo due campi nel modulo: la e-mail della persona che sottopone il modulo ed i commenti di questa
persona. In questo modulo viene richiesta la e-mail della persona , così potremo rispondere ai suoi commenti.

Costruire il modulo

Il modulo è la parte più grande e più complicata di questa procedura, soprattutto perché v’è tanto lavoro da
fare per supportare la gestione degli errori. Questo modulo è un oggetto Controller Page Template chiamato
feedbackForm. Per assicurarsi che sia contenuto nel modello principale, inizieremo il modulo in un metodo
standard:

<html
xmlns="http://www.w3.org/1999/xhtml"
xml:lang="en-US"
lang="en-US"
i18n:domain="plone"
metal:use-macro="here/main_template/macros/master">
<body>
<div metal:fill-slot="main"
tal:define="errors options/state/getErrors;">

Un’aggiunta opzionale qui è errors options/state/getErrors che posiziona qualsiasi cosa e tutti gli errori all’in-
terno della variabile locale per usi futuri.
A causa del requisito del modulo di poter far riferimento indietro a se stesso, viene impostata questa azione in
TAL, con l’espressione template/id. Questo percorso estrae l’ID del modello e lo inserisce nell’azione, così che
questo percorso funzionerà sempre, anche se rinominiamo il modello. Notiamo che stiamo aggiungendo anche
marcatori i18n per essere sicuri che questo modulo possa essere localizzato:

<form method="post"
tal:attributes="action template/id;">

<legend i18n:translate="legend_feedback_form">
Website Feedback
</legend>

Ciò che segue è l’inizio della riga dell’indirizzo e-mail. Definiamo qui una variabile chiamata error_email_address
che posizionerà una stringa di errore se v’è una stringa appropriata nel dizionario errors. Quel valore di errore
sarà generato dal validatore qualora dovesse generarsi un errore là:

<div class="field"
tal:attributes="class python:test(error_email_address,
’field error’, ’field’)">
tal:define="error_email_address errors/email_address|nothing;">

La seguente è l’etichetta per il campo indirizzo e-mail. In questa etichetta includeremo un div per il testo di aiuto.
L’elemento span diventa ora il familiare punto rosso vicino all’etichetta così che l’utente sappia che è richiesto:
172 INDICE

<label i18n:translate="label_email_address">Your email address</label>


<span class="fieldRequired" title="Required">(Required)</span>
<div class="formHelp"
i18n:translate="label_email_address_help">
Enter your email address.
</div>

Successivamente aggiungeremo l’elemento attuale:

<div tal:condition="error_email_address">
<tal:block i18n:translate=""
content="error_email_address">Error
</tal:block>
</div>
<input type="text" name="email_address"
tal:attributes="tabindex tabindex/next;
value request/email_address|nothing" />
</div>

All’inizio di questo blocco, esamineremo per vedere se c’è un errore. Se c’è, la classe per l’elemento cambiato
sarà la classe field error; questa classe mostrerà una bel riquadro arancio attorno al campo. Successivamente,
se è accaduto un errore in questa zona (come abbiamo già sperimentato), sarà visualizzato il corrispondente
messaggio. Finalmente, mostrerà l’elemento del modulo, e se v’è un valore per email_address già nella richiesta,
popolerà l’elemento del modulo con quel valore.
Il tabindex è un utile strumento di Plone. Contiene un numero sequenziale che viene incrementato per ogni
elemento, e ogni volta imposta un nuovo valore HTML tabindex per ciascun elemento nel modulo. Questa è una
bella caratteristica per l’interfaccia utente; vuole dire che ciascun elemento del modulo può essere salvato senza
doversi preoccupare di ricordare il numero tabindex perché questo viene generato automaticamente.
Questo è un grosso lavoro per un elemento, ma è soprattutto codice pronto all’uso (boilerplate); possiamo
facilmente copiarlo o possiamo cambiarlo. Possiamo trovare il resto del modulo nell’‘Appendice B‘_.

Creare un validatore

Nell’esempio abbiamo solamente un elemento richiesto (la e-mail), così è un semplice pezzo di Python chiamato
validEmail.vpy ad eseguire il lavoro. I contenuti di questo script sono i seguenti:

email = context.REQUEST.get(’email_address’, None)


if not email:
state.setError(’email_address’, ’Email is required’,
new_status=’failure’)
if state.getErrors():
state.set(portal_status_message=’Please correct the errors.’)
return state

Se nessun indirizzo e-mail può essere trovato, questo script aggiunge un errore al dizionario degli errori con
la chiave email_address ed un messaggio. Questa chiave è usata nel modello di pagina per vedere se è stato
generato un errore in quel particolare campo.

Eseguire lo script

Questo esempio ha un semplice script e-mail che restituisce i valori (che sono già convalidati) e realizza un indi-
rizzo e-mail da questi. Questo è un oggetto Controller Python Script; proprio come un oggetto Script (Python)
6.4. USARE I MODULI 173

standard con una variabile aggiuntiva state, e, come un Controller Page Template, possiamo fornirgli azioni per
quando esso viene invocato:

mhost = context.MailHost
emailAddress = context.REQUEST.get(’email_address’)
administratorEmailAddress = context.email_from_address
comments = context.REQUEST.get(’comments’)

# the message format, %s will be filled in from data


message = """
From: %s
To: %s
Subject: Website Feedback

%s
URL: %s """

# format the message


message = message % (
emailAddress,
administratorEmailAddress,
comments,
context.absolute_url())

mhost.send(message)

Ora abbiamo visto una semplice script per spedire posta elettronica. Questa è un comune script che vedremo
spesso. Fondamentalmente, gli oggetti MailHost in Plone prendono una e-mail come una stringa, affinché sia
conforme alla specifica Request for Comment (RFC) per la e-mail che ha gli indirizzi From e To.
In questa e-mail, prende l’indirizzo dell’amministratore che abbiamo specificato nella configurazione del por-
tale e spedisce la posta elettronica a quella persona. L’unica parte addizionale di questo script è aggiungere
L’impostazione dello stato. Questo prepara un messaggio che fornisce alcuni feedback all’utente:

screenMsg = "Comments sent, thank you."


state.setKwargs( {’portal_status_message’:screenMsg} )
return state

Assemblare le tre parti

Al momento, comunque viene richiesta la e-mail della persona , così potremo rispondere ai suoi commenti.

Costruire il modulo

Il modulo è la parte più grande e più complicata di questa procedura, soprattutto perché v’è tanto lavoro da
fare per supportare la gestione degli errori. Questo modulo è un oggetto Controller Page Template chiamato
feedbackForm. Per assicurarsi che sia contenuto nel modello principale, inizieremo il modulo in un metodo
standard:

<html
xmlns="http://www.w3.org/1999/xhtml"
xml:lang="en-US"
174 INDICE

lang="en-US"
i18n:domain="plone"
metal:use-macro="here/main_template/macros/master">
<body>
<div metal:fill-slot="main"
tal:define="errors options/state/getErrors;">

Un’aggiunta opzionale qui è errors options/state/getErrors che posiziona qualsiasi cosa e tutti gli errori all’in-
terno della variabile locale per usi futuri.
A causa del requisito del modulo di poter far riferimento indietro a se stesso, viene impostata questa azione in
TAL, con l’espressione template/id. Questo percorso estrae l’ID del modello e lo inserisce nell’azione, così che
questo percorso funzionerà sempre, anche se rinominiamo il modello. Notiamo che stiamo aggiungendo anche
marcatori i18n per essere sicuri che questo modulo possa essere localizzato:

<form method="post"
tal:attributes="action template/id;">

<legend i18n:translate="legend_feedback_form">
Website Feedback
</legend>

Ciò che segue è l’inizio della riga dell’indirizzo e-mail. Definiamo qui una variabile chiamata error_email_address
che posizionerà una stringa di errore se v’è una stringa appropriata nel dizionario errors. Quel valore di errore
sarà generato dal validatore qualora dovesse generarsi un errore là:

<div class="field"
tal:attributes="class python:test(error_email_address,
’field error’, ’field’)">
tal:define="error_email_address errors/email_address|nothing;">

La seguente è l’etichetta per il campo indirizzo e-mail. In questa etichetta includeremo un div per il testo di aiuto.
L’elemento span diventa ora il familiare punto rosso vicino all’etichetta così che l’utente sappia che è richiesto:

<label i18n:translate="label_email_address">Your email address</label>


<span class="fieldRequired" title="Required">(Required)</span>
<div class="formHelp"
i18n:translate="label_email_address_help">
Enter your email address.
</div>

Successivamente aggiungeremo l’elemento attuale:

<div tal:condition="error_email_address">
<tal:block i18n:translate=""
content="error_email_address">Error
</tal:block>
</div>
<input type="text" name="email_address"
tal:attributes="tabindex tabindex/next;
value request/email_address|nothing" />
</div>
6.4. USARE I MODULI 175

All’inizio di questo blocco, esamineremo per vedere se c’è un errore. Se c’è, la classe per l’elemento cambiato
sarà la classe field error; questa classe mostrerà una bel riquadro arancio attorno al campo. Successivamente,
se è accaduto un errore in questa zona (come abbiamo già sperimentato), sarà visualizzato il corrispondente
messaggio. Finalmente, mostrerà l’elemento del modulo, e se v’è un valore per email_address già nella richiesta,
popolerà l’elemento del modulo con quel valore.
Il tabindex è un utile strumento di Plone. Contiene un numero sequenziale che viene incrementato per ogni
elemento, e ogni volta imposta un nuovo valore HTML tabindex per ciascun elemento nel modulo. Questa è una
bella caratteristica per l’interfaccia utente; vuole dire che ciascun elemento del modulo può essere salvato senza
doversi preoccupare di ricordare il numero tabindex perché questo viene generato automaticamente.
Questo è un grosso lavoro per un elemento, ma è soprattutto codice pronto all’uso (boilerplate); possiamo
facilmente copiarlo o possiamo cambiarlo. Possiamo trovare il resto del modulo nell’‘Appendice B‘_.

Creare un validatore

Nell’esempio abbiamo solamente un elemento richiesto (la e-mail), così è un semplice pezzo di Python chiamato
validEmail.vpy ad eseguire il lavoro. I contenuti di questo script sono i seguenti:

email = context.REQUEST.get(’email_address’, None)


if not email:
state.setError(’email_address’, ’Email is required’,
new_status=’failure’)
if state.getErrors():
state.set(portal_status_message=’Please correct the errors.’)
return state

Se nessun indirizzo e-mail può essere trovato, questo script aggiunge un errore al dizionario degli errori con
la chiave email_address ed un messaggio. Questa chiave è usata nel modello di pagina per vedere se è stato
generato un errore in quel particolare campo.

Eseguire lo script

Questo esempio ha un semplice script e-mail che restituisce i valori (che sono già convalidati) e realizza un indi-
rizzo e-mail da questi. Questo è un oggetto Controller Python Script; proprio come un oggetto Script (Python)
standard con una variabile aggiuntiva state, e, come un Controller Page Template, possiamo fornirgli azioni per
quando esso viene invocato:

mhost = context.MailHost
emailAddress = context.REQUEST.get(’email_address’)
administratorEmailAddress = context.email_from_address
comments = context.REQUEST.get(’comments’)

# the message format, %s will be filled in from data


message = """
From: %s
To: %s
Subject: Website Feedback

%s
URL: %s """

# format the message


176 INDICE

message = message % (
emailAddress,
administratorEmailAddress,
comments,
context.absolute_url())

mhost.send(message)

Ora abbiamo visto una semplice script per spedire posta elettronica. Questa è un comune script che vedremo
spesso. Fondamentalmente, gli oggetti MailHost in Plone prendono una e-mail come una stringa, affinché sia
conforme alla specifica Request for Comment (RFC) per la e-mail che ha gli indirizzi From e To.
In questa e-mail, prende l’indirizzo dell’amministratore che abbiamo specificato nella configurazione del por-
tale e spedisce la posta elettronica a quella persona. L’unica parte addizionale di questo script è aggiungere
L’impostazione dello stato. Questo prepara un messaggio che fornisce alcuni feedback all’utente:

screenMsg = "Comments sent, thank you."


state.setKwargs( {’portal_status_message’:screenMsg} )
return state

Assemblare le tre parti

Al momento, comunque esistono tre entità separate: un modulo, un validatore ed uno script d’azione. Ora hanno
bisogno di essere assemblati per formare una concatenazione, per questo dobbiamo ritornare all’oggetto Control-
ler Template. Clicchiamo la scheda Validator, e digitiamo un nuovo validatore che punti allo script validEmail.
Aggiungiamo inoltre un’azione di successo per quando il processo abbia correttamente traversato lo script sen-
dEmail. Sullo script sendEmail, ora possiamo aggiungere un altro traversamento di ritorno a feedbackForm così
che dopo che viene eseguita correttamente sendEmail, l’utente sarà rispedito alla pagina originale.

Nota
Uno script di validazione e-mail molto più completo appare in Plone chiamando
validate_emailaddr che controlla che la posta elettronica sia nel formato corretto. Se
vogliamo usare invece questo script, possiamo puntare il validatore ad esso.

Questo è fatto! Ora dovremmo essere capaci di esaminare il modulo sul sito web del libro. Per renderlo più
facile, abbiamo fatto una scheda FeedBack, che punta al modello feedbackForm e da qui ora possiamo fornire un
feedBack su questo libro!
Capitolo 7

Capitolo 7: Personalizzare l’aspetto di


Plone

177
178 CAPITOLO 7. CAPITOLO 7: PERSONALIZZARE L’ASPETTO DI PLONE
Indice

Note alla traduzione del capitolo


layer: livello
Page Template: Modelli di pagina
skin: skin, pelle, aspetto
breadcrumbs: briciole

Nei precedenti due capitoli abbiamo trattato alcune delle componenti essenziali dell’interfaccia utente di Plone
compresi gli aggetti Script (Python) e i modelli di pagina. È il momento di trattare esattamente come si costruisce
l’aspetto di un sito Plone. Questo capitolo include gli oggetti dei precedenti capitoli e ne introduce di nuovi.
Per partire vediamo tutte le definizioni chiave e gli elementi compresi in un sito Plone. Riparleremo di termini già
sentiti come skin e livelli. Poi tratteremo la personalizzazione dell’interfaccia utente concentrandoci sulla potenza
messa a disposizione dello sviluppatore del sito dal foglio di stile (Cascading Style Sheet - CSS). Parleremo
delle variabili chiave e di come sia possibile cambiarle. Riparleremo poi della personalizzazione del logo e degli
elementi dello skin mettendo insieme tutti gli argomenti di cui abbiamo parlato nei tre capitoli precedenti.
Poi mostreremo come realizzare un nuovo skin e spiegheremo le tecniche per sviluppare tutto questo sul file-
system.
Per terminare finiremo il capitolo con un sito di esempio. Mostreremo specificamente il sito Maestro che è stato
utilizzato dalla NASA per distribuire dati riguardo i rover su Marte. Quello è un sito ad alto traffico realizzato con
Plone e lo skin che usa è un caso interessante per la personalizzazione di un sito. Questo esempio reale su come
si può personalizzare e modificare un sito Plone faciliterà la personalizzazione del proprio sito.

7.1 Introduzione agli Skin di Plone


Quando viene mostrato un documento in Plone, il contenuto di quel documento appare nell’ormai famigliare
interfaccia verde e blu. Uno skin determina esattamente come deve essere mostrato all’utente quel documento,
incluse le immagini e gli stili che circondano il contenuto. Uno skin per gruppi di elementi, riveste quel pezzo di
contenuto e lo presenta in una determinata maniera.
Per generare la rappresentazione che vede l’utente, uno skin include vari elementi, inclusi elementi statici, come
delle immagini, e pezzi dinamici, come gli script. Nel precedente capitolo, il modulo per il feedback era un
esempio che aggiungeva alcuni elementi allo skin per crearne uno nuovo. Quell’esempio conteneva la logica sotto
forma di un’oggetto Python (script) e nuove pagine sotto forma di modello di pagina (page template).
Abbiamo aggiunto quegli elementi allo skin per consentire all’utente di interagire tramite il modulo.

179
180 INDICE

È possibile assemblare un nuovo skin per Plone utilizzando più o meno elementi di uno già esistente. Si possono
fare piccoli aggiustamenti o profonde modifiche allo skin come si può notare girando per i siti della comunità
come per esempio http://www.zopezen.org e http://www.zopera.org. Ogni sito Plone deve possedere perlomeno
uno skin da utilizzare come default ma può avere quanti skin vogliono gli sviluppatori. Un utente può eventual-
mente passare da uno skin all’altro, se lo sviluppatore del sito ha previsto di renderlo possibile, ma questo caso è
applicato raramente.
Lo skin Plone predefinito è quello che si può vedere su un sito Plone come http://www.plone.org, con la famigliare
interfaccia verde e blu. Ma Plone non deve necessariamente apparire così o essere vagamente somigliante ad un
sito Plone (standard n.d.t.), il suo aspetto è completamente nelle nostre mani. Prendiamo per esempio l’elenco
dei siti che si vede in http://www.plone.org/about/sites; ciascuno di quei siti mostra una differente personale
esperienza per l’utente. In molti casi quei siti possono passare da uno skin ad un altro e mostrare all’utente
aspetti differenti. Altri siti usano la potenza e la flessibilità insita nell’interfaccia di Plone per creare e modificare
i contenuti internamente mentre mostrano un aspetto completamente differente agli utenti esterni.
Abbiamo visto molte discussioni su questo nelle mailing list; “Plone deve avere un aspetto simile ad un sito
Plone (predefinito n.d.t.)?”, “Può essere mostrato in un modo ad un utente ed in un altro ad un altro utente?”,
“Può avere l’aspetto del proprio sito aziendale?” La risposta a tutte queste domande è “si”: l’unico limite è la
propria immaginazione (ed il tempo che si è disposti a impiegare nella personalizzazione del proprio sito).

7.1.1 Uso dei livelli dentro uno Skin


Uno skin è suddiviso per collezioni logiche di modelli e di script dette livelli. La modifica di queste singole col-
lezioni consente la semplice aggiunta o la rimozione di elementi da parte dell’utente. I livelli sono rappresentati
in uno skin con un elenco gerarchico di cartelle. A ciascun livello corrisponde un nome di una cartella, ed ogni
cartella contiene gli elementi dello skin.
Per esempio uno skin può avere i seguenti livelli:

custom, gruf, plone_ecmascript, plone_wysiwyg ...

L’ordine dei livelli di quest’elenco è la chiave di come Plone trova gli elementi. Quando viene richiesto un
elemento dallo skin, come per esempio l’immagine logo.jpg, lo skin guarda tra i livelli per trovarla. Lo skin parte
cercando nel primo livello assegnato (nel nostro esempio custom). Se lo skin non riesce a trovare l’elemento nel
primo livello, passa al secondo (nell’esempio gruf ). Poi prosegue cercando nell’elenco dei livelli fino a che non
trova l’elemento cercato. Se non trova quell’elemento solleva un errore 404 e lo passa al browser.
Un concetto simile in molti sistemi è l’uso della variabile d’ambiente PATH. Quando si lancia un comando o si
cerca un programma il sistema operativo cerca nelle cartelle del file system specificate nella variabile PATH. Un
approccio simile lo si ha con i livelli, quando i livelli sono attraversati alla ricerca di un certo elemento.
Predisponendo la precedenza dei livelli superiori rispetto a quelli sotto, gli sviluppatori e gli amministratori
possono quindi personalizzare e manipolare il proprio sito tramite i livelli. Se non si desidera un particolare
elemento di uno skin Plone, spostandolo in un livello, è possibile deciderne la modalità di visualizzazione. È
possibile ordinare i propri livelli con lo strumento portal_skins che affronteremo di seguito.

7.1.2 Gestire gli Skin con lo strumento portal_skins


In Plone per definire le caratteristiche dello skin e dei livelli si usa lo strumento portal_skins. Lo strumento
portal_skins fornisce inoltre un servizio ed una API (application programming interface) per la creazione e
l’uso degli skin.
Per accedere allo strumento portal_skins si va nella interfaccia di Zope ZMI e si clicca su portal_skins. Ci sono
due schermate chiave nella ZMI; la prima, la scheda Contents, mostra tutte le cartelle e viste delle directory del
file system (FSDVs) posizionate dentro questo strumento (vedere Figura 7-1).
7.1. INTRODUZIONE AGLI SKIN DI PLONE 181
182 INDICE

Figura 7-1. I contenuti dello strumento portal_skins in una installazione Plone standard
Non tutte le cartelle o le viste delle directory del file system della scheda Contents sono livelli, ma è possibile
trasformarle in livelli. Inoltre, la seconda importante schermata, la scheda Properties, mostra tutti gli skin e livelli
definiti nel proprio sito Plone (vedere la Figura 7-2).

Figura 7-2. Gli skin e i livelli di una installazione Plone standard


Come mostra la figura 7-2, l’elenco di questi livelli è abbastanza lungo. Sebbene ciò intimidisca, questo gran
numero di livelli permette allo sviluppatore un grado di flessibilità e di riusabilità notevole. Ciascuno skin è
mostrato sulla sinistra con una propria area di testo sulla destra contenente i livelli di quello skin. Come detto in
precedenza, Plone, per trovare elementi, ricerca nei livelli dall’inizio alla fine. Ciascun livello è il nome di una
cartella o di un FSDV della scheda Contents. Nella Figura 7-2 si vede una cartella plone_ecmascript e in
Figura 7-1 c’è l’oggetto FSDV corrispondente.
Un FSDV è un nuovo oggetto di Plone che offre una utile funzionalità; consente l’accesso diretto agli elementi
dello skin che sono stati definiti nel file system piuttosto che nel database ad oggetti di Zope , come d’abitudine.
FSDV rende facili lo sviluppo e la personalizzazione. Leggendo direttamente gli oggetti dal file system, per gli
sviluppatori è molto più semplice scrivere o modificare il codice che genera il sito. Quando si installa Plone lo
skin viene scritto dentro il file system. Quando si personalizza un oggetto se ne fa una copia locale dentro il
database di Plone. L’uso di un FSDV consente di mantenere una netta separazione tra il codice scaricato dalla
rete ed il codice personalizzato nella propria istanza locale.
Plone 2 è fornito con due skin, Plone predefinito e Plone Tableless. Lo skin Plone predefinito usa le tabelle per
rendere il corpo principale affiancato da due celle di tabella dalle parti contenenti i riquadri (slot) di destra e di
sinistra. Per compatibilità con i browser questa è l’impostazione predefinita. Comunque, cambiando a Plone
Tableless, si ottiene uno skin che sembra uguale tranne che non ci sono tabelle che producono la pagina, il che
ci da, come sviluppatori del sito, maggiore flessibilità. Mentre scriviamo lo skin Plone Tableless da un po’
di problemi con alcuni browser, tipo Internet Explorer. Speriamo che in futuro lo skin Plone Tableless possa
diventare lo skin predefinito di Plone.
Per cambiare lo skin scorrere fino al fondo del modulo dove si trova lo skin predefinito e selezionare lo skin di de-
fault dall’elenco di scelte. Selezionando l’opzione Skin Flexibility gli utenti potranno scegliere successivamente
un proprio skin dalla sezione preferenze personali
Ritornando nella scheda Contents dello strumento portal_skins si può notare che alcune delle cartelle, la custom
per esempio, sono cartelle standard di Zope. Hanno infatti la normale icona delle cartelle. Altre, per esempio
plone_images, sono viste FSDV che puntano ad aree del file system. Queste hanno la stessa icona delle
cartelle ma con un lucchetto verde dentro. Questo lucchetto indica che non è possibile aggiungere o modificare
degli elementi di una vista FSDV tramite web; è possibile farlo solo tramite il file system.
Per capire dove risiedono i file di una vista FSDV nel proprio disco rigido cliccare sulla scheda Properties
dell’FSDV. Per esempio dalla scheda Contents dello strumento portal_skins cliccare Properties e verrà elen-
cato il path del file system di CMFPlone/skins/plone_images. Questo path è la posizione di questa
cartella sul file system relativo alla istanza principale specificata nel processo di installazione. Siccome si pos-
sono vedere i file tramite il web nell’FSDV oppure dal file system, per leggerli vi si può accedere in entrambi i
modi. E siccome visualizzare file tramite il file system è decisamente piu amichevole e facile, ci riferiamo ad un
file come al path di un file system, a cui si può accedere con strumenti famigliari.

7.2 Personalizzare gli Skin


Abbiamo visto come interagiscono skin e livelli. Ora vediamo come personalizzare un sito Plone. Iniziamo
ritornando all’esempio del Capitolo 4 dove abbiamo imparato a personalizzare il logo. Usando le conoscenze
acquisite su come funzionano gli skin, sapremo proseguire e personalizzare lo skin. Continueremo poi mostrando
la potenza del CSS di Plone e come personalizzarlo. Infine tratteremo il modello di pagina principale (main
template) che abbiamo già visto nei precedenti capitoli e ripasseremo tutti i suoi elementi.
7.2. PERSONALIZZARE GLI SKIN 183
184 INDICE

7.2.1 Personalizzare il Logo, ripetizione


Nel Capitolo 4 abbiamo imparato come personalizzare il logo dell’angolo in alto a sinistra del sito Plone ma
abbiamo sorvolato su cosa realmente accade. Questa sezione rivisita quell’esempio.
L’immagine logo.jpg è l’immagine che appare in ogni pagina nell’angolo in alto a sinistra. Vediamo quindi cosa
succede quando un browser cerca di visualizzare questa pagina. Quando Plone riceve la richiesta di quella im-
magine egli cerca tra i livelli per trovare logo.jpg. In un sito predefinito c’è un elemento in plone_images
denominato logo.jpg. Siccome questo è un oggetto FSVD, come detto precedentemente, non è possibile mo-
dificare l’immagine via web. In vista di future modifiche al sito non si vorrà neppure modificarlo sul file system.
Guardiamo meglio cosa fa il pulsante Customize. Se guardiamo nuovamente questo pulsante possiamo vedere
che c’è, a sinistra del pulsante, un elenco di scelta di cartelle contenute nello strumento portal_skins.

Nota
Le cartelle elencate sono quelle esistenti nel database di Zope. Le viste FSDV non sono
incluse nell’elenco; per default vengono mostrate solo cartelle.

Cliccando sul pulsante Customize si crea una copia nella cartella locale dell’elemento selezionato nell’elenco di
scelta. Per default questa è la cartella custom, quidi ora avremo una copia nella cartella custom. Quando Plone
cerca l’elemento logo.jpg, accede alla versione della cartella custom. Guardando nuovamente i livelli dello
skin predefinito di Plone, la cartella custom è il livello in cima allo skin. Quando viene chiamato logo.jpg
verrà trovata l’immagine nel livello personalizzato (custom). Così è come viene reso il nuovo logo.jpg.
Mettere elementi personalizzati nella cartella custom è la strada più veloce per iniziare a distinguere il proprio
sito Plone. La cartella custom è una cartella Plone standard ed è quindi possibile inserirvi quanti elementi si
vogliono per sovrascrivere gli elementi precedenti.

7.2.2 Introduzione al foglio di stile (CSS) di Plone


La rappresentazione visiva di un sito Plone in un browser è messa insieme quasi interamente usando il CSS.
Forse il miglior sistema per capire cosa fa il CSS per un sito Plone è quello di paragonare la Figura 7-3 con la
Figura 7-4. La prima mostra Plone con il foglio di stile, e la seconda mostra Plone senza alcun foglio di stile.

Figura 7-3. Plone con foglio di stile

Figura 7-4. Plone senza foglio di stile

Consiglio
Se si desidera riprodurre questa visualizzazione, rimuovere l’uso del foglio di sti-
le dal browser. Internet Explorer non consente di farlo facilmente ma Firefox
(http://www.mozilla.org/products/firefox/), il browser a sorgente aperto basato su Mozilla, lo
fa facilmente. In Firefox selezionare Tools - Web Developer - Disable - Disable Styles. Col
suo grande uso di CSS ed altri numerosi strumenti di sviluppo, Firefox è il browser scelto da
molti sviluppatori.

La differenza non è da poco. Il CSS determina non solo la rappresentazione visiva della pagina ma anche il suo
aspetto. Cambiando il CSS è possibile modificare questa rappresentazione e l’aspetto di un sito Plone (con i
vincoli del CSS).
Realizzare l’aspetto di Plone utilizzando il CSS è una impressionante attività svolta da talentuosi utenti svilup-
patori di interfacce. Quelli che seguono sono alcuni dei benefici dell’usare il CSS per determinare l’aspetto:
7.2. PERSONALIZZARE GLI SKIN 185
186 INDICE
7.2. PERSONALIZZARE GLI SKIN 187

• Il CSS fornisce un livello di separazione tra la presentazione ed il modello di pagina che genera
la presentazione.
• È possibile effettuare molte modifiche senza dover toccare il sottostante modello di pagina.
Tutto quello che serve è un esperto sviluppatore di CSS.
• Il CSS rende più veloce il sito poiché invia file più piccoli. Ciascun file HTML (Hypertext
Markup Language) è più piccolo di quanto l’aspetto del sito non è descritto nell’HTML bensì
nel CSS, che può essere mantenuto nella cache.
• Il CSS consente di personalizzare l’aspetto senza rompere il sottostante lavoro sull’accessibi-
lità.

Livelli del codice

Quando viene resa una pagina Plone sono almeno tre i livelli di codice che creano la pagina. Per esempio, per le
schede che appaiono in cima ad un sito Plone, questo è il modo come vengono assemblate:

Attenzione!
????? manca qc??? <lallo>

Quindi piuttosto che chiedersi come é possibile personalizzare le schede, è meglio decidere esattamente quale
personalizzazione vogliamo fare. Ciò può significare modificare il CSS, l’HTML, i dati o le schede sottostanti.
Le regole generali sono le seguenti:

Attenzione!
????? manca qc??? <lallo>

In effetti Plone è talmente personalizzabile, a così tanti livelli, che è frequente chiedersi quale sia il punto da
personalizzare. Per essere sicuri che future modifiche nei modelli di pagina di Plone non compromettano il
design delle nostre applicazioni cerchiamo di non modificare i modelli. Si raccomanda invece di provare a
lavorare prima sul CSS e sulle azioni. In questo modo, quando i modelli cambieranno in versioni future di Plone,
vi sarà meno possibilità che nasca un problema.

7.2.3 Personalizzare caratteri, colori e spaziature


Il foglio di stile attuale che fa gran parte del lavoro, plone.css, contiene numerose variabili inserite usando il
DTML, l’HTML dinamico (Dynamic HTML ). In questo libro non trattiamo il DTML; questo è probabilmente l’u-
nico uso che se ne fa in Plone, quindi non è necessario conoscerlo già, e, se possibile, raccomandiamo di evitare
di studiarlo! Il sistema Zope Page Templates ha tutto quello che ci serve. In rete esistono dei riferimenti eccel-
lenti al DTML per Zope; riferirsi comunque a http://docit.bice.dyndns.org/static/Zope/ZopeBook/DTMLBase.rst
(http://zope.org/Documentation/Books/ZopeBook/2_6Edition/DTML.stx).
La sintassi DTML di questo foglio di stile è veramente semplice; ciascuna variabile è correlata ad un corri-
spondente attributo di un foglio di proprietà. Per accedere a questo foglio di proprietà cliccare su portal_skins,
plone_styles e poi su base_properties. Nella Figura 7-5 si vede come questo file viene mostrato nella ZMI.

Figura 7-5. Le proprietà base del foglio di stile


Per esempio, dtml-fontColor; individua la variabile fontColor e la mette nel foglio di stile in modo che qui
fontColor è black. Ora possiamo vedere dove la variabile è referenziata nel file plone.css. Per accedere al file
CSS, cliccare su portal_skins, plone_styles e poi plone.css. In questo file è possibile vedere che mainFontColor
è referenziata in più punti, per esempio è referenziata nel corpo di una pagina; in questo modo:
188 INDICE
7.2. PERSONALIZZARE GLI SKIN 189

body {
font: dtml-fontBaseSize; <dtml-var fontFamily>;
background-color: dtml-backgroundColor;;

color: dtml-fontColor;;

margin: 0;
padding: 0;
}

Si può continuare a leggere il foglio di stile, se si vuole realmente, ma cambiare la variabile è sempre il modo
più rapido per vedere esattamente su cosa interviene.
Ritornare alla ZMI, cliccare portal_skin cliccare su plone_styles, cliccare poi base_properties e quindi cliccare
il bottone Customize. Come si potrà vedere, questo creerà un oggetto nella ZMI che è possibile personalizzare.
Questa volta l’oggetto personalizzato è davvero una cartella che ha le proprietà contenute nella cartella. Per
accedere alle proprietà che abbiamo appena personalizzato, cliccare portal_skin, cliccare custom e quindi cliccare
base_properties. In seguito, selezionare la scheda Properties (vedere Figura 7-6).

Figure 7-6. Le proprietà della cartella


Questa elenco di proprietà permette di modificare le proprietà di mainColor a qualche cosa di differente, per
esempio red o #cc9900. Cambiare il valore di quella proprietà, e cliccare Save Changes. Ritornando al sito
Plone, si dovrebbe quindi vedere il nuovo gradevole colore .
Nel Capitolo 4 abbiamo visto un esempio dove, per cambiare una scheda in cima ad una pagina, gli utenti possono
cambiare le azioni. Anche se è possibile inserire un’azione con il primo carattere maiuscolo (come Members)
questa viene poi visualizzate in lettere minuscole nella pagina web. Questo perché il CSS trasforma il testo in
minuscolo per via della proprietà textTransform nel foglio delle proprietà. Per bloccare questa trasformazione,
cambiare la proprietà textTransform a none.
Nel foglio di stile, le proprietà sono definite per tutti i colori, la spaziatura, ed il tipo di carattere usati in un sito
Plone. La tabella 7-1 descrive tutti i parametri.
Tabella 7-1. Proprietà del CSS

Nome della variabile Descrizione


logoName Il nome del file del logo del portale
fontFamily La famiglia di caratteri usata per il testo che è un’intestazione
fontBaseSize La dimensione dei caratteri in base alla quale viene calcolato tutto
fontColor Il colore principale dei caratteri
backgroundColor Il colore di sfondo
linkColor Il colore usato per i collegamenti normali
linkActiveColor Il colore usato per i collegamenti attivi
linkVisitedColor Il colore usato per i collegamenti visitati
borderWidth Lo spessore di molti bordi in Plone
borderStyle Lo stile delle linee di demarcazione (di default solid)
borderStyleAnnotations Lo stile delle linee dei bordi attorno ai commenti, e così via
globalBorderColor Il colore dei bordi usati nelle schede principali, nelle portlet e così via
globalBackgroundColor Il colore di sfondo delle schede selezionate, intestazioni delle portlet, e così via
globalfontColor Il colore dei caratteri nelle schede e nelle intestazioni delle portlet
headingFontFamily La famiglia di caratteri per i titoli h1, h2, h3, h4, h5 e h6
190 INDICE

Nome della variabile Descrizione


headingFontBaseSize La dimensione usata come base per calcolare le diverse dimensioni dei titoli
contentViewBorderColor Il colore del bordo della scheda nella scheda Contents
contentViewBackgroundColor
Il colore di sfondo della scheda view nella scheda Contents
contentViewfontColor Il colore dei caratteri delle schede nella scheda Contents
textTransform Se trasformare a testo minuscolo le portlet, schede, e così via
evenRowBackgroundColor Il colore di sfondo delle righe dispari negli elenchi
oddRowBackgroundColor Il colore di sfondo delle righe pari negli elenchi
notifyBorderColor Il colore del bordo degli elementi di notifica p. es.: messaggio di status,
calendario
notifyBackgroundColor Il colore di sfondo degli elementi di notifica
helpBackgroundColor Il colore di sfondo del calendario e pop-up widget
discreetColor Il colore di crediti, byline del documento , modulo di aiuto
portalMinWidth La larghezza minima del portale
columnOneWidth La larghezza della colonna di sinistra
columnTwoWidth La larghezza della colonna di destra

7.2.4 Personalizzare il CSS


Se si hanno poche personalizzazioni, è possibile metterle in ploneCustom.css. Questo è il secondo foglio di
stile che viene caricato dopo plone.css. Usando la funzionalità a caduta dei fogli di stile, è possibile applicare
qualsiasi modifica a ploneCustom.css per sovrascrivere il foglio di stile.
Per esempio, per cambiare la byline che appare sul fondo di ciascuna pagina, è sufficente cambiare ploneCustom.css.
Di nuovo, accediamo al file attraverso la ZMI, e quindi clicchiamo Customize. Questo crea una copia di quel
foglio di stile nella cartella custom. Per modificare il byline, muoverlo al lato sinistro ed impostarlo a grassetto,
come dimostrato in Figura 7-7.

Figura 7-7. Il nuovo byline in grassetto sulla sinistra


Per fare ciò aggiungere il seguente:

div.documentByLine {
text-align: left;
font-weight: bold;
}

Qui abbiamo impostato due attributi per l’elemento byline: text-align e font-weight. Notare che non abbiamo
cambiato nessun altro attributo dell’elemento byline; gli attributi rimasti sono ereditati dal foglio di stile origi-
nale. Con alcune semplici linee di CSS, abbiamo cambiato il sito e assicurato che altre modifiche a Plone non
influenzeranno il nostro sito. Modificare ploneCustom.css è la migliore scelta per delle piccole modifiche.
Usando fogli di stile diversi, è possibile utilizzare Plone ed offrire un’aspetto diverso a client diversi. Spesso
i siti Web hanno un pulsante che stampa una pagina più semplice, senza molta formattazione. Plone attenua
questo problema offrendo un foglio di stile separato; quando un browser stampa la pagina, quel foglio di stile
formatta la pagina. Tutti i fogli di stile alternativi sono inclusi in cima ad una pagina; si possono trovare cliccando
portal_skin, cliccando plone_template e quindi header.pt.
7.2. PERSONALIZZARE GLI SKIN 191
192 INDICE

Nota
Un foglio di stile un po’ insolito è il foglio di stile di proiezione. È supportato solamente da
Opera, e quando il browser è usato in modalità a pieno-schermo, le intestazioni girano in
pagine separate e mostrano un’interfaccia in stile

7.2.5 Personalizzare il modello di pagina principale


Come visto nel capitolo precedente, per dare un certo aspetto in una pagina a Plone , abbiamo bisogno di usare
la macro master del main_template. Ciascuna pagina Plone usa questa macro e quindi riempie gli slot adatti.
Dando un sguardo nei dettagli al modello principale, è possibile vedere come una pagina Plone venga costruita
da un modello di pagina e quindi vedere con precisione come si possano singolarmente personalizzare quegli
elementi della pagina.
Se si guarda la pagina principale di Plone, si notano numerosi elementi. La Figura 7-8 mostra una pagina Plone
con tutti gli elementi chiave dell’interfaccia utente. La Tabella 7-2 descrive ognuno degli elementi ed il loro
scopo. Per ogni elemento della Figura 7-8 si trova un numero corrispondente nella tabella.

Figura 7-8. Tutti gli elementi principali dell’interfaccia utente di Plone


Tabella 7-2. Elementi dell’interfaccia utente

Name Description
No.
1 Site logo Mostra il logo.
2 Search form Mostra il modulo ricerca.
3 Portal tabs Mostra le schede in alto nel sito.
4 Personal bar Mostra le informazioni personali di quell’utente come il login e la cartella
personale.
5 Breadcrumbs Mostra la posizione del contenuto corrente.
7.2. PERSONALIZZARE GLI SKIN 193

Name Description
No.
6 Left slot Determina dove vengono mostrate le portlet aggiunte con proprietà left_slot.
7 Content tabs Mostra le azioni con la categoria content_tabs per quella parte di contenuto.
8 Content drop-down lists Mostra dei menu a discesa per questo contenuto, il workflow e i nuovi tipi
di contenuto.
9 Document actions Mostra le azioni per questo particolare pezzo di contenuto: stampa o e-mail.
10 Byline Mostra una descrizione del contenuto e del suo autore.
11 Right slot Determina dove vengono mostrate le portlet aggiunte con proprietà
right_slot.
12 Footer Mostra le informazioni in fondo alla pagina.
13 Colophon Mostra ulteriori informazioni sotto il piè di pagina.

Non abbiamo ancora trattato una sezione di questo modello di pagina: il contenuto. Tutto il testo da Welcome to
Plone giù fino a The Plone Team è il contenuto aggiunto e modificato dagli utenti. Questo è lo slot principale
del modello di pagina che viene riempito con un particolare tipo di contenuto o modello di pagina, come abbiamo
visto. Nel Capitolo 6 abbiamo trattato l’uso degli slot; in quel capitolo abbiamo mostrato come, usando lo slot
principale, possiamo essere sicuri che il contenuto appaia in una pagina Plone.
Quindi, determinati i componenti della nostra pagina Plone, com’è possibile personalizzarne una singola par-
te? La risposta è: trovare la sezione corrispondente nel main_template, vedere quale parte chiama, e poi
personalizzarla. Per questa ragione, tratteremo in dettaglio il modello principale.
A prima vista, il modello principale appare molto lungo e complicato, ma è costituito essenzialmente tutto da
macro, ed il suo scopo principale è di prelevare contenuto da altre aree. È possibile trovare il modello principale
cliccando portal_skin, cliccando plone_templates, e cliccando quindi main_template.
La filosofia retrostante al modello principale è che un utente non dovrebbe aver bisogno di modificare la confi-
gurazione del modello corrente, a meno che si siano pianificate grandi modifiche. Siccome il modello principale
preleva tutto il contento da altri posti all’interno di Plone, è possibile modificare la pagina così assemblata per-
sonalizzando quei singoli elementi. Questo significa che è possibile modificare solo le sezioni che interessano
piuttosto che modificare l’intero modello.
Il modello principale usa pesantemente lo spazio dei nomi dell’XML (Extensible Markup Language) per presen-
tare il più semplicemente possibile il codice METAL. Per esempio:

<metal:headslot define-slot="head_slot" />


<!--Uno slot dove è possibile inserire gli elementi dell’header da
un modello-->

Qui, il nome del marcatore non è un elemento standard dell’XHTML (Extensible HTML ); invece, usa il prefisso
metal: per definire uno spazio dei nomi come metal:headslot. Questo da i seguenti vantaggi:

• L’elemento headslot è semantico, cioé descrive l’elemento. È facile evidenziare che questo è
lo slot per aggiungere qualsiasi cosa che si voglia aggiungere in cima alla propria pagina.
• Gli attributi in quell’elemento usano lo spazio dei nomi dell’elemento se non altrimenti dichia-
rato; quindi, invece di metal:fill-slot, si può usare solo fill-slot.
• Il marcatore corrente non è un marcatore XHTML valido, così non verrà visualizzato. Co-
munque, se la traduzione del marcatore genera qualcosa di XHTML‘ valido, allora
l’‘‘XHTML viene visualizzato.

Quando viene usata una macro, il contenuto nel modello chiamante viene rimosso, così è possibile mettere nel
modello chiamante dei commenti inseriti nella macro come testo. Per esempio:
194 INDICE
7.2. PERSONALIZZARE GLI SKIN 195

<div metal:use-macro="here/global_searchbox/macros/quick_search">
Il box di ricerca veloce, normalmente posizionato in alto a destra
</div>

In base al commento, è facile capire che questa macro si riferisce al box di ricerca nell’angolo in alto a destra
di un sito (elemento 2 in Figura 7-8). Per vedere la macro, si trovi lo script denominato global_searchbox
e la macro quick_search contenute al suo interno. Il modello principale continua con macro principali,
recuperando informazioni da diversi modelli e script, e costruisce la pagina nel modo giusto.
Dopo questa sezione, il modello principale giunge al contenuto principale della pagina che è l’oggetto che dev’es-
sere reso. Nel Capitolo 6 abbiamo spiegato la differenza tra uno slot ed una macro; ricordiamo che un modello
definisce gli slot che poi vengono riempiti dal contenuto. In realtà c’è un solo slot di qualche importanza per il
contenuto, ed l’abbiamo detto molte volte: lo slot principale (main slot).
Una argomento comune in Plone che può generare confusione è come definire uno slot all’interno di un’altro slot
(a riempimento). Per esempio, il seguente è la definizione per il css_slot:

<metal:cssslot fill-slot="css_slot">
<!-- Uno slot dove si può inserire il CSS da un modello -->
<metal:cssslot define-slot="css_slot" />
</metal:cssslot>

Questo tipo di schema sembra un pò strano, ma definisce lo slot e quindi ricrea lo slot a riempimento. Se
guardiamo attentamente il modello principale, questi slot sono proprio nell’header use-macro, così la macro
degli header può riempire questo slot. Ma vogliamo anche il modello finale per riempire lo slot, per questa
ragione lo slot viene ridefinito. Questo vuol dire che uno slot può essere ora riempito in due posti che è una utile
tecnica per modificare i modelli.
Continuando l’esame per il resto del modello principale, giungiamo alle colonne di sinistra e di destra, al piè di
pagina ed al Colophon. Si noti che la colonna sinistra può apparire prima del contenuto principale di una pagina
(peraltro, solo se la nostra lingua si legge da sinistra a destra), ma il foglio di stile la mette là. Questo assicura
che se si visita il sito con un browser testuale, il contenuto principale appaia prima e non dopo tutte le opzioni di
navigazione.
Tabella 7-3 Descrive le macro e gli slot del modello principale

Nome Descrizione Slot o Macro


Cache headers Imposta la cache degli header HTTP per il Macro: cacheheaders in
contento. global_cache_settings
Head slot Permette al contenuto di aggiungere l’ele- Slot: head_slot
mento head di una pagina.
CSS slot Permette al contenuto di aggiungere del Slot: css_slot
CSS personalizzato per la pagina.
JavaScript head slot Permette al contenuto di aggiungere Java- Slot: javascript_head_slot
Script personalizzato alla pagina.
Site actions Permette di avere una serie di azioni sopra Macro: site_actions in global_siteactions
la ricerca. Di default questo permette di
cambiare la dimensione dei caratteri.
Quick search Il box cerca è mostrato nell’angolo in alto a Macro: quick_search in
destra. global_searchbox
Portal tabs Le schede del portale (normalmente blu) Macro: portal_tabs in global_sections
che normalmente sono in alto a sinistra. Le
schede realmente mostrate sono determina-
te dalle azioni. Questo valore determina
come le schede sono rese in HTML.
196 INDICE

Personal bar La barra parsonale in alto a destra: login, Macro: personal_bar in


logout, e cosi via. global_personalbar
Path bar Il path briciole che inizia con “Tu sei qui” Macro: path_bar in global_pathbar
Content views Le schede in cima al contenuto (normal- Macro: content_views in
mente verdi). Queste sono mostrate sola- global_contentviews
mente se modificabili dall’utente corrente.
Le schede realmente mostrate sono determi-
nate dalle azioni. Questo valore determina
come le schede sono rese in HTML.
Content actions Il piccolo elenco drop-down di azio- Macro: content_actions in
ni nell’angolo a destra della barra dei global_contentviews
contenuti.
Portal status messa- Un messaggio mostrato ogni qual volta Macro: portal_message in
ge qualcosa viene cambiata. global_statusmessage
Header L’intestazione di un pezzo di contenuto. Slot: header
main La parte principale di un pezzo di contenuto. Slot: main
Sub La parte inferiore di un pezzo di contenuto Slot: sub
dove compaiono i commenti su un oggetto.
Left portlets Gli slot o le portlet mostrati a sinistra del- Macro: left_column in portlets_fetcher
la pagina. Ci sono alcune definizioni qui;
column-one-slot è l’intera colonna sinistra,
e portlets-one-slot è l’analogo slot. Se non
è definito alcuno slot, chiama la macro.
Right portlets Gli slot o le portlet mostrati a destra della Macro: right_column in portlets_fetcher
pagina. Vedere Left portlets.
Footer Copyright e altri messaggi. Macro: portal_footer in footer
Colophon Messaggi vari nella parte inferiore. Macro: Colophon in Colophon

Dotati di queste informazioni, ora cambiare l’aspetto della pagina è solo una questione di personalizzare le macro
o gli slot. Si raccomanda nuovamente di non personalizzare realmente il modello principale di pagina stesso, ma
di personalizzare invece le parti che vengono chiamate dal modello principale. La sezione successiva mostra
alcuni esempi di personalizzazioni che è possibile fare a Plone.

7.2.6 Frammenti di personalizzazione


Le seguenti sezioni mostrano alcuni esempi che dimostrano delle semplici personalizzazioni che si possono fare
al proprio sito Plone. Alcune soluzioni offrono uno o due modi diversi di effettuare lo stesso compito.

7.2.7 Rimuovere un Block


Un trucco abbastanza pulito è la possibilità di rimuovere facilmente un blocco dall’interfaccia utente come
la barra degli indirizzi o il box di ricerca. Abbiamo due modi di farlo; il più ovvio è personalizzare la ma-
cro che visualizza l’elemento. Per esempio, per rimuovere le briciole, possiamo cliccare portal_skin, cliccare
plone_template, cliccare global_pathbar e poi spegnere l’elemento (breadcrumbs) al livello del modello di
pagina; per esempio, possiamo cambiare il codice che segue:

<div metal:define-macro="path_bar"
id="pathBar"
7.2. PERSONALIZZARE GLI SKIN 197

tal:define="breadcrumbs python:here.breadcrumbs(here);
portal_url portal_url|here/portal_url">

quindi aggiungiamo le seguenti linee:

<div metal:define-macro="path_bar"
id="portal-breadcrumbs"
tal:condition="nothing"
tal:define="breadcrumbs python:here.breadcrumbs(here);
portal_url portal_url|here/portal_url">

Questo significa che personalizzare un modello di pagina non è proprio un problema e che da ora è un qualche
cosa con la quale dobbiamo avere famigliarità. L’approccio lievemente diverso è la possibilità di nascondere
elementi a livello CSS. Questo vuol dire che l’oggetto viene ancora reso e che l’HTML viene generato, ma che
non viene dato ai client di chi non può vederlo. Siccome l’HTML viene ancora generato, questa non è la soluzione
ottimale, ma è un bel trucco.
La maggior parte degli elementi Plone possiede un identificatore unico Document Object Model (DOM); che, per
esempio, nel caso delle briciole è portal-breadcrumbs, come si può vedere nel codice precedente. Per
bloccare la visualizzazione di portal-breadcrumbs, semplicemente aggiungiamo a ploneCustom.css
le seguenti righe di codice:

#portal-breadcrumbs {
display: none;
}

7.2.8 Cambiare le schede del portale


Abbiamo già mostrato come sia possibile cambiare il testo delle schede del portale cambiando le azioni. Sono
visualizzate usando il foglio di stile, e non usando delle tabelle (anche se gli utenti possono pensare inizialmente
così). Guardando alla Tabella 7-3, possiamo vedere che il codice per le schede del portale è in portalTabs.
Per rendere punteggiato il bordo delle schede non selezionate, si può semplicemente cambiare il foglio di stile
ploneCustom come segue:

#portal-globalnav li a {
border: 1px dotted;
}

Le schede sono una serie elementi composti di elenchi puntati (li) e di ancore (an) HTML, così cambiando il
CSS per questi elementi, possiamo cambiare l’aspetto delle schede. In un secondo tempo nella sezione Caso
reale: Esame dello Skin Nasa mostreremo come cambiare queste schede in immagini.
Mediante l’uso del CSS si può muovere l’ubicazione di qualsiasi elemento tramite l’attributo position. Succes-
sivamente, trasportiamo le nostre schede in cima allo schermo, sopra il logo ed il box di ricerca. Per fare questo,
usiamo il valore assoluto della posizione che permette di definire la posizione usando gli attributi left, right, top
e bottom. Aggiungiamo il seguente codice al nostro foglio di stile ploneCustom per posizionare le schede del
portale in cima al nostro sito Plone:

#portal-globalnav {
position: absolute;
top: 0em;
}

Questa è una tecnica potente per muovere degli elementi. Ci sono più opzioni per posizionare gli elementi,
incluso il posizionamento relativo ma quello richiede un po’ di lavoro con il CSS per trovare il posizionamento
corretto.
198 INDICE

7.2.9 Muovere gli slot di sinistra e di destra


Abbiamo discusso degli slot di sinistra e di destra nel Capitolo 4, ed abbiamo mostrato come aggiungere un
nuovo slot all’elenco degli slot. Abbiamo potuto anche notare che i termini left slot e right slot possono essere
un po’ fuorvianti. L’opzione predefinita è mostrare gli slot in quelle posizioni, ma è facile spostarli.

Nota
Questo funziona solamente quando si sta usando lo skin Plone Tableless. Questa non è
l’impostazione predefinita, quindi si dovrà modificare lo skin con lo strumento portal_skin,
come discusso precedentemente in Gestire gli Skin con lo strumento portal_skins.

Per esempio, se volessimo trasportare la portlet sinistra sul lato destro della pagina, allora potremmo fare questo
cambiando ploneCustom.css come segue:

#portal-column-one {
float: right;
}
#portal-column-content {
float: left;
}

Questo trasporta la colonna più a sinistra sul lato destro e spinge la sezione principale alla sinistra.

7.2.10 Nascondere l’aiuto dei moduli


Se volessimo nascondere l’aiuto in tutti i moduli,sicuramente non vorremmo cambiare tutti i modelli. Ma po-
tremmo assumere una tattica simile al nascondere la barra degli indirizzi ed impostare solo display:none negli
elementi del modulo. Il codice seguente ha l’effetto desiderato di non mettere l’elemento in ingresso su una
nuova riga:

div.formHelp {
display: none;
}

La Figura 7-9 mostra la pagina di feedback senza le briciole, con l’aiuto nascosto, con le schede punteggiate e
con lo slot di sinistra messo sulla destra della pagina, il tutto modificato con solo poche linee di CSS.

Figura 7-9. L’effetto combinato di alcuni degli esempi

7.2.11 Come cercare l’elemento X?


Come abbiamo mostrato, i modelli, gli script, e le immagini contenute nelle cartelle skin di una installazione
Plone creano uno skin Plone. In questa cartella ci sono molti file, cosicché navigare attraverso ogni file sarebbe
lungo e controproducente quando questi file vengono modificati. Risulta invece utile per capire le tecniche di
base per trovare gli elementi che si vogliono modificare.
Si tenga presente a quale livello si vuole personalizzare l’elemento. Come precedentemente notato, abbiamo tre
livelli per visualizzare un oggetto. Se vogliamo cambiare la rappresentazione visiva o la sua posizione, allora si
può cambiare il CSS e non occorre fare ulteriore lavoro.
7.2. PERSONALIZZARE GLI SKIN 199
200 INDICE

Se il CSS non è sufficiente, allora la successiva migliore mossa sarà fare una ricerca nei modelli. Per esempio,
supponiamo di voler cambiare il testo che viene mostrato sulla pagina quando un utente si registra, o di voler
cambiare l’intera pagina. In questo esempio, modifichiamo la pagina mostrata nella Figura 7-10 e lo fa uno script
che fa qualche cosa di insolito.

Figura 7-10. La pagina “ Benvenuto! Ora sei connesso.”


Ci sono alcuni indizi per trovare questo modello per poi poterlo modificare; li proveremo subito, uno ad uno.

7.2.12 Cercare usando l’URL


L’URL di una pagina (Uniform Resource Locator) si traduce in una serie di oggetti di Plone che vengono attra-
versati. Nella Figura 7-10, abbiamo attraversato fino alla pagina login_success. In questo caso, la parte
finale dell’URL è login_success, come si può vedere nella barra degli indirizzi in figura 7-10. Quando un
oggetto è caricato in un FSDV, l’estensione viene eliminata, così da cercare un modello o uno script che inizi con
login_success.

Figura 7-11. Cercare un ID


In Zope è possibile effettuare questa ricerca con lo strumento portal_skin e cliccando la scheda Find. Una volta
là, digitare login_success nel campo with ids. Lasciare inalterate tutte le altre impostazioni, e cliccare il pulsante
Find. Sicuramente troveremo il modello login_success.
Si può fare questa ricerca anche nel File System, in funzione del proprio sistema operativo e degli strumenti
disponibili. Il modo più rapido di trovare questo file in Linux è posizionarsi nella nostra cartella CMFPlone e
fare come segue:

$ cd skins
$ find -name ’login_success*’ -print
./plone_forms/login_success.pt

In Windows, si apra la cartella CMFPlone con Windows Explorer e poi si clicchi sulla scheda Search. Poi
inserire il nome del file login_success e cliccare Search. Questo dovrebbe fornire un elenco di file simili.
Questa ricerca dovrebbe dare come risultato CMFPlone/plone_forms/login_success.pt. Se si fa la
stessa ricerca nella ZMI, cliccare portal_skin, cliccare plone_forms e quindi cliccare login_success.

7.2.13 Cercare un pezzo di testo


Un approccio piuttosto grezzo che qualche volta ha successo è fare una ricerca a pieno testo nel codice per
localizzare l’elemento che visualizza la pagina. Per esempio, osservando la pagina in figura 7-12, si può vedere
che contiene il testo Notice that the top. Il modo più semplice di trovare i bit che visualizzano quel testo è
cercarlo.

Figura 7-12. Cercare testo


In Zope è possibile anche effettuare questa ricerca con lo strumento portal_skin cliccando sulla scheda Find.
Una volta là, inserire Notice that the top (il testo che vogliamo cercare - n.d.t.) nel campo containing. Lasciare
invariate tutte la altre impostazioni, e cliccare il pulsante Find. Sicuramente troveremo il modello login_success.
Possiamo operare la stessa ricerca anche nel File System, in funzione del nostro sistema operativo e degli
strumenti disponibili. Il modo più rapido di trovare questo file in Linux è posizionarsi nella nostra directory
CMFPlone e fare come segue:
7.2. PERSONALIZZARE GLI SKIN 201
202 INDICE
7.2. PERSONALIZZARE GLI SKIN 203
204 INDICE

$ grep -ri "Notice that the top" *


plone_forms/login_success.pt: Notice that the top

In Windows, aprire la cartella CMFPlone con Windows Explorer e cliccare la scheda Search. Poi digitare i
contenuti del file come Notice that the top (il testo che vogliamo cercare - n.d.t.), e cliccare Search. Questo
dovrebbe dare un elenco di file simili. Usando questa tecnica piuttosto grezza, abbiamo trovato un modello,
login_success, che visualizza il messaggio di ritorno all’utente.
Questa tecnica ha i seguenti problemi:

• Cura del contenuto in caratteri minuscoli nel CSS; fare sempre le ricerche in modalità case
insensitive (predefinito in Windows). E’ irritatamente cercare home quando nel modello c’è
Home e nel CSS è in caratteri minuscoli.
• Se si sta cercando di farlo in un linguaggio diverso dall’inglese, il contenuto potrebbe essere
localizzato e causare così il fallimento della ricerca.
• Occasionalmente potrebbe non esserci testo ricercabile che corrisponda; in questo caso, l’ap-
proccio raccomandato è di ricercare tramite l’URL.

7.3 Creare nuovi Skin e Livelli


Finora abbiamo parlato di personalizzare lo skin esistente. Il processo per creare un nuovo skin completo o un
nuovo livello non è davvero molto diverso. Trattiamo ora un punto chiave, mettere i nostri modelli e script nel
File System.
Creare modelli e script nel File System e, in generale, la creazione di nuovi skin e livelli è il miglior modo di
garantire a lungo termine la possibilità di manutenzione e la flessibilità. Non solo è più facile creare elementi
dello skin con strumenti famigliari nel File System, ma ciò permette anche di ridistribuire più facilmente il nostro
codice. Scrivere nel File System è lo stile scelto da quasi tutti gli sviluppatori Plone, con delle modifiche minori,
se necessarie, nella cartella custom.

7.3.1 Realizzare un nuovo skin


Come abbiamo visto, uno skin in realtà non è nulla di più di una raccolta di livelli. Per un nuovo skin, vo-
gliamo mettere tutto il nostro codice personalizzato in un solo luogo, così andiamo nello strumento portal_skin,
aggiungiamo una nuovo contenitore, e gli diamo l’ID custom_chrome.
Quindi, per aggiungere un nuovo skin, dobbiamo cliccare su portal_skin, selezionare la scheda Properties, ed
aggiungere un nuovo skin sotto il testo Add a new skin. Abbiamo bisogno di inserire una serie di livelli che
vogliamo preparare per questo skin. In questo esempio, abbiamo aggiunto un nuovo skin chiamato Custom
Chrome ed una serie di livelli, come mostrato in Figura 7-13.

Figura 7-13. Aggiungere lo skin Custom Chrome


Quindi abbiamo aggiunto i livelli per lo skin. In questo caso, lo skin non ha in sé un livello denominato custom;
invece ha una cartella chiamata custom_chrome. Abbiamo quindi due diversi skin che usano due livelli e due
cartelle. Qualsiasi oggetto aggiunto alla cartella custom_chrome riguarda quello skin, non lo skin predefinito
Plone Default.
7.3. CREARE NUOVI SKIN E LIVELLI 205
206 INDICE

7.3.2 Usare Skin multipli


Come abbiamo già menzionato, un sito Plone standard possiede due skin, Plone Default e Plone Tableless. Nella
sezione precedente, abbiamo aggiunto un nuovo skin, Custom Chrome. Come abbiamo discusso nel Capitolo
4, è possibile impostare lo skin predefinito usando l’interfaccia Plone. Cliccare configurazione di plone, e poi
cliccare il pulsante Skin. Questo rispecchia le opzioni disponibili nella ZMI dopo avere cliccato portal_skin,
selezionato la scheda Properties, ed essere andati in fondo alla pagina.
Inoltre abbiamo un’ulteriore scelta: REQUEST *nome variabile*. Questa è la variabile richiesta che conterrà le
informazioni dello skin dell’utente. Il valore predefinito è plone_skin che è il nome del cookie. Ma potrebbe
essere passato anche tramite altre variabili di richiesta come una (stringa) query. È disponibile solo dalla ZMI.
È inoltre possibile impostare skin programmaticamente. Questo consente agli sviluppatori di mostrare skin
diversi ad utenti differenti in base a logiche di affari o del sito. Per esempio, se un utente sta scrivendo contenuto
per un sito, potrebbe vedere lo skin standard di Plone. Se invece è un utente anonimo, allora potrebbe vedere
uno skin totalmente diverso. Piuttosto che lasciare scegliere all’utente, che sia il sito a prendere questa decisione.
Se proprio si vuole, si può basare la scelta dello skin sulla cartella a cui si sta accedendo; comunque questo
approccio potrebbe portare in confusione, così non lo raccomandiamo.
Per cambiare lo skin, aggiungiamo un oggetto Script (Python) chiamato setSkin alla radice del nostro sito Plone.
Poi aggiungiamo il codice seguente:

##title=Skin changing script


##parameters=
req = context.REQUEST
if req[’SERVER_URL’].find(’internal.somesite.org’) > -1:
context.changeSkin("Plone Default")
context.changeSkin("Custom Chrome")

La vera logica per determinare lo skin dipende dalle regole di affari del sito. In questo caso chiunque acceda a
http://internal.somesite.org otterrà lo skin predefinito di Plone, e chiunque acceda a http://external.somesite.org
visualizzerà lo skin Custom Chrome. Sfortunatamente, un inconveniente è che non si può determinare lo skin in
funzione del livello di sicurezza dell’utente (per esempio, gli utenti autenticati che vedono uno skin ed i manager
un’altro). Questa funzionalità piuttosto banale non è ancora disponibile attualmente, senza un pesante hacking
del sito Plone.

Nota
Basare la scelta dello skin sulle informazioni di client non autenticati è pratica comune ma
non completamente sicura perché si sta avendo fiducia nelle informazioni del client. L’accer-
tare che questo sia sicuro dipende dalle nostre particolari impostazioni di rete. In molti casi,
si può facilmente amministrarere questo con un firewall o mediante l’uso di un server proxy
come Apache che può essere configurato per rendere impraticabili tutte le richieste esterne
a http://internal.somesite.org. Tratteremo l’integrazione con Apache nel Capitolo 10.

Per attivare questo codice, assegnamo una regola di accesso a questo oggetto. Questo vuol dire che ogni volta
che vi sarà un accesso a questo sito Plone, questo script (Python) verrà eseguito. Ogni volta che lo script viene
lanciato lo skin verrà impostato in base allo script. Per assegnare una regola a questo script, selezionare dal menu
a cascata Set Access Rule e quindi inserire il nome del nostro oggetto Script (Python). Ora proviamolo visitando
il sito, e vediamo quale skin otteniamo.
Dobbiamo stare attenti con le regole di accesso perché vengono eseguite su ogni chiamata di quella cartella (o del
sito Plone); dobbiamo assicurare che siano corrette e che non possa avvenire qualcosa di dannoso. Se abbiamo
scritto accidentalmente un oggetto Script (Python) brutto o scorretto e non riusciamo a riavere accesso neppure
tramite la ZMI per ripararlo, allora possiamo togliere le regole di accesso riavviando Plone con la seguente
variabile di ambiente:
7.3. CREARE NUOVI SKIN E LIVELLI 207

SUPPRESS_ACCESSRULE = 1

L’ ‘Appendice B‘_ spiega come utilizzare le variabili di ambiente quando non si è famigliari con questo processo.

7.3.3 Realizzare un nuovo skin nel File System


In tutti questi capitoli stiamo usando la ZMI. Ma quello che gli sviluppatori di Plone usano di più per qualsiasi
lavoro serio è il File System. Realizzare uno skin nel File System è davvero facile.
Andiamo nella cartella home dell’istanza della nostra installazione Plone. All’interno della directory Products,
creiamo una nuova cartella; il nome di questa cartella è il nome del prodotto, così per convenzione è qualche co-
sa di breve, senza spazi o sottolineature o lettere maiuscole e minuscole mescolate. PloneBookExample,
CMFPlone, e PloneSilverCity sono degli esempi. In questa cartella , creiamo un nuovo file chiamato
__init__.py ed una cartella denominata skins. Nel file __init__.py, dobbiamo aggiungere le due
linee seguenti:

from Products.CMFCore import DirectoryView


DirectoryView.registerDirectory(’skins’, globals())

Successivamente, riavviamo Plone, e poi clicchiamo su portal_skin per aggiungere un FSDV. Ciò apre un elenco
di cartelle registrate. Muoviamoci in giù finché troviamo quello che corrisponde alla cartella che abbiamo regi-
strato; questo sarà il nome della directory con /skin alla fine. Inseriamo un ID che abbia senso, e clicchiamo
Add. Ora abbiamo una cartella vuota dove poter aggiungere i livelli del nostro skin.

7.3.4 Eseguire il debug di uno Skin


Un’altra ragione per cui abbiamo usato ripetutamente la ZMI, piuttosto che il File System è che quella restituisce
gli errori e che è comoda per collocare oggetti all’interno di altri. Un’ulteriore caratteristica positiva dell’uso
della ZMI è che i cambiamenti sono immediati. Se si cambia un oggetto e poi si aggiorna, immediatamente si
vedono i cambiamenti (presumendo che non usiamo la cache).
Questo non avviene con il File System. Se si cambia qualche cosa nel File System, questo non viene aggiornato
in Plone. Questo per ragioni di prestazioni. Plone non ha alcun modo di sapere che abbiamo fatto quelche
cambiamento, e deve aggiornare la copia di quel oggetto nella cache di Zope. Senza entrare nei meccanismi del
sistema di notifica dei file, un sito Plone ha due stati: modalità di produzione e modalità debug. Quando Plone
è in modalità di debug, controlla tutte le cartelle, trova i file che sono stati cambiati, e quindi aggiorna Plone.
Questo significa che si può fare un cambiamento, ed immediatamente sarà visualizzato. Invece, quando viene
eseguito in modalità di produzione, non si vedono le modifiche fatte finché non si aggiorna lo skin (si veda il
Capitolo 11) o si riavvia Zope.
Per ragioni ovvie, se si sta sviluppando uno skin Plone, eseguire in modalità di debug è quindi il modo migliore.
Nel Capitolo 2 abbiamo mostrato come cambiare la configurazione di Plone per eseguirlo in modalità debug.
Come veloce riepilogo, apriamo il file zope.conf all’interno della cartella etc della nostra installazione ed
assicuriamoci che la direttiva debug-mode sia impostata ad on.

7.3.5 Usare oggetti nel File System


I FSDV permettono di mappare solamente quegli oggetti Zope che specificamente sono stati configurati per essere
usati in questa modo. Determinano gli oggetti Zope basandosi sull’estensione del nome del file. I contenuti di
questo file sono i contenuti di un attributo dell’oggetto, di solito il contenuto principale, come i contenuti binari
di un’immagine o il testo contenuto nel modello.
208 INDICE

Per creare un oggetto nel nostro FSDV vuoto, andiamo semplicemente nella cartella dello skin ed iniziamo
aggiungendo i file che corrispondono agli oggetti che vogliamo creare. Una volta che il file è caricato in Zope
come oggetto Zope, quell’estensione viene eliminata. Per esempio, some_template.pt diventa un modello di
pagina nel File System con l’ID some_template. La Tabella 7-4 descrive le estensioni.
Tabella 7-4. Estensioni

Estensioni Tipi di oggetto Oggetto equivalente in


Zope
.pt, .zpt, .html, .htm Filesystem Page Template Page Template
.cpt Controller Filesystem Page Controller Page Template
Template
.py Filesystem Script (Python) Script (Python)
.cpy Controller Python Script Controller Python Script
.vpy Controller Validator Controller Validator
.doc, .pdf, .swf, .jar, .cab, .ico, .js, .css Filesystem File File
.gif, .jpg, .jpeg, .png Filesystem Image Image
.props Filesystem Properties Object Folder with Properties
.zsql Filesystem Z SQL Method ZSQL Method
.dtml Filesystem DTML Method DTML Method

Quindi, per trovare un’immagine nella nostra cartella, vediamo i file .gif o .jpeg. Per cercare un oggetto Script
(Python), aggiungiamo quindi un file che termini con .py.

7.3.6 Impostare i metadati degli oggetti del File System


I contenuti extra di un oggetto come titolo, sicurezza o cache sono conservati in un file separato. Questo file ha lo
stesso nome del file originale, con aggiunto alla fine .metadata. Se il file originale è, per esempio, logo.jpg,
allora i metadati saranno contenuti nel file logo.jpg.metadata.
Il file dei metadati è nel formato .ini di Windows con coppie chiave = valore. Questo formato è stato esteso per
contenere informazioni su moduli per l’oggetto Form Controller che vedremo nella prossima sezione. Tutte le
opzioni, anche la presenza di questo file, sono opzionali. Il seguente è un esempio del file:

[default]
title = Test object
cache = RAMCache
proxy = Manager

[security]
Access contents information = 1:Manager,Anonymous

Quelli che seguono sono i valori che possono essere impostati in questo file:

title Questo è il titolo applicato all’oggetto nella ZMI di Plone; questo verrà mostrato nei modelli di Plone.
cache Questo è l’ID dell’oggetto cache nel quale si vuole che l’oggetto sia tenuto (in cache). Per default Plone
viene fornito con due oggetti per la cache: una gestione della cache RAM (RAM Cache Manager) ed una
gestione della cache HTTP (HTTP Cache Manager). Il Capitolo 14 tratta la funzione di questi due oggetti.
proxy Questo è il ruolo proxy che si vuole applicare a questo oggetto. Si veda il ‘Capitolo 9‘_ per ulteriori
informazioni.
7.3. CREARE NUOVI SKIN E LIVELLI 209

security Questa è l’area della sicurezza che permette l’impostazione di più linee. La chiave contiene il nome del
permesso. Il lato destro contiene le impostazioni dell’acquisizione, seguito dai ruoli separati da virgole.
Per esempio, View = 0:Manager significa che solamente gli utenti con i ruoli di member e di manager
possono vedere un oggetto, e che le impostazioni di sicurezza non sono acquisite per quel permesso.

7.3.7 Usare validatori nel File System


Per specificare validatori nel File System, si aggiunga il volore validator al file .metadata. La sezione
validator del file .metadata dovrebbe essere come questa:

[validators]
validators = validate_script1, validate_script2

Questo eseguirà i due script di validazione: validate_script1 e validate_script2, in questo ordine. Uno script di
validazione esaminerà i dati e, se c’è un problema, aggiungerà errori al modulo controller state.
I contextType e le opzioni button hanno bisogno di una sintassi lievemente diversa. Validazioni sono eseguite
sul contesto che viene eseguito, per esempio un documento o una immagine. Potremmo avere due differenti
validazioni da eseguire una per il documento ed una per l’immagine. Per esempio, per avere un diverso script di
validazione da eseguire quando questo è invocato come un documento, si aggiunga la linea seguente:

validators.Document = validate_script2

Possiamo variare la validazione in base al pulsante cliccato sul modulo aggiungendo il nome del pulsante nel
modulo al lato sinistro del validatore. Il nome del pulsante deve cominciare con form.button. Per esempio:

<input type="submit" name="form.button.button1" value="First" />

Il file metadata dovrà allora somigliare al seguente:

validators..button1 = validate_script1

I .. sono uno spazio per il tipo di contenuto, cosicché se, come in precedenza, vogliamo che questo accada per
button1 su un documento, allora il file dei metadati dovrà essere come segue:

validators.Document.button1 = validate_script5
210 INDICE

7.3.8 Usare le azioni nel File System

Trovare esempi di skin su File System ed il libro degli esempi


Tutti gli esempi di questo libro sono stati raccolti in uno skin che è possibile in-
stallare. Lo si può trovare sul sito web del Plone Book all’indirizzo http://plone-
book.agmweb.ca/Software/PloneBookExamples e sul sito web dell’editore Apress a
http://www.apress.com. È disponibile come un file .zip dello skin; dopo averlo scaricato e
decompresso, si troverà che la struttura del file è simile a quella precedentemente descritta.
Abbiamo un file __init__.py ed una cartella di skin. Nella cartella degli skin troviamo
una serie di modelli di pagina, oggetti del controllo di validazione e tutti i corrispondenti fi-
le con i metadati. Se si vuole installarlo, copiamo la cartella PloneBookExamples nella
cartella Products della nostra istanza home. Riavviamo Plone, e quindi clicchiamo con-
figurazione di plone. Selezioniamo Add/Remove Products, e vedremo una proposta per
PloneBookExamples; controlliamolo, e poi clicchiamo installa. Ora abbiamo installato i mo-
delli e possiamo andare alla feedbackForm per ritrovare il modello di pagina discusso nel
capitolo precedente.
Quello che ha fatto la procedura d’installazione è di automatizzare il processo di aggiunta
di un FSDV e successivamente aggiungere un livello per ciascun skin. Se si clicca su por-
tal_skin e poi si seleziona la scheda Properties, vedremo che è stato aggiunto il nuovo livello
plone_book_examples.

Come per i validatori, possiamo specificare anche azioni nel file .metadata. La sintassi per la sezione delle
azioni del nostro file dovrebbe somigliare a questa:

[actions] action.success = traverse_to:string:script1

Nell’esempio precedente, quando il modulo è inviato e gli script di validazione ritornano con uno stato success,
l’attraversamento dell’azione viene chiamato con l’argomento string:script1. Tale argomento è in realtà un’e-
spressione. L’azione predefinita per lo stato failure è di ricaricare il modulo corrente. Il modulo avrà accesso a
tutti i messaggi di errore tramite l’oggetto state nelle sue opzioni.
Di nuovo, possiamo specificare una particolare azione in un particolare contesto; per esempio, per specificare
un’azione di successo quando si è su un documento, possiamo fare come segue:

action.success.Documnent = traverse_to:string:document_script

Di nuovo è possibile specificare l’azione per il pulsante come segue

<input type="submit" name="form.button.button1" value="Button" />

aggiungendo il seguente codice al file .metadata:

action.success..button1 = traverse_to:string:script1

In questo esempio non abbiamo alcun contesto esplicito, quindi è valido per qualsiasi tipo di contesto.

7.4 Caso reale: Esame dello Skin Nasa


Nel gennaio 2004 due sonde della Nasa sbarcarono su Marte: Spirit ed Opportunity. Questi robot, controllati da
remoto, perlustrarono la superficie di Marte, inviarono immagini ed analisi della superficie. Le sonde furono un
grande successo, inviarono stupende immagini della superficie di Marte che entusiasmarono il mondo.
Una piccola parte di questo ingranaggio era un sito web all’indirizzo http://mars.telascience.org. Questo sito
pubblicò un programma chiamato Maestro. Per citare il sito web, il suo scopo era il seguente:
7.4. CASO REALE: ESAME DELLO SKIN NASA 211

Potete scaricare una versione ridotta del programma che gli scienziati della Nasa usano per guidare Spirit
ed Opportunity. Aggiornamenti sono inoltre disponibili per Maestro che contiene i dati reali di Marte che
potete aggiungere alla vostra copia di Maestro.

Rivolgendosi a Plone, il gruppo responsabile di questo sito sviluppò un sito che mostrava rapidità e facilità di
accesso. In quel caso, un gran numero di membri della comunità e di volontari aiutarono i membri del team
Maestro a sviluppare il sito. La Figura 7-14 mostra il sito Plone al lavoro.

Figura 7-14. Il sito Maestro


Probabilmente riconoscerete dei segni simili ad un sito Plone: le schede in cima, la barra personale nell’angolo
in alto a destra, e le usuali briciole. Per altre cose, il sito sembra piuttosto diverso da un sito Plone standard. Nelle
sezioni seguenti, mostreremo precisamente come questo fu fatto. Bene, in realtà è piuttosto semplice perché la
maggior parte dell’aspetto fu messo insieme usando il CSS. Ci furono pochi o nessuno cambiamento oltre che
cambiare il foglio di stile custom ed alcune nuove immagini.
Guardate prima di tutto le modifiche non-CSS al sito che sono state ottenute cambiando alcuni modelli ed alcune
proprietà.

7.4.1 Rimuovere le portlet ed alcuni degli elementi principali


Il sito non ha portlet. Sono stati rimossi perché in questo sito nessuno di loro è utile. Invece, le notizie appaiono
sulla pagina iniziale. Per rimuovere queste portlet dal nostro sito, andiamo alla radice del sito Plone e clicchiamo
Properties. Nei campi del modulo cancelliamo tutti i valori vicino a left_slots ed a right_slots.
Nel sito di Maestro, sono stati rimossi alcuni elementi. Alcune volte abbiamo trovato che questa sia la migliore
cosa da fare per le caratteristiche che non sono necessarie in un sito. Può essere un poco faticoso restringere ogni
elemento dell’interfaccia utente di un sito Plone, ma in realtà non dobbiamo farlo sempre; invece, rimuoviamo
solamente gli elementi dei quali non abbiamo bisogno. Alcuni elementi qui sono stati rimossi: le azioni del sito,
il box di ricerca, il piè pagina, ed il Colophon.
Per terminare, quei modelli che producono il codice furono personalizzati, e poi modificati così che non vi-
sualizzassero nulla. Per esempio, per rimuovere il box di ricerca, nella ZMI cliccare su portal_skin, clicca-
re plone_template, e quindi cliccare global_searchbox. Successivamente, cliccare il pulsante Customize. Poi
modificate il modello come segue:

<html
xmlns="http://www.w3.org/1999/xhtml"
xml:lang="en" lang="en"
i18n:domain="plone">
<body>

<div id="portal-searchbox"
metal:define-macro="quick_search"
tal:condition="nothing">
Nothing to see here.
</div>
</body>
</html>

Questa è la tecnica che abbiamo mostrato precedentemente per rimuovere gli elementi; impostare solamente
tal:condition sull’elemento macro per assicurare che la condizione sia a false.
212 INDICE
7.4. CASO REALE: ESAME DELLO SKIN NASA 213

7.4.2 Personalizzare i colori


Impostare i colori di base del sito nell’oggetto base_properties. Questo oggetto è stato personalizzato, ed i colori
cambiati con i seguenti colori (se non menzionati, gli altri elementi sono immutati):

linkColor: #776a44
globalBorderColor: #776a44
globalBackgroundColor: #e0d3ad
globalFontColor: #776a44

Il cambiamento di colore più evidente è il globalBackgroundColor, che interessa i colori della barra personale
e che è stato cambiato da blu a marroncino. Queste modifiche minori ai colori modificheranno il foglio di stile
cosicché corrisponderà esattamente alle immagini ed all’aspetto complessivo e sembrerà grazioso.

7.4.3 Creare il foglio di stile


La gran parte di questo sito è il foglio di stile che è riportato interamente nell’‘Appendice B‘_. Qui esaminiamo
alcune delle parti principali del foglio di stile. Questo foglio di stile è basato su ploneCustom.css che è
stato personalizzato nella cartella custom. Poi, alcuni degli elementi della pagina web, sono stati sovrascritti
nel nuovo file ploneCustom.css.
Primo, l’intero sfondo per il corpo è impostato al colore #343434.

body {
background: #343434;
}

Secondo, il reale contenuto di una pagina Plone, la parte che può essere modificata è contenuta all’interno di una
classe chiamata documentContent. Siccome il colore di sfondo dell’elemento documentContent è impostato
a bianco nel file principale plone.css, lo sfondo del testo è bianco e forma l’area bianca nel mezzo dello
schermo.
Quindi, l’immagine del satellite ed il robot in alto nel sito web è una immagine grande. Si può posizionare in
cima usando il CSS. Il codice per farlo è il seguente:

#portal-top {
background: url("http://mars.telascience.org/header.jpg") transparent no-repeat;
padding: 162px 0 0 0;
position: relative;
}

Questo codice CSS imposta i parametri per l’elemento che ha l’ID portal-top. Se si guarda il codice HTML
di un sito Plone, si vede l’elemento portal-top in cima alla pagina, giusto sotto l’elemento body. Impostando lo
sfondo per quell’immagine all’URL dell’immagine in questione, si può ottenere la visualizzazione dell’immagine.
L’immagine è alta 162 pixel, e questo è il motivo perché il padding per la cima dell’elemento #portal-top è
impostato a 162px. Se non si fa questo, allora tutti gli elementi sottostanti saranno spinti su, e si sovrapporranno
all’immagine.
L’immagine di testa è larga 677 pixel, e si noterà che il testo nella pagina va a riempire in modo pulito il sotto
dell’immagine, piuttosto che spuntar fuori a sinistra o a destra. È possibile fare ciò impostando il valore dell’e-
lemento a 680px. L’elemento HTML visual-portal-wrapper è attualmente giusto sotto il body, e pone l’ampiezza
per l’intero corpo pagina. Il codice di questo è il seguente:
214 INDICE

#visual-portal-wrapper {
width: 680px;
margin: 1em auto 0 auto;
}

Questo imposta l’ampiezza fissa per tutte le pagine, che sta bene finché ci si assicura che l’ampiezza sia più
piccola dell’ampiezza dello standard industriale di 800 punti. Nessuna problema per come l’utente renda grande
la finestra del browser, la parte principale della pagina non crescerà mai oltre quei 680 punti, assicurando che
corrisponda gradevolmente all’immagine.
Probabilmente le altre ovvie modifiche sono le schede in alto nella pagina che ora sono immagini invece dei soliti
box standard di Plone. Tre immagini formano le schede in cima alla pagina: uno spazio fra le schede, la parte
sinistra della scheda, e la parte destra della scheda. Mettendo insieme queste tre immagini, si ottiene l’effetto
della scheda. La Figura 7-15 mostra queste tre immagini.

Figura 7-15. Le tre immagini che combinandosi formano la tab


Per modificare il CSS, si ricordi che ciascuna delle schede è in realtà un elemento di elenco contenente all’interno
un elemento con l’ID portale-globalnav. Per impostare lo spazio di sfondo fra ciascuna scheda, lo skin
prima imposta lo sfondo per l’intero elemento. Di nuovo, si noti che mettendo l’altezza dell’immagine a 21 pixel,
l’identica dimensione dell’immagine, abbiamo assicurato che ci sia lo spazio adatto per l’immagine. Il codice è
il seguente:

#portal-globalnav {
background: url("http://mars.telascience.org/listspacer.gif") transparent;
padding: 0;
height: 21px;
border: 0;
margin: 0 0 1px 6px;
clear: both;
}

Per impostare l’immagine sulla sinistra in fondo della scheda, usare l’immagine iniziale. Impostare l’immagine
iniziale ponendo il valore nell’elemento li, piuttosto che nell’elemento anchor in questo modo:

#portal-globalnav li {
display: block;
float: left;
height: 21px;
background: url("/liststart.gif") transparent no-repeat;
padding: 0 0 0 33px;
margin: 0 0.5em 0 0;
}

Finalmente, impostare la parte destra della scheda aggiungendo un’immagine all’elemento anchor. Per fare que-
sto modificare l’elemento anchor all’interno della scheda. Il codice seguente mostra dove si imposta l’immagine
di background perché sia la parte destra:
7.4. CASO REALE: ESAME DELLO SKIN NASA 215

#portal-globalnav li a {
display: block;
float: left;
height: 21px;
background: url("/listitem.gif") transparent right top;
padding: 0 33px 0 0;
border: 0;
line-height: 2em;
color: black;
font-size: 90%;
margin: 0;
}

Ora, abbiamo sostituito a sufficenza l’aspetto standard delle schede Plone con pulsanti great-looking.

7.4.4 Creare la pagina Splash


Questa pagina ha un altro elemento chiave. La pagina frontale del sito è una pagina splash che mostra un bel
grafico ed invita l’utente ad entrare. Possiamo aggiungere questo andando nella ZMI e rimuovendo l’oggetto
index_html che normalmente è là. Una volta rimosso, creiamo un nuovo file chiamato index_html. In
questo file, mettiamo del codice personalizzato per realizzare la pagina iniziale, incluso un CSS personalizzato.
L’elemento principale è un’immagine, posta qui dal seguente CSS:

div {
background: url(/splash.jpg) transparent no-repeat;
width: 260px;
height: 335px;
position: absolute;
...
}

Il rimanente CSS gestisce la posizione del testo ed i collegamenti all’interno di quell’immagine. Questa pagina
non ha alcun elemento Plone; è HTML statico.

7.4.5 Conclusioni
Questo appare come un sito ragionevolmente complesso, con un CSS relativamente semplice che fa la maggior
parte del lavoro duro. Usando il CSS‘‘ abbiamo cambiato l’aspetto di Plone senza aver
una grande conoscenza di Plone oltre l’ ‘‘HTML . Inoltre, assicurando che le immagini sia-
no posizionate usando il CSS, abbiamo conservato le funzioni fondamentali di accessibilità.
Grazie alla Nasa ed a tutte le persone della comunità Plone coinvolte per l’aiuto dato a questo sito e caso di
studio. Questi ringraziamenti includono ma non sono limitati solamente a John Graham, Alma Ong, Joe Geldart,
Michael Zeltner, e Tom Croucher.
Duplicate explicit target name: “appendice b”.
216 INDICE
Capitolo 8

Capitolo 8: Gestire il controllo di flusso


(workflow)

217
218 CAPITOLO 8. CAPITOLO 8: GESTIRE IL CONTROLLO DI FLUSSO (WORKFLOW)
Indice

Note alla traduzione del capitolo


workflow: controllo di flusso
state: stato
transition: transizione
worklist: elenco lavori
owner: possessore
pending: proposto, in revisione
namespace: spazio dei nomi
issue, report bug: problema

Uno dei punti di forza di Plone è lo strumento per il controllo di flusso. Il controllo di flusso ci porta in uno
dei temi centrali della gestione di contenuti che è la separazione di logica, contenuto e presentazione. Questo
capitolo tratta nel dettaglio il controllo di flusso.
Il capitolo inizia trattando alcune definizioni chiave correlate al controllo di flusso e agli strumenti coinvolti in
modo da poter iniziare a concettualizzare il controllo di flusso. Una volta chiariti i concetti discutiamo di come
aggiungere e modificare il proprio controllo di flusso.
In questo capitolo presentiamo alcune semplici modifiche che è possibile fare al controllo di flusso predefinito di
Plone. Una serie di esempi aiuta a realizzare obiettivi come la creazione di notifiche, lo spostamento di contenuti
e così via. Infine mostriamo le più avanzate funzionalità di sviluppo del controllo di flusso e i più importanti
strumenti disponibili.

8.1 Cos’è il controllo di flusso?


Il Controllo di flusso è una catena di azioni che avvengono su qualcosa per raggiungere uno scopo. Il control-
lo di flusso esprime spesso delle regole di lavoro esistenti. Ogni attività ha sue differenti regole e sistemi di
amministrazione che devono essere svolti da un’azienda. Alcuni esempi possono essere:

• Prima che l’orario di un dipendente sia approvato deve essere visto e controllato da un supervisore.
• In una fabbrica di apparecchi per ogni oggetto costruito, agli utenti deve essere comunicata ogni variazione
dell’ordine e dell’oggetto appena ciò sia stabilito in fabbrica.

219
220 INDICE

• Prima di pubblicare una pagina di un sito web questa dev’essere approvata dal responsabile del marketing,
approvata dal responsabile del sito e tradotta da un traduttore.

Il controllo di flusso separa la logica di queste regole di affari e uniforma il modo di concepire questi cambiamenti.
Separando la logica, è poi facile per gli affaristi cambiare l’applicazione per centrare i loro obiettivi e le loro
regole di affari. Spesso le applicazioni provano a forzare un controllo di flusso su un lavoro perché tale controllo
è codificato dentro l’applicazione stessa.

8.2 Capire il controllo di flusso in Plone


Lo strumento del controllo di flusso di Plone fornisce alcune funzionalità e limitazioni che sono decisive per
capire il controllo di flusso di Plone stesso. Il prodotto per il controllo del flusso usato da Plone è il DCWork-
flow che un prodotto a sorgente aperto rilasciato dalla Zope Corporation. Sono disponibili altri strumenti per il
controllo di flusso ed alcuni stanno per essere incorporati in Plone, come OpenFlow (http://www.openflow.it -
prodotto da italiani! n.d.t.). Comunque, per il momento, DCWorkflow è sufficentemente semplice e potente e
fornisce tutte le funzionalità di cui hanno bisogno la maggior parte degli utenti.
Il DCWorkflow assume che vi sia un oggetto nel sistema che sia sottoposto al controllo di flusso - per esempio
un pezzo di contenuto o un elemento. Assume poi che oggetti dello stesso tipo siano sottoposti al medesimo
controllo di flusso. Riproponendo un tipo di contenuto (vedere il Capitolo 11 per ulteriori informazioni su questo
argomento) si possono avere contenuti simili sottoposti a controlli di flusso differenti.
Il sistema DCWorkflow è incluso in Plone e quindi non vi è nulla di extra da installare. Nella ZMI (l’Interfaccia
di Gestione Zope Management Interface) è rappresentato dall’oggetto portal_workflow.

8.2.1 Concettualizzare un Controllo di Flusso


Prima di spiegare un controllo di flusso spieghiamo alcuni semplici elementi della terminologia: stati e transizio-
ni.
Uno stato è una informazione su un elemento di contenuto in un particolare istante. Esempi di stato sono privato,
pubblicato, in revisione e bozza. Tutti i controlli di flusso hanno come minimo uno stato di partenza con cui
parte ogni contenuto. Il controllo di flusso passa poi il contenuto attraverso una serie di stati sia per l’intervento
dell’utente che per qualche processo automatico. Quando in contenuto raggiunge uno stato finale, rimane in
quello stato per un lungo periodo (normalmente per sempre). Il contenuto può arrivare ad uno o più differenti
stati finali nel processo di un controllo di flusso.
Per spostare da uno stato ad un altro un certo pezzo di contenuto è necessaria una transizione. Una transizione
congiunge uno stato iniziale con uno stato finale. Una transizione può avere molte funzionalità associate, come
vedremo più avanti, ma, per il momento, ci basta sapere che una transizione sposta un contenuto da due stati.
Una transizione viene normalmente impostata da qualche forza esterna come il click di un utente su un pulsante
di una pagina web o uno script che interagisce con una pagina.
Visualizzare un controllo di flusso, specie quando si parla di qualcosa di nebuloso come contenuto, può con-
fondere un po’. Può aiutare il pensare ad una scadenza giornaliera. Un caso così, l’esempio seguente mostra il
controllo di flusso di un conto di una carta di credito, si è fortunati se lo si riceve ogni mese:

1. La compagnia emittente prepara un conto e ce lo invia tramite e-mail.


2. Riceviamo il conto e lo mettiamo sulla scrivania. Talvolta il conto sta li sulla scrivania per qualche
tempo in attesa della fine del mese. Occasionalmente è necessario chiedere spiegazioni a qualcuno
a proposito di certe spese del tipo “Cos’erano quei vestiti che hai comperato?”.
3. Per qualsiasi domanda o problema importante si torna alla compagnia emittente causando talvolta
l’emissione di un nuovo conto (sebbene questo avvenga molto raramente).
8.2. CAPIRE IL CONTROLLO DI FLUSSO IN PLONE 221

4. Normalmente, alla fine del mese, quando si fanno tutti gli addebiti, poi si paga il conto.

Da questo quindi si possono ricavare alcuni stati. Guardando i passi precedenti vediamo che non è proprio
necessario creare altri stati per ricevere il conto, inclusi l’aprirlo e metterlo sulla scrivania. Ugualmente non
dobbiamo preoccuparci per ogni movimento che arriva. Anche se questi sono tutti passi validi che realmente
avvengono, provare a fare un controllo di flusso per tutti gli stati può essere macchinoso. É possibile, piuttosto,
riassumere il controllo di flusso nei seguenti stati:

Emissione Il conto della carta di credito viene preparato per esserci spadito.
Revisione Riceviamo il conto della carta di credito e lo mettiamo sulla nostra scrivania per controllarlo
Pagamento Il conto della carta di credito viene pagato, messo in archivio e dimenticato per sempre.

Ora che abbiamo estratto gli stati possiamo pensare ai cambiamenti che avvengono. Per ugnuno di questi stati
dev’esserci almeno una transizione che possa cambiare da uno stato ad un altro il conto:

Invio La banca spedisce il conto della carta di credito


Pagamento Paghiamo il conto della carta di credito.

Rigetto C’è qualcosa di sbagliato nel conto e non viene approvato.

La Figura 8-1 mostra questo insieme di transizioni e di stati. Nella figura i riquadri rappresentano gli stati con
il loro nome scritto dentro. Le frecce rappresentano le transizioni da uno stato al prossimo con il nome della
transizione in corsivo.

Figura 8-1. Una semplice macchina degli stati per il pagamento dei conti delle carte di credito.
Abbiamo quindi estratto questi processi di lavoro per pagare il conto di una carta di credito con un controllo di
flusso. Il prossimo passo è pensare ai ruoli ed alla sicurezza relative al conto della nostra carta di credito. Questo
controllo di flusso ora contiene la logica del lavoro per una applicazione che debba processare le carte di credito.

8.2.2 Capire Ruoli e Sicurezza nel Controllo di Flusso


In qualsiasi sistema complesso si hanno utenti di tutti i ruoli e gruppi. I ruoli in Plone danno una grande flessibilità
sulla sicurezza ma possono anche renderla più complicata. Il ‘Capitolo 9‘_ tratta della sicurezza, dei ruoli locali,
dei gruppi ma in questa sezione trattiamo alcuni punti chiave sul come questi argomenti sono correlati al controllo
di flusso.
Quando un pezzo di contenuto passa da uno stato ad un altro del controllo di flusso, il processo di controllo può
cambiare le impostazioni di sicurezza di quel contenuto. Le impostazioni di sicurezza determinano quale utente
può effettuare quella azione su quel pezzo di contenuto. Manipolando le impostazioni di sicurezza del controllo
di flusso, è possibile causare la modifica della sicurezza di un pezzo di contenuto durante il suo ciclo vitale. Gli
utenti provenienti da sistemi statici o da Zope spesso sono confisi in quanto, in Zope, tutti i pezzi di contenuto
hanno le medesime impostazioni di sicurezza durante l’intera loro vita.
222 INDICE

Ritornando all’esempio, noi possiamo interferire con le impostazioni di sicurezza del conto della carta di credito.
Un modo per rappresentarlo è quello di produrre una tabella che espanda in termini generici la sicurezza delle
transizioni che possono avvenire in ciascuno dei vari stati, come mostrato in Tabella 8-1.
Tabella 8-1. Le Transizioni e le Entità che possono farle

Stato Noi Banca


Emissione Invia
Revisione Paghiamo Rigetta
Pagamento

A questo punto nella Tabella 8-1 vediamo le transizioni e chi può farle. Non abbiamo ancora pensato all’accesso
che deve effettuare ciascun utente per realizzare una azione su un oggetto in ogni punto. Per esempio in quale
punto è possibile che qualcuno modifichi il conto, e quando può essere visto questo? Queste sono dette azioni
nella terminologia Plone, come viene mostrato nella Figura 8-2. Speriamo di avere solo noi l’accesso agli or-
dinativi della nostra carta di credito! Ugualmente in ogni passaggio la banca è in grado di vedere il conto della
carta di credito e di rispondere a domande su di essp.
Tabella 8-2. Le Azioni e le Entità che possono farle

Stato Noi Banca


Emissione Vede, Modifica
Revisione Vediamo Vede
Pagamento Vediamo Vede

In realtà, quando viene emesso, non ci è possibile modificare il conto della nostra carta di credito, solo la banca
lo può fare. Possiamo mandare di ritorno il nostro conto respingendolo ma la banca non è detto che voglia le
nostre modifiche. In una situazione come questa assumiamo che la banca sia proprietaria del conto della carta
di credito. Ciò dimostra il concetto detto possesso. Possiamo ricevere conti di carte di credito diverse da banche
diverse ed in ciascun caso possiamo pensare alla banca come alla proprietaria del conto. Ciascuna banca possiede
il proprio conto di carta di credito ma la banca A non possiede il conto della banca B. La Tabella 8-3 combina le
transizioni con le azioni cambiando rispettivamente i termini Noi e Banca con Pagante e Possessore
Tabella 8-3. Le Transizioni e le Azioni Combinate, più i Ruoli della gente

Stato Pagante Possessore


Emissione Invia, Vede, Modifica
Revisione Paga, Rigetta, Vede Vede
Pagamento Vede Vede

Ovviamente questo è un esempio alquanto limitato, ma illustra com’è possibile applicare un controllo di flusso a
degli stati base. Qui potrebbero avvenire altri tipi di transizione, per esempio, saremmo più che felici se qualcun
altro pagasse il conto della carta di credito per noi, ma ciò è talmente improbabile che non lo aggiungeremo al
controllo di flusso o alla sicurezza.
Prima di mostrare come creare e modificare il controllo di flusso vediamo il controllo di flusso predefinito di
Plone.
8.2. CAPIRE IL CONTROLLO DI FLUSSO IN PLONE 223

8.2.3 Introduzione al controllo di flusso di Plone


Plone è fornito di un insieme di controlli di flusso predefiniti per il nostro sito. Questi controlli di flusso prevedono
una percorso logico nello spostamento dei contenuti dentro un sito Plone. Un sito Plone standard ha due controlli
di flusso: il controllo di flusso normale e il controllo di flusso delle cartelle. Le seguenti sezioni trattano a turno
ciascuno di questi.

Controllo di flusso predefinito (Default Workflow)

Nel ‘Capitolo 3‘_ abbiamo trattato il controllo di flusso e le impostazioni della pubblicazione dei contenuti
predefiniti. Abbiamo discusso di ciascuno stato del controllo di flusso. Comunque una immagine è meglio di
migliaia di parole così la Figura 8-2 mostra gli stati del controllo di flusso predefinito fornito con Plone.

Figura 8-2. Il Controllo di Flusso predefinito fornito con Plone


La Figura 8-2 mostra i principali stati e transizioni. Questa immagine ha una linea grigia punteggiata che rap-
presenta una sorta di divisione della sicurezza. A sinistra della linea è la parte dove normalmente i possessori
del contenuto interagiscono con il contenuto stesso. A destra di quella linea c’è la parte dove sono i revisori che
interagiscono con i contenuti.
224 INDICE

Nota
Il possessore di un contenuto è la persona che ha creato in origine il contenuto. Un posses-
sore è un particolare collaboratore di un siti Plone. Sebbene esisteno molti membri in un
sito solo una persona può essere il possessore di un pezzo di contenuto di un sito Plone.
Siccome il ruolo di possessore viene determinato quando un oggetto viene creato, il ruolo di
possessore è un ruolo speciale.

Come nell’esempio della carta di credito, esiste un insieme di impostazioni di permessi per il controllo di flusso
predefinito. La Tabella 8-4 mostra tutti i permessi e gli stati.
Tabella 8-4. I Permessi predefiniti del Controllo di Flusso

Stato Anonimo Autenticato Possessore Manager Revisore


Proposto View View View Edit Edit
Privato Edit Edit View
Pubblicato View View View Edit View
Visibile View View Edit Edit View

View fa riferimento ai seguenti permessi: Access Contents Information e View


Edit fa riferimento al seguente permesso: Modify Portal Content
Come si può vedere nella Tabella 8-4, l’impostazione predefinita è che solo quando un contenuto è nello stato
privato è certamente nascosto a qualsiasi altra persona. Quando un contenuto è nello stato Pubblicato solo un
manager può modificarlo. In una prossima sezione, Modificare i permessi, vedremo come cambiare facilmente
questi permessi via web.

Controllo di Flusso delle Cartelle

Abbiamo trattato anche il controllo di flusso delle cartelle nel ‘Capitolo 3‘_ quando abbiamo parlato la pubbli-
cazione dei contenuti. Comunque, come abbiamo notato in quel capitolo, non esiste lo stato Proposto (Pending)
per le cartelle. Abbiamo invece un controllo di flusso più semplice, come mostra la Figura 8-3.
8.3. AGGIUNGERE E MODIFICARE IL CONTROLLO DI FLUSSO 225

Figura 8-3. Il Controllo di Flusso predefinito per le cartelle fornito con Plone

Altri Controlli di Flusso

In un sito Plone sono disponibili numerosi controlli di flusso, inclusi controlli privati, controlli per comunità,
controlli per la pubblicazione diretta (one-step workflow n.d.t.) e così via. ZopeZen ha un suo controllo di flusso
come pure PloneCollectorNG. DCWorkflow ha ben quattro controlli di flusso.
Attualmente vi sono due controlli di flusso nel prodotto PloneWorkflows del progetto collettivo in SourceForge
(http://sf.net/projects/collective): il controllo di flusso per comunità e quello per la pubblicazione diretta. Il
primo è molto simile al controllo di flusso predefinito di Plone con poche variazioni. Il controllo di flusso per la
pubblicazione diretta ha solo due stati: Privato e Pubblicato.
Al momento non è semplice installare e disinstallare i controlli di flusso, e non c’è un modo semplice per far
transitare i contenuti da uno stato ad un altro. Per esempio se si installa il controllo di flusso per la pubblicazione
diretta su uno stato già esistente, sarà necessario aggiustare gli stati di tutti gli oggetti per metterli in uno degli
stati nuovi. Questa è probabilmente una situazione semplice, ogni cosa nello stato Pubblicato può rimanere
com’è, mentre tutto il resto deve passare allo stato Privato.

8.3 Aggiungere e modificare il Controllo di Flusso


Ora che abbiamo parlato del controllo di flusso predefinito arriviamo al punto chiave che con ogni probabilità
abbiamo già in mente: Come possiamo cambiare le impostazioni predefinite? Ebbene, come con quasi tutto in
226 INDICE

Plone, è possibile aggiungere, modificare e cancellare tutto di un controllo di flusso tramite la ZMI. Lo strumento
che gestisce i controlli di flusso è il portal_workflow. Nelle sezioni che seguono vedremo come vengono assegnati
i controlli di flusso e poi entreremo nei dettagli di tutte le sue impostazioni.

8.3.1 Impostare il Controllo di Flusso per un Tipo di Contenuto


Dopo aver cliccato su portal_workflow possiamo vedere un elenco di assegnamenti dei controlli di flusso. Una
caratteristica del DCWorkflow è che ogni tipo di contenuto ha uno ed un solo controllo di flusso a lui assegnato;
la Figura 8-4 mostra questi assegnamenti.
8.3. AGGIUNGERE E MODIFICARE IL CONTROLLO DI FLUSSO 227

Figura 8-4. L’elenco dei controlli di flusso per tipo


In questa pagina vediamo un elenco con ogni tipo di contenuto ed il controllo di flusso che vi è applicato. Se
non è specificato alcun controllo di flusso (in altre parole, se il valore è a blank), allora non viene applicato
alcun controllo. Come esempio, l’impostazione predefinita per il tipo Portal Site è a blank. Sicuramente non si
desidera provare a far transitare ad altro stato il sito Plone medesimo ma solo gli oggetti contenuti. Se il valore
è Default, a questo tipo di contenuto verrà applicato il controllo di flusso predefinito in cima alla pagina. Nella
Figura 8-4 viene applicato il controllo di flusso folder_workflow ai tipi tema e folder, mentre per tutti gli altri
tipi viene applicato il controllo plone_workflow. I nomi dei controlli di flusso riferiscono al nome degli oggetti
228 INDICE

di controllo importati o creati con lo strumento di controllo del flusso. Per ulteriori informazioni sui controlli di
flusso disponibili, selezionare la scheda Contents. Questa apre l’elenco dei controlli di flusso che vengono letti
nel sistema, come mostra la Figura 8-5.

Figure 8-5. I Controlli di Flusso disponibili


È possibile aggiungere controlli di flusso cliccando sul pulsante Add Workflow. Questo apre l’elenco dei controlli
disponibili, per crearne uno selezionare un tipo di controllo di flusso ed inserire un nome per esso. Per creare
un controllo di flusso che sia vuoto ma che sia configurabile via web, selezionare dc_workflow e dargli un nome
appropriato; per esempio inserire mio_workflow.

8.3.2 Modificare un Controllo di Flusso


Nella scheda Contents è possibile cliccare su un controllo di flusso per accedere alla schermata della gestione
di quel workflow: a tutti gli stati, transizioni e funzionalità associate. La serie di schede in cima alla pagina
mostrano molto bene le funzionalità del controllo di flusso: Stati, Transizioni, Elenco lavori, Script e Permessi.
Giriamo ora in tutte queste schede ed in alcune altre opzioni che sono disponibili. Se non altrimenti specificato
tutte le prossime schede sono accessibili da questa pagina principale del controllo di flusso.
La creazione o la modifica di un controllo di flusso può richiedere molti click e può fare un po’ di confusione.
Se siamo sviluppatori ci terremo all’uso del file system e volendo, fare tutto con Python, parleremo di questo più
avanti in questo capitolo nella sezione Scrivere un Controllo di Flusso in Python.

Impostare lo Stato Iniziale

Per impostare lo stato iniziale andiamo nella scheda States dove vediamo gli stati disponibili e dove possiamo
notare che, vicino ad uno, c’è un asterisco, come mostra la Figura 8-6.
8.3. AGGIUNGERE E MODIFICARE IL CONTROLLO DI FLUSSO 229

Figura 8-6. Impostare lo stato iniziale per questo controllo di flusso


Impostiamo lo stato iniziale per il nostro controllo di flusso spuntando il box accanto allo stato e cliccando poi
Set Initial State. Qualsiasi contenuto generato con questo controllo di flusso avrà quello stato iniziale. Qual-
siasi contenuto già esistente rimane nello stato in cui si trovava; cambiare lo stato iniziale successivamente non
modifica lo stato. Per ciascun controllo di flusso è possibile impostare solo lo stato iniziale.

Come impostare lo stato iniziale a privato

In molti siti può avere senso che un contenuto non venga mostrato o che non sia accessibile agli utenti, se non ai
soli amministratori o ai possessori, se non dopo che sia stato completato. La maniera migliore per ottenere questo
è quello di impostare lo stato iniziale degli oggetti a qualche valore che garantisca questo grado di sicurezza: per
esempio, privato. Nello stato privato solo i revisori, i manager e i possessori possono vedere l’elemento.
Per impostare lo stato predefinito a privato dalla ZMI, cliccare su portal_workflow e selezionare la scheda Con-
tents. Poi cliccare plone_workflow, selezionare la scheda States e poi scegliere lo stato predefinito spuntando il
box accanto a private. Cliccare infine il pulsante Save Changes. Ora i nuovi contenuti nascono nello stato private
e non sono più accessibili da tutti.

Attenzione!
nell’originale c’è un errore? dice di spuntare accanto a visible - lallo
230 INDICE

Modificare gli Stati

La scheda States elenca gli stati che sono definiti in questo controllo di flusso. All’inizio del capitolo abbiamo
detto che uno stato rappresenta un oggetto in un determinato istante. Ogni stato ha un ID unico che usualmente
è un semplice verbo come in revisione o pubblicato (pending, published). Per aggiungere uno stato inserire un
ID e cliccare Add in fondo alla pagina.
Sono visibili anche le seguenti opzioni:

Title Il titolo dello stato viene mostrato nel sito Plone e dev’essere quindi user-friendly.
Description La descrizione può essere una lunga descrizione dello stato. Non viene attualmente mostrata agli
utenti ma potrebbe esserlo in futuro.
Possible transitions Questa elenca tutte le possibili transizioni che possono intervenire sullo stato. Quest’elenco
contiene elementi solo se realmente esiste almeno una transizione nel sistema. Selezionare semplicemente
le transizioni di cui abbiamo bisogno per questo stato. Selezionando una transizione per questo stato stiamo
scegliendo che il punto iniziale per questa transizione sia questo stato.

Per modificare uno stato, inserire le modifiche e premere Save per confermare. La scheda Permission si aprirà
con i permessi che verranno applicati ad un oggetto quando si troverà in questo stato. Ciò può significare il
cambiamento dei permessi su un oggetto quando arriva (transiziona) a questo stato. Il modulo è sufficentemente
auto esplicativo; per abilitare l’utente anonimo a vedere l’oggetto, spuntare il box che corrisponde a View ed ad
Anonimous e cliccare Save, come mostra la Figura 8-7.

Figura 8-7. Pagina dei permessi degli stati


Se si cambiano i permessi per un certo stato del controllo di flusso nasce un problema che è necessario risolvere.
Ogni contenuto esistente in quello stato non ha impostati i nuovi permessi. Quel contenuto ha i permessi del
8.3. AGGIUNGERE E MODIFICARE IL CONTROLLO DI FLUSSO 231

vecchio controllo di flusso ed è necessario aggiornarli. Quando abbiamo finito di fare tutte le modifiche andiamo
alla pagina principale del controllo di flusso e clicchiamo su Update Security Settings, come mostra la Figura
8-4. Questo aggiornamento può prendere un bel po’ di tempo in quanto dipende dal numero di oggetti su cui si
interviene.
La scheda Variables consente di assegnare un valore ad una variabile quando l’oggetto è in questo stato. Il
controllo di flusso determina l’elenco delle variabili disponibili per ciascun stato. Per maggiori informazioni
vedere la sezione Modificare le variabili

Modificare le transazioni

La scheda Transitions elenca le transizioni che esistenti in questo controllo di flusso. All’inizio del capitolo
abbiamo detto che una transizione rappresenta i possibili cambiamenti dello stato di un oggetto. Ciascuna transi-
zione ha lcune variabili che sono mostrate nella pagina di sommario. Per aggiungere una transizione inserire un
ID e cliccare Add in fondo alla pagina, come mostra la Figura 8-8.
232 INDICE

Figura 8-8. Pagina di dettaglio della transizione


Se ora clicchiamo su una transizione apriamo i seguenti dettagli per questa transizione:

Title È il titolo di questa transizione.


Description La descrizione dettagliata per questa transizione.
Destination state È lo stato che sarà raggiunto dopo questa transizione. Lo stato sorgente iniziale è definito
assegnando la transizione allo stato.
8.3. AGGIUNGERE E MODIFICARE IL CONTROLLO DI FLUSSO 233

Trigger type Indica come verrà svolta questa transizione. Automatic significa che avviene appena un oggetto
arriva a questo stato. Initiated by user action è la scelta più comune ed è che un utente debba attivare la
transizione cliccando un collegamento.
Script (before) Esegue questo script prima che avvenga la transizione.
Script (after) Esegue questo script dopo che la transizione è avvenuta.
Guard È il grado di sicurezza per questo stato (spiegata brevemente).

Display in actions box Indica come viene mostrata questa transizione in Plone. Inserendo un valore assicura
che la transizione sia inserita come azione. Si potrà quindi ottenere la transizione come azione chiamando
le azioni.

Tra questi valori il Destination state è davvero interessante. Anche se abbiamo sostenuto in precedenza che le
transizioni normalmente cambiano uno stato, ciò non è richiesto. Siccome ogni transizione è in grado di lanciare
script e scrivere qualcosa nella history, a volte è utile non cambiare stato. Per un esempio di questo modo d’uso,
vedere la sezione Uso del controllo di flusso per tracciare le modifiche, più avanti in questo capitolo. Se vogliamo
che la transizione cambi lo stato, selezioniamo il nuovo stato come stato di destinazione.
Una transizione può avere più punti di partenza ma solo una destinazione; se abbiamo bisogno di avere desti-
nazioni multiple sono necessarie altrettante transizioni. Possiamo specificare script da eseguire prima o dopo la
transizione. Due semplici esempi sono muovere un oggetto in un controllo di flusso e inviare una notifica e-mail.
La sezione Problemi comuni ed esempi tratta entrambi i casi.
Prima che qualsiasi transizione possa essere eseguita, una sentinella di guardia controlla l’intera transizione
assicurando che l’utente che ha lanciato la transizione abbia i diritti per farlo. La sentinella è composta dai
seguenti tre componenti:

Permission(s) Sono i permessi richiesti. Permessi multipli devono essere separati da punti e virgola (;).
Role(s) Sono i ruoli richiesti. Ruoli multipli devono essere separati da punti e virgola (;).
Expression È una espressione del controllo di flusso. Per ulteriori informazioni vedere la sezione Modificare le
espressioni del controllo di flusso più avanti in questo capitolo. Per ciascun valore specificato la sentinella
deve valutarla a true prima di poter continuare. Se la prova con uno di questi valore fallisce, la transizione
non viene eseguita. Si noterà che solitamente le sentinelle hanno specificati solo uno o due valori.

Modificare le variabili

La scheda Variables elenca le variabili che sono state create e modificate nel controllo di flusso. Non ne abbiamo
parlato molto finora perché ci siamo concentrati sugli stati e sulle transizioni. Questa sezione tratta delle variabili.
Non sempre è possibile, e non si consiglia di provarlo, incapsulare tutte le informazioni necessarie in un controllo
di flusso, semplicemente usando gli stati e le transizioni. Ma è possibile usare le variabili per contenere alcune
informazioni correlate al controllo di flusso. Come, nel precedente esempio della carta di credito, il conto può
essere pagato in svariati modi (Servizio di Internet banking, assegno e così via). È possibile conservare l’ammon-
tare del metodo (100 Euro, per esempio) in una variabile. Ad un rigetto o modifica del conto questo ammontare
dovrà essere aggiornato. Lo scopo di una variabile è di avere qualcosa che cambia al cambiare di ogni stato e
transizione.
Ritornando alla pagina principale del controllo di flusso, clicchiamo la scheda Variables per vedere l’elenco di
tutte le variabili. Per aggiungere una variabile, inserire l’ID per la variabile e premere su Add in fondo alla
pagina. Per determinare in qualsiasi momento in quale stato si trovi un oggetto, il DCWorkflow contiene lo stato
corrente in una variabile dell’oggetto. Il nome predefinito di questa variabile è review_state.
234 INDICE

Nota
Se si ha la necessità di cambiarlo perché va in conflitto con qualche altro nome, è possibile
farlo in fondo alla pagina. Questo causerà però la perdita dello stato da parte di tutti gli
oggetti attuali, quindi porre molta attenzione nel cambiare questo valore.

Ogni variabile del controllo di flusso possiede le seguenti proprietà:

Description È la descrizione della variabile


Make available to catalog Queste variabili vengono messe in un’elenco che può essere mostrato al catalogo.
Non inserisce indici o metadati nel catalogo, questo dev’essere fatto manualmente.
Store in workflow Determina se le informazioni debbano essere conservate nel controllo di flusso piuttosto che
nell’oggetto.
Variable update mode Determina quando aggiornare la variabile
Default value Determina un valore predefinito formato stringa
Default expression È il valore predefinito tramite una espressione. Se è presente viene usato al posto di Default
value (per maggiori informazioni vedere la sezione Modificare le espressioni del controllo di flusso più
avanti nel capitolo).
Info. guard Sono impostazioni di sicurezza per questa variabile. Queste impostazioni di sentinella sono simili
a quelle analoghe delle transizioni, comunque qui la sentinella interviene quando si accede alla variabile.

Modificare l’elenco dei lavori

La scheda Worklist consente l’accesso a tutti gli elenchi dei lavori che sono assegnati in questo controllo di flusso.
Un elenco lavori (worklist) è un metodo per interrogare il controllo di flusso per informazioni a proposito dei
suoi numerosi oggetti. Per esempio, vorremmo chiedere facilmente al controllo di flusso tutti i crediti della nostra
carta di credito che non abbiamo ancora pagato .
Per aggiungere un worklist inserire un ID e premere Add. Ciascun elenco lavori ha le seguenti proprietà:

Description È la descrizione dell’elenco lavori.


Cataloged variable matches È il valore a cui deve corrispondere la variabile per essere inserita in questo elenco
lavori. La variabile corrispondente è la variabile di stato del controllo di flusso contenuta nell’elenco delle
variabili (il nome della variabile predefinito per questa variabile è review_state).
Display in actions box Sono informazioni da mostrare nell’interfaccia utente. l’inserimento di un valore assi-
cura che la transizione sia inserita come azione. Sarà quindi possibile ottenere questa transizione come
azione chiamando le azioni.
Guard È una sentinella all’accesso di quest’elenco lavori.

Ritornando all’esempio della carta di credito, se vogliamo sapere tutti i conti che dobbiamo ancora approvare,
potremmo mettere queste informazioni in un worklist. Per prima cosa la variabile review_state dovrà contenere
lo stato corrente per ciascun elemento. Tutti i conti della carta di credito che devono essere approvati devono
essere nello stato review. Poi aggiungiamo un elenco lavori con il nome di review_queue dove il valore della
variabile sia pending. Possiamo quindi chiamare l’elenco di tutti gli elementi in review_queue.
Sebbene l’elenco lavori sia un modo conveniente per conservare informazioni, Plone non lo usa. Plone usa
invece ZCatalog per chiamare gli oggetti che sono sottoposti a controllo di flusso. Siccome gli elenchi lavori di
DCWorkflow usano lo strumento di catalogazione, il risultato è il medesimo.
8.3. AGGIUNGERE E MODIFICARE IL CONTROLLO DI FLUSSO 235

Modificare gli Script

La scheda Scripts elenca gli script disponibili in questo controllo di flusso. Questo elenco è una reale cartella
standard nella ZMI e vi si può aggiungere quasi ogni cosa. Ma in questa cartella dovremo aggiungere solo
script Python e l’unica ragione per farlo dovrebbe essere aggiungere uno script per una gestione avanzate delle
transizioni.
Per aggiungere uno script dalla scheda Scripts selezionare Scripts dal menù a cascata e dare un ID allo script.
Lo script è passato ad uno ed un solo oggetto, che è l’oggetto base del controllo di flusso delle espressioni; per
ulteriori informazioni su questo oggetto vedere la sezione Modificare gli script del Controllo di Flusso più avanti
nel capitolo. Per esempio, se vogliamo accedere all’attuale oggetto nel controllo di flusso, possiamo usare uno
script Python come il seguente:

##parameters=state_change
obj = state_change.object

Ciò che succede in questo script è cosa da sviluppatori, noi possiamo far girare quasi ogni cosa qui. Possiamo
controllare eventi, e accedere ad altri controlli di flusso e transizioni. Per degli esempi di script vedere le sezioni
Inviare notifiche via E-Mail e Spostare oggetti più avanti nel capitolo. Quando viene eseguito lo script, viene
eseguito con l’utente che avvia la transizione. Se è necessario eseguirlo come qualcun altro, è possibile asse-
gnargli un ruolo proxy. Ritornando alle transizioni, è possibile assegnare questo script ad un numero arbitrario
di transizioni nelle opzioni script (after) e script (before). È possibile avviare lo script sia prima che dopo una
transizione.

Modificare i Permessi

La scheda Permissions elenca i permessi gestiti da questo controllo di flusso. Abbiamo già visto questi permessi
esaminando gli stati. In questa scheda si imposta l’elenco dei permessi gestibili da quegli stati. Per aggiungere
un nuovo permesso, selezionare il permesso dall’elenco a cascata e selezionare Add.

É possibile modificare un documento pubblicato?

Ebbene, nel controllo di flusso predefinito, se non si ha il ruolo di manager non è possibile modificare un do-
cumento pubblicato. Se si abilita il possessore del documento a modificarlo si dovrà poi sottoporlo nuovamente
a revisione. Comunque questa sembra una richiesta comune ed è banale soddisfarla. Nalla ZMI cliccare por-
tal_workflow e selezionare la scheda Contents. Poi cliccare plone_workflow e selezionare la scheda States. Clic-
care infine su published e scegliere la scheda Permission. Spuntare il box che corrisponde a concedere all’owner
la possibilità di modificare i contenuti del portale.
*Insert 3294s0801.tif*
Cliccare su Save Changes per salvare i nostri permessi. Siccome abbiamo alterato le impostazioni della sicurezza
dobbiamo cliccare su portal_workflow, selezionare la scheda Contents e poi cliccare su Update security settings.
Questo aggiorna tutti gli oggetti del nostro sito ed assicura che i (nuovi) permessi vengano applicati agli oggetti
esistenti. Ora i possessori possono modificare i loro documenti anche quando essi sono nello stato published.

Modificare gli script del Controllo di Flusso

Gli script danno allo sviluppatore l’opportunità di intervenire sulla logica di una transizione. Questa logica può
essere quasi ogni cosa si desidera. Potremmo controllare che siano rispettate alcune condizioni (per esempio,
è stato fatta la correzione degli errori ortografici del documento?) o se sono state effettuate alcune delle azioni
speciali. Quando l’oggetto è sottoposto a transizione viene chiamato lo script.
236 INDICE

Quando viene chiamato uno script, gli viene passato un parametro extra. Questo parametro extra fornisce l’ac-
cesso a tutti i tipi di elementi e attributi correlati alla transizione. Questo parametro è denominato state_change
ed ha i seguenti attributi:

status è lo stato del controllo di flusso


object È l’oggetto sottoposto a transizione nel controllo di flusso
workflow È l’oggetto workflow corrente dell’oggetto sottoposto a transizione
transition È l’oggetto transizione che viene eseguito
old_state È lo stato originario dell’oggetto
new_state È lo stato di destinazione dell’oggetto
kwargs Sono gli argomenti parole-chiave passate al metodo doActionFor
getHistory È un metodo che non prende parametri e ritorna una copia della history degli oggetti del controllo
di flusso.
getPortal È un metodo che non prende parametri e ritorna l’oggetto Plone root
ObjectDeleted(folder) Dice al controllo di flusso che l’oggetto che sta per essere sottoposto a transizione è
stato cancellato; prende l’oggetto a cui si desidera ritorni l’utente. Passa all’eccezione la cartella a cui si
vuol redirigere l’utente (vedere la sezione Spostare oggetti più avanti nel capitolo)
ObjectMoved(newObject, newObject) Dice al controllo di flusso che l’oggetto che sta per essere sottoposto
a transizione è stato spostato. Passa all’eccezione la cartella a cui si vuol redirigere l’utente (vedere la
sezione Spostare oggetti più avanti nel capitolo)
getDateTime È un metodo che non prende parametri e ritorna l’oggetto DateTime relativo alla transizione

Per esempio, per sapere a quale sia lo stato di destinazione della transazione e in che momento, è necessa-
rio un oggetto Script (Python) come il seguente, che ci darà proprio questa informazione. Lo script scrive le
informazioni relative alla transizione nel file di log:

##parameters=state_change
st = ’From %s to %s on %s’ % (
state_change.old_state,
state_change.new_state,
state_change.getDateTime())
context.plone_log(st)

Consiglio
Mentre si scrive un oggetto Script (Python) è possibile aver bisogno di scrivere in un file
di log per facilitare la correzione degli errori (debug). Uno script denominato plone_log fa
proprio questo, prende una stringa e la passa alle funzioni di registrazione di Plone. Di
conseguenza, chiamando context.plone_log si ha un utile strumento per correggere gli
errori.

Quando si assegna uno script ad una transizione si hanno due possibilità: before e after (prima e dopo). Come
suggeriscono i nomi, uno script impostato a before viene lanciato prima della transizione. Ciò è sfruttabile per
script che devono controllare se qualcosa deve avvenire prima che la transizione sia lanciata, come controllare
se un altro oggetto o pagina dipendenti siano stati aggiornati o che non vi siano errori ortografici. Uno script
impostato ad after viene lanciato una volta che la transizione è stata completata, anche se, in qualsiasi momento,
una eccezione inaspettatamente sollevata dallo script, può far fallire la transizione e far rimanere l’oggetto nel
suo stato originale, mentre l’eccezione viene mostrata all’utente.
8.4. PROBLEMI COMUNI ED ESEMPI 237

Modificare le espressioni del controllo di flusso

In questo capitolo abbiamo visto valori che possono essere espressi tramite espressioni del controllo di flusso.
Per esempio il valore assegnato ad una variabile che è il risultato di una espressione del controllo di flusso.
Questa espressione non ha niente di speciale; è semplicemente una espressione TAL (Template Attribute Lan-
guage) con alcune differenti variabili disponibili. Abbiamo già studiato le espressioni TAL nel ‘Capitolo 5‘_ e
quindi dovremmo avere famigliarità con quelle espressioni e le loro opzioni, come del Python, stringhe e path
expression.
A differenza delle espressioni TAL standard, alcuni parametri extra vengono passati allo spazio dei nomi (na-
mespace) relativo ad un determinato controllo di flusso. Lo spazio dei nomi di una espressione del controllo di
flusso contengono i seguenti parametri:

here È l’oggetto sottoposto a transizione nel controllo di flusso


container È il contenitore dell’oggetto sottoposto a transizione nel controllo di flusso
state_change È l’oggetto del cambiamento di stato referenziato nella sezione Modificare gli script del Controllo
di Flusso
transition È la transizione che viene eseguita, identico a state_change.transition.
status È lo stato originario dell’oggetto, identico a state_change.old_state.
workflow È il controllo di flusso per questo oggetto
scripts Sono gli script disponibili in questo controllo di flusso
user È l’utente che esegue la transizione

8.4 Problemi comuni ed esempi


Ora presentiamo alcuni comuni problemi che si possono risolvere facilmente usando il controllo di flusso. Quan-
do un’utente provoca una transizione nel controllo di flusso, questa transizione gira usando l’account di quello
specifico utente. In quasi tutti i seguenti esempi, un utente normale può non avere i permessi sufficienti per com-
pletare l’operazione. Per esempio, gli utenti con il ruolo di member non hanno normalmente il diritto all’accesso
all’elenco degli utenti a meno che questo permesso non sia stato dato loro esplicitamente.
Per risolvere questo problema di permessi, come già segnalato, ad alcuni dei seguenti oggetti Script (Python) è
stato dato un ruolo leggermente diverso. Per impostare un ruolo proxy su uno script, accedere alla scheda Proxy
di un oggetto o poi selezionare l’utente che deve lanciare lo script, come mostra la Figura 8-9.
238 INDICE

Figura 8-9. Impostare le opzioni proxy su uno script


Ci assicureremo, ovviamente, che i nostri script siano eseguiti con il ruolo minimo necessario, il che dipende
direttamente da cosa fa il nostro script.

8.4.1 Introduzione delle espressioni del Controllo di Flusso


Le successive espressioni per il controllo di flusso sono alcuni utili esempi che possono essere usati in varie
posizioni
Per ottenere i commenti, o una stringa vuota, da questa transizione usiamo:

python:state_change.kwargs.get(’comment’, ’’)

Per ottenere il titolo della cartella che contiene l’oggetto usiamo

container/Title

Per provare se il vecchio stato è review usiamo:

python: state_change.old_state == ’review’

Per avere l’utente che sta eseguendo la transizione usiamo:

user/getId

Così se vogliamo tracciare chi è l’ultimo utente che ha eseguito una transizione sull’oggetto, è possibile aggiun-
gere una variabile last user nel controllo di flusso. Lo si può fare andando nel controllo di flusso e cliccando la
scheda Variables. Poi aggiungiamo la variabile last_user. Se si imposta la variabile Default expr a user/getId,
ogni volta che l’oggetto cambia, questo valore viene tenuto per noi.
8.4. PROBLEMI COMUNI ED ESEMPI 239

8.4.2 Uso del controllo di flusso per tracciare le modifiche


In una particolare applicazione di un nostro cliente abbiamo dovuto tener traccia del momento in cui un elemento
viene modificato e delle ragioni di questa modifica in modo che quando successivamente si guarda l’elemento si
possa trovare un commento per ogni cambiamento. Grazie al controllo di flusso questo è facile ottenerlo.
Nel nostro caso il controllo di flusso aveva solo uno stato ma ora questo funziona per quasi tutti i workflow. In
quello, abbiamo aggiunto una transizione denominata edit. Quella transizione non modifica realmente lo stato
dell’oggetto; lo stato di destinazione per la transizione era (Remain in state), che significa che non deve evvenire
alcun cambiamento.
Quando viene modificato un oggetto, viene chiamato un metodo per effettuare la modifica. Per esempio, quando
viene modificato un documento, il metodo chiamato è document_edit.cpy. Si può trovare questo script cliccando
su portal_skins, poi su plone_form_scripts e quindi su document_edit. Tutto quello che si deve fare è aggiungere
a quello script una riga prima dell’ultima:

context.portal_workflow.doActionFor(new_context,
’edit’, comment=’’)

Il metodo doActionFor di portal_workflow effettua le transizioni date (nel nostro caso edit) per l’oggetto che vie-
ne passato (nel nostro caso context). Ogni volta che l’oggetto viene modificato viene eseguita quella transizione
edit. Ciò causa l’aggiunta di una riga all’elenco dei commenti che mostra chi ha modificato l’oggetto, quando è
stato aggiunto e qualsiasi commento ad esso associato.
Quando un oggetto viene modificato, non vengono inseriti realmente commenti, quindi per essere un po’ più
avanzati, dobbiamo modificare il modello di modifica dei documenti (edit template) affinché includa un campo
commenti. Poi possiamo accedere a questo elenco di commenti andando nella scheda State dove viene mostrato,
in fondo, l’elenco delle modifiche.

8.4.3 Spostare oggetti


Una utile possibilità è lo spostamento di un oggetto durante il controllo di flusso. Per esempio potremmo spostare
tutti i rilasci stampa in una cartella denominata Press Release ogniqualvolta ne viene pubblicato uno. I
contenuti possono essere creati e modificati ovunque e poi spostati con la pubblicazione in questa cartella. Lo
script di esempio nel Listato 8-1 sposta l’oggetto che è sottoposto al controllo di flusso nella cartella Members.
Per aggiungere questo script andare nello strumento del controllo di flusso nella ZMI e selezionare la scheda
Scripts. Poi scegliere Script (Python) dal box con l’elenco a cascata. Dare al nuovo oggetto il nome moveObject
quindi inserire il Listato 8-1 in questo script.
Listato 8-1. Spostare un oggetto

##parameters=state_change
# get the object and its ID
obj = state_change.object
id = obj.getId()

# get the src folder and the destination folder


dstFldr = context.portal_url.Members
srcFldr = obj.aq_parent

# perform the move


objs = srcFldr.manage_cutObjects([id,])
dstFldr.manage_pasteObjects(objs)
240 INDICE

# get the new object


new_obj = dstFldr[id]

# pass new_obj to the error, *twice*


raise state_change.ObjectMoved(new_obj, new_obj)

Dobbiamo fare ancora alcune cose; primo, assegnare questo script ad una transizione. Normalmente si usa
uno script simile nella transizione publish. Per far questo andiamo in quella transizione ed assegnamo il valore
moveObject al campo script (after).
Secondo, esiste un altro piccolo problema: questo script sposta gli oggetti nella cartella Members. Probabil-
mente abbiamo in mente una destinazione migliore. Per fare un tale spostamento l’utente deve avere i diritti
appropriati per muovere oggetti tra queste cartelle. Normalmente solo un manager può spostare oggetti dentro la
cartella Members. Così è necessario dare allo script il ruolo proxy di manager. Si può farlo cliccando su Scripts,
poi su moveObject e selezionando la scheda Proxy. Assegnare il ruolo di manager allo script. Nel ‘Capitolo 9‘_
si possono avere ulteriori informazioni sulla sicurezza e sui ruoli locali.
Guardando il codice, prima lo script ottiene l’oggetto e l’ID dell’oggetto dallo spazio dei nomi della transizione.
Poi ottiene la cartella sorgente e quella di destinazione. Poi effettua il copia incolla utilizzando l’interfaccia API
(Application Programming Interface) di Zope ObjectManager. È possibile ovviamente determinare programma-
ticamente queste cartelle, magari in base all’utente che realizza la transizione o al tipo di contenuto che viene
spostato. Infine si ottiene l’oggetto e lo si passa ad una eccezione ObjectMoved.
L’eccezione ObjectMoved è una speciale eccezione del DCWorkflow. Dandole due volte il nuovo oggetto come
parametro, il nuovo oggetto viene passato al front-end Plone. Ciò risulta critico e quindi quando l’utente viene
mandato all’oggetto in seguito alla modifica, è alla nuova posizione dell’oggetto, non a quella vecchia. Possiamo
ovviamente scrivere una funzione che riporti indietro l’oggetto qualora fosse respinto, magari nella cartella home
del collaboratore.
Un altro caso speciale e ancora più insolito e di cancellare un oggetto con il controllo di flusso. Normalmente
la cancellazione è una azione del contenitore dell’oggetto quindi è insolito trovarla in un controllo di flusso.
Per questo scopo si può sollevare l’eccezione ObjectDeleted. Il Listato 8-2 mostra lo script per effettuare una
cancellazione.
Listato 8-2. Cancellare un oggetto

##parameters=state_change

# get the object


obj = state_change.object
id = obj.getId()

# get the parent folder, delete the object


srcFldr = obj.aq_parent
srcFldr.manage_delObjects([id,])

# raise the object deleted method and pass


# the folder you want to return to
raise state_change.ObjectDeleted(srcFldr)

Possiamo chiamare questo script deleteObject e cancellare completamente oggetti tramite il controllo di flusso.
Di nuovo, per assicurare che l’errore sia sollevato, Plone vuol sapere cosa fare; in questo caso, egli prende l’utente
dalla cartella contenente quell’oggetto.
8.4. PROBLEMI COMUNI ED ESEMPI 241

8.4.4 Inviare notifiche via E-Mail


Se si ha un sito Plone che un utente non visita regolarmente è abbastanza stupido mettere informazioni su cosa
deve essere revisionato e quando. Si può trasformare il controllodi flusso in un rudimentale sistema di notifica
utilizzandolo per inviare una e-mail agli utenti. I canale di notifica delle e-mail è solo un piccolo esempio, Può
diventare un messaggio istantaneo, come un messaggio di testo spedito via telefono e così via. Lasciamo le altre
possibilità all’immaginazione.
In questo esempio, inviamo una e-mail tramite l’oggetto MailHost sul server ad ogni utente del sistema che abbia
il ruolo di reviewer, dicendo loro che un nuovo oggetto è stato sottoposto a revisione. È uno script realmente più
complicato del primo che abbiamo mostrato poco fa, in quanto effettua alcuni passi: definizione delle variabili,
ricerca del nome dell’account di ciascun revisore, ricerca dell’indirizzo e-mail, invio di una e-mail. Il Listato 8-3
mostra lo script.
Listato 8-3. Inviare una notifica e-mail

##parameters=state_change
# the objects we need
object = state_change.object
mship = context.portal_membership
mhost = context.MailHost
administratorEmailAddress = context.email_from_address

# the message format, %s will be filled in from data


message = """
From: %s
To: %s
Subject: New item submitted for approval - %s

%s

URL: %s
"""

Questo imposta il messaggio e gli oggetti di cui avevamo bisogno. Oltre all’oggetto soggetto a transizione,
abbiamo bisogno anche di un riferimento allo strumento per la gestione degli utenti portal_membership e al
server SMTP (Simple Mail Transfer Protocol ) via MailHost. Il messaggio è facilmente configurabile per mandare
una e-mail in ogni formato si desideri.
Poi usiamo il metodo listMembers dell’oggetto portal_membership per ottenere un elenco dei collaboratori. Per
ciascun collaboratore si può vedere in seguito se il ruolo di revisore è nell’elenco dei ruoli per quell’utente
chiamando il metodo getRoles:

for user in mship.listMembers():


if "Reviewer" in mship.getMemberById(user.id).getRoles():

Il lettore astuto noterà che girare su ogni collaboratore in un sito Plone può essere un po’ lento se si hanno migliaia
di utenti. Nel prossimo capitolo modifichiamo questo script per avere l’elenco degli utenti di un determinato
gruppo.
Non è possibile inviare una e-mail se non si un indirizzo dell’utente, quindi controlliamo prima che ci sia un
indirizzo valido. Manca solo formattare il messaggio e-mail e spedirlo. Per far questo si può usare la funzionalità
di sostituzione di stringhe di Python e passarle i quattro parametri che corrispondono ai %s della variabile
message impostata all’inizio dello script. Dopo questa sostituzione la variabile msg contiene la e-mail che
vogliamo spedire. Per spedirla chiamiamo semplicemente il metodo send dell’oggetto MailHost e passare la
stringa della e-mail:
242 INDICE

if user.email:
msg = message % (
administratorEmailAddress,
user.email,
object.TitleOrId(),
object.Description(),
object.absolute_url()
)
mhost.send(msg)

Il risultato è la seguente e-mail che verrà spedita:

From: administrator@agmweb.ca
To: andy@agmweb.ca
Subject: New item submitted for approval - Plone’s great

We all know Plone is a great product, but with the newest release
it’s gotten even better...

URL: http://agmweb.ca/Members/andym/News_Item_123

L’‘Appendice B‘_ contiene il listato completo di questo script.

8.4.5 Uso del PloneCollectorNG


PloneCollectorNG è un raccoglitore di problemi disponibile in Plone. Ci sono molti tracciatori di problemi in
giro ma questo è quello che usiamo e raccomandiamo in Plone. In effetti sembra che scrivere un tracciatore sia
alquanto comune tra gli sviluppatori. Una delle cose realmente simpatiche del controllo di flusso è che abitua
gli utenti a significativi cambiamenti nell’uso di una applicazione. Come per lo sviluppatore, sviluppare prodotti
agganciati ad un DCWorkflow consente all’applicazione di rimanere flessibile. Si può trovare PloneCollectorNG
all’indirizzo http://www.zope.org/Members/ajung/PloneCollectorNG.
Il prodotto aggiunge durante l’installazione una serie di tipi di contenuto, uno dei quali è PloneIssueNG, che è un
issue (report bug, problema). Piuttosto di mettere nel codice (hard-coding) esattamente come il problema cambia
nel database, al problema viene assegnato un controllo di flusso separato. Quel controllo di flusso contiene stati,
transizioni, variabili ed elenchi lavori appropriati.
Ad ogni passaggio si può ricavare in quale stato si trova un oggetto chiamando il metodo getInfoFor di por-
tal_workflow. Questo utile metodo accetta un oggetto e la variabile da cercare. Nel controllo di flusso di Plone-
CollectorNG questa variabile è denominata state, mentre nel controllo di flusso Plone è detta review_state. Per
trovare lo stato di un oggetto usiamo per esempio:

portal_workflow.getInfoFor(obj, "review_state")

Possiamo trovare i possibili stati di un oggetto esaminando lo stato dell’oggetto direttamente nel controllo di
flusso, in questo modo:

portal_workflow[’pcng_workflow’].states._mapping.keys()

Come risultato avremo che se l’utente vuol avere un semplice sistema di tracciatura dei problemi, allora mo-
dificare questo controllo di flusso via web diventa banale (se, quando è stata sviluppata l’applicazione, è stato
considerato lo strumento di controllo di flusso). Compariamo questo sistema ad un altro popolare bug-tracking,
Bugzilla dove, cambiare uno stato o una transizione richiede ore ed ore di programmazione Perl per trovare tutte
le referenze ad uno stato di errore (bug’s state) nel codice (hard-coded).
8.4. PROBLEMI COMUNI ED ESEMPI 243

8.4.6 Distribuire e scrivere il Controllo di Flusso


Se si ha un controllo di flusso molto esteso per la propria applicazione, ci sono alcuni differenti modi di di-
stribuirlo. Le prossime sezioni chiudono la trattazione del controllo di flusso presentando una coppia di tali
opzioni.

Scrivere tramite la ZMI

Probabilmente scrivere il controllo di flusso tramite la ZMI è il modo più semplice anche se più laborioso.
Sebbene la ZMI porti spesso la gente a impazzire, essa rimane la via più semplice per impostare le opzioni.
Sfortunatamente una volta che si è iniziato a scrivere il controllo di flusso tramite la ZMI siamo bloccati in quel
paradigma. In altre parole non vi è un modo semplice per modificare o alterare quel controllo di flusso sul file
system. Ovviamente, abbiamo parlato, precedentemente in questo capitolo, della modifica di un controllo di
flusso via web.
Per esportare un controllo di flusso dalla ZMI, cliccare su portal_workflow e selezionare la scheda Contents,
selezionare i controlli di flusso che si desidera esportare spuntando i box sulla sinistra nella ZMI cliccando
poi import/export. Nella parte in cima della pagina di esportazione, selezionare Download to local machine e
cliccare export. Viene creato un file con estensione .zexp che può essere salvato e redistribuito. Selezionando
XML Format si ottiene un file nel formato XML (Extensible Markup Language) con estensione .xml.
Se si ha un controllo di flusso in formato .zexp o .xml l’importazione in Plone è assolutamente lineare. Mettere
quel file nella cartella di importazione di Zope sul file system. Può essere sia la cartella home dell’istanza sia la
cartella Zope.
Clicchiamo poi portal_workflow, scegliamo la scheda Contents e clicchiamo su import/export. Nella parte in
cima alla pagina si può vedere un semplice modulo che prende il nome di un file da importare. Inseriamo qui
il nome del file e lasciamo selezionato Take ownership of imported objects. Clicchiamo il pulsante Import
per importare il controllo di flusso. Il controllo di flusso viene importato e gli viene dato il nome specificato
nell’esportazione.

Scrivere un Controllo di Flusso in Python

La maniera preferita dai programmatori per scrivere un controllo di flusso è probabilmente usare Python, in
quanto può essere fatto tutto con Python e facilmente distribuito. Primo, facciamo un modulo Python nel file
system. In cima al file importiamo gli strumenti necessari, come segue:

from Products.CMFCore.WorkflowTool import addWorkflowFactory


from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition

Secondo, facciamo una funzione che crei il controllo di flusso. L’‘Appendice A‘_ elenca le API per scrivere un
controllo di flusso un po’ più in dettaglio. Ma possiamo semplicemente barare e guardare ai numerosi esempi
disponibili nel progetto PloneWorkflow nel collective (http://sf.net/projects/collective) o anche in quelli contenuti
in Plone. Per esempio:

def sample(id):
""" Sample workflow """
ob = DCWorkflowDefinition(id)
ob.states.addState(’private’)
ob.states.addState(’public’)
# add transitions
return ob

Finalmente registriemo il controllo di flusso nel sistema così:


244 INDICE

addWorkflowFactory(sample,
id=’sample_workflow’,
title=’Sample workflow’)

Questo script deve far parte della installasione di un prodotto. Il Capitolo 12 tratta dello scrivere ed installare
prodotti.
Ora, naturalmente, è disponibile una scorciatoia, che si chiama DCWorkflowDump. Questa prende il codice dalla
ZMI e lo sbatte (dump) dentro un modulo Python. Il codice sorgente di DCWorkflowDump è disponibile nel
collective (http://sf.net/projects/collective) ma anche nel sito web del manuale Plone all’indirizzo http://plone-
book.agmweb.ca si può trovare un file .zip con il codice.
Per installare DCWorkflowDump, decomprimere il file e copiare la cartella denominata DCWorkflowDump
nella cartella Products della nostra installazione Plone. Come controllo per sapere se siamo nella cartella
giusta, verifichiamo che la stessa cartella contenga, tra le altre cose, una cartella per DCWorkflow. Poi riavviamo
l’istanza Plone.
Una volta riavviato Plone, rechiamoci nella ZMI in quel particolare controllo di flusso e noteremo una nuova
scheda denominate dump. Scegliamo quella pagina per vedere la schermata di dump e clicchiamo su Dump it!
per ottenere il controllo di flusso. Questo prende il nostro controllo di flusso e lo formatta in Python. Salviamo
questo file nel nostro prodotto e quindi ora abbiamo un file Python da manipolare. Questo prodotto è un valido
strumento poiché consente di creare il controllo di flusso con la ZMI e poi distribuirlo e alterarlo tramite Python.
Duplicate explicit target name: “capitolo 3”.
Duplicate explicit target name: “capitolo 5”.
Duplicate explicit target name: “capitolo 9”.
Duplicate explicit target name: “appendice a”.
Duplicate explicit target name: “appendice b”.
Capitolo 9

Capitolo 9: Gestire la sicurezza e gli utenti

245
246 CAPITOLO 9. CAPITOLO 9: GESTIRE LA SICUREZZA E GLI UTENTI
Indice

Plone ha un potente e granulare modello di sicurezza. Tale sistema consiste in una miriade di opzioni per la
sicurezza ad ogni livello tanto che ogni oggetto può avere una propria configurazione della sicurezza per un certo
utente, ruolo o gruppo e così via.
Per rendere il problema trattato in questo capitolo vogliamo condividere una citazione interessante:

La sicurezza è dura. (Security is hard.)

—Jim Fulton, capo architetto di Zope

La sicurezza per Plone è così potente e sfaccettata che può essere veramente duro farne il debug e gestirla. Ma
forse nessun’altra parte di un sito Plone è così importante come quello da cui si ottengono i permessi relativi alla
sicurezza. Lasciare un difetto nella sicurezza del sito è probabilmente la più grande stupidaggine che si possa
fare e, per questa ragione, tratteremo la sicurezza in modo esaustivo.
In questo capitolo prima tratteremo tutta la terminologia sull’utente e le interfacce chiave con cui gli utenti inte-
ragiscono. Poi tratteremo l’aggiunta e la modifica di utenti e gruppi tramite l’interfaccia Plone. Successivamente
passeremo per gli strumenti chiave e le API (Application Programming Interfaces) che gestiscono gli utenti e la
loro sicurezza. Poi tratteremo l’uso degli strumenti Python per generare script per intervenire sugli utenti e le loro
proprietà. Infine tratteremo la sicurezza del server e l’autenticazione espansa dell’utente fornendo un dettagliato
esempio su come incorporare gli utenti da un server LDAP (Lightweight Directory Access Protocol ).

9.1 Amministrare gli utenti


Uno dei più comuni problemi che deve risolvere un amministratore di portale Plone è quello di comunicare
con i collaboratori del sito. L’amministrazione comprende usualmente la gestione delle password e la modifica
delle impostazioni per i collaboratori (member). È possibile effettuare le operazioni più semplici via web, ma,
naturalmente,per effettuare modifiche massicce, il miglior amico di qualsiasi amministratore è un linguaggio di
scripting come Python. Se si ha un gran numero di utenti si troverà la sezione Manipolazione degli utenti con
degli script, più avanti in questo capitolo, particolarmente interessante.

9.1.1 Utenti, ruoli e gruppi


Utenti, ruoli e gruppi sono concetti fondamentali in Plone. Prima di trattare come modificarli vediamo nei dettagli
in cosa consistono.

247
248 INDICE

Utenti

Chiunque stia visitando un sito Plone è riferito come utente. L’utente può essere o non essere formalmente
autenticato (registrato) e l’utente non autenticato è detto utente anonimo. Gli utenti autenticati sono quelli che si
sono loggati con un account esistente. Se non si ha un proprio account è solitamente possibile crearselo.
Gli utenti anonimi sono il livello più basso degli utenti perciò hanno abitualmente le maggiori restrizioni. Una
volta che un utente si è registrato ottiene il ruolo conferitogli dal proprio account. Un utente è identificato con un
breve identificatore (username), per esempio lallo. Per default l’installazione di Plone non crea altri utenti oltre
a quello aggiunto a Zope dall’installer per dare accesso come amministratore. Il nome di questo utente è quello
impostato nell’installer, usualmente è admin.

Ruoli

Un sito Plone ha una serie di ruoli; un ruolo è la categorizzazione logica degli utenti. Piuttosto che impostare i
permessi individualmente per ciascun utente i permessi vengono assegnati ad ogni ruolo. Ad ogni utente possono
essere assegnati da nessuno a più ruoli: per esempio un utente può essere un collaboratore e un manager. Ciascun
ruolo è identificato con un nome semplice, per esempio: Collaboratore (Member).
Un sito Plone ha cinque ruoli predefiniti suddivisi in due gruppi: ruoli assegnabili e non assegnabili. I ruoli
assegnabili sono quelli che si possono dare ai propri utenti in modo che quando si loggano assumano quel ruolo.
I ruoli non assegnabili sono quelli che non vengono assegnati specificamente ma che vengono assunti dentro il
sito Plone. Per esempio non si attribuisce il ruolo di anonimo ad un utente.
Quelli che seguono sono i ruoli non assegnabili:

Anonimo: (Anonymous) Questo è un utente che non si è loggato nel sito. Può essere qualcuno che non ha un
account o che semplicemente non si è ancora registrato.
Autenticato: (Authenticated) Questo ruolo è riferito ad ogni utente che è loggato nel sito, indipendentemente
da qualsiasi altro ruolo gli sia stato assegnato. Per definizione un utente può essere anonimo o autenticato;
questi due ruoli sono mutualmente esclusivi. Siccome il ruolo di utente autenticato non è particolarmente
efficente in granularità, non è raccomandato per applicazioni principali.

Quelli che seguono sono i ruoli assegnabili:

Possessore: (Owner) È un ruolo speciale che viene assegnato all’utente quando crea un oggetto. Viene appli-
cato all’utente solo per quell’oggetto, le informazioni vengono memorizzate nell’oggetto. Normalmente
non si assegna esplicitamente il ruolo di possessore a qualcuno. Plone lo fa automaticamente.
Collaboratore: (Member) È il ruolo di default per un utente che si è loggato in un sito. Chiunque entri nel sito
usando il pulsante registrati (join) dell’interfaccia Plone assume questo ruolo.
Revisore: (Reviewer) Questo è un utente con più permessi rispetto ad un collaboratore ma meno di quelli di
un manager. I revisori sono utenti che possono modificare o revisionare contenuti inseriti da collaboratori;
non può però modificare la configurazione del sito o alterare gli account degli utenti.
Manager Un manager può fare quasi tutto ad un sito Plone e quindi questo ruolo deve essere assegnato solo a
sviluppatori ed amministratori sicuri. Un manager può cancellare o modificare contenuti, eliminare utenti,
alterare la configurazione del sito o anche eliminare completamente il sito.
9.1. AMMINISTRARE GLI UTENTI 249

Gruppi

I gruppi sono concettualmente diversi dai ruoli. I ruoli implicano che l’utente ha differenti permessi rispetto a
chi ha un ruolo differente mentre un gruppo è una categorizzazione logica degli utenti. Per esempio il settore
marketing potrebbe essere un gruppo e lo studio tecnico un altro gruppo. Ciascun utente può appartenere a zero
o più gruppi. I gruppi sono opzionali, non è necessario usarli ma il Plone Team li ha considerati sufficentemente
utili da integrarli.
Gli sviluppatori di siti possono utilizzare i gruppi secondo le loro necessità vuoi per un settore piuttosto che per
una certa classe di utenti. Per quelli che per la prima volta usano Plone raccomandiamo di lasciare inalterati i
gruppi, per default non vengono creati gruppi.

Nota
Per implementare i gruppi si usa GRUF (Group User Folder ). I gruppi non fanno parte di
Zope ma sono uno strumento extra aggiunto per Plone. GRUF è stato sviluppato e aggiunto
da Ingeniweb.

9.1.2 Scheda per la condivisione


Trattando il processo di pubblicazione dei documenti, nel ‘Capitolo 3‘_ abbiamo saltato la scheda per la condi-
visione perché è una funzionalità avanzata che non sempre si vuole usare. La scheda per la condivisione è una
azione delle portal actions, quindi, se si desidera che non appaia, recarsi in quello strumento tramite la ZMI
(Zope Management Interface) e disabilitare l’opzione visible. Però la scheda per la condivisione è decisamente
utile perché consente di assegnare differenti ruoli locali a utenti e gruppi su un oggetto di Plone.
Se si ha un contenuto che è stato aggiunto ad un sito Plone e si vuole che un’altra persona lo possa modificare è
necessario dare a questa più permessi su quell’oggetto. Ciò è detto dare un ruolo locale e consiste nell’espandere
i diritti di un utente su un elemento. Se si scrive un (nuovo) documento in Plone se ne diventa il possessore e
si hanno i relativi diritti. Se vogliamo collaborare su questo documento con un collega, prima di pubblicarlo,
dobbiamo dare al collega più permessi affinché egli possa modificare quel documento. Per far questo ci si reca
nella scheda per la condivisione e si danno gli ulteriori permessi al collega.

Nota
È possibile assegnare ruoli locali ad una cartella o ad un documento base. Se si assegnano
ruoli locali ad una cartella tale regola viene assegnata ad ogni oggetto in quella cartella.

La scheda per la condivisione appare solamente nei posti dove si ha il diritto di modificarla; uno di questi posti è
la propria cartella personale. Cliccare su cartella personale e poi su condivisione. La Figura 9-1 mostra la scheda
per la condivisione. Essa ha tre funzioni principali: si può assegnare ad un utente un ruolo locale sull’oggetto,
assegnare ad un intero gruppo un ruolo locale sull’oggetto e vedere chi ha già determinati ruoli.

Per trovare un utente a cui assegnare un ruolo introdurre un termine per la ricerca (per esempio Guido) che
produrrà un elenco con gli utenti che corrispondono al criterio immesso. Si potrà quindi cliccare sull’utente e
scegliere un ruolo dall’elenco a cascata. Per esempio, nella Figura 9-2 diamo a specchio il ruolo di manager su
questa cartella.

Nell’esempio precedente abbiamo assegnato un ruolo ad un singolo utente ma questo sistema potrebbe risultare
noioso se fatto per numerosi utenti ... a meno che non li assegnamo a dei gruppi. Se vogliamo che tutto il settore
marketing possa modificare il nostro documento possiamo farlo in questo modo. Per accedere ai gruppi cliccare
su Visualizza gruppi che apre l’elenco dei gruppi disponibili nel sito e consente di assegnare un ruolo locale ad
un gruppo. Nella Figura 9-3 stiamo assegnando il ruolo di possessore al gruppo Intranet su questa cartella.
250 INDICE

Figura 9.1: Figura 9-1. Accedere alla scheda condivisione


9.1. AMMINISTRARE GLI UTENTI 251

Figura 9.2: Figura 9-2. Assegnare un ruolo a un utente


252 INDICE

Figura 9.3: Figura 9-3. Assegnare un ruolo a un gruppo

Per finire, nella Figura 9-4, possiamo vedere quali utenti e gruppi abbiano dei ruoli in questa pagina ed even-
tualmente rimuoverli. Una volta che si è assegnato un ruolo locale su un oggetto a qualcun altro, gli viene
automaticamente concesso l’accesso alla scheda di condivisione. A quel punto nulla impedirà loro di poter
rimuovere i nostri propri ruoli da quel contenuto.

9.1.3 Amministrazione attraverso il web


Con l’interfaccia Plone è facile modificare l’assegnazione dell’utente a determinati gruppi, le sue informazioni,
aggiungere gruppi e così via. Ciò è possibile tramite il pannello di controllo di Plone semplicemente cliccando
su Configurazione di Plone e poi Amministrazione di Utenti e Gruppi. Verranno mostrate due schede: Utenti e
Gruppi.
Cliccare sulla scheda Utenti per accedere all’elenco degli utenti del sistema. La maschera è sufficentemente
autoesplicativa: è possibile rimuovere un utente, eliminare la password (in questo caso viene inviata all’utente
via mail comunque) oppure cambiare l’indirizzo e-mail tutto dalla medesima maschera, come viene mostrato in
Figura 9-5..

Cliccando su un utente si può accedere alle preferenze per quell’utente, fare delle modifiche e poi salvare. Per
aggiungere un nuovo utente cliccare su Aggiungi un nuovo utente. Questo apre la scheda di registrazione dell’u-
tente di cui è possibile modificare i dati. Considerato il grande numero di utenti che può avere un sito Plone i
dati sono raggruppati nella abituale maniera plonesca. Si può immettere una stringa che verrà ricercata tra tutti i
gli utenti per rintracciare quelli in cui corrispondano il nome o l’indirizzo.
È possibile aggiungere, modificare e rimuovere gruppi cliccando sulla scheda Gruppi. Per aggiungere un gruppo
cliccare sul pulsante Aggiungi un nuovo gruppo. Questo apre una scheda per il gruppo: l’unico campo richiesto
obbligatoriamente è il Titolo, che dovrebbe essere un nome breve ma descrittivo per il gruppo; abitualmente un
gruppo è direttamente correlato ad una attività aziendale o del sito.
9.1. AMMINISTRARE GLI UTENTI 253

Figura 9.4: Figura 9-4. Esaminare e rimuovere i ruoli

Quando si è inserito un gruppo e si hanno alcuni utenti si possono mappare utenti e gruppi. Ancora una volta è
possibile farlo tramite il pannello di controllo di Plone. È possibile sia cliccare sull’utente e dargli dei gruppi che
cliccare su un gruppo e mettervi degli utenti.

Quando vanno usati i gruppi?

L’uso dei gruppi è opzionale ed è possibile anche scegliere di non usarli. Un buon uso dei gruppi, comunque,
è per realizzare delle aree di lavoro (workspace). In un sito Plone standard gli utenti possono aggiungere e
modificare i contenuti della propria cartella; ogni elemento della cartella appartiene quindi a chi lo ha creato.
Purtroppo questo sistema non è ben scalabile; dopo tutto il punto è che si vorrebbe che alcune persone possano
modificare un documento e condividerlo, naturalmente!
Qui è dove intervengono i Gruppi e le aree di lavoro. Come esiste la cartella per i collaboratori (Members n.d.t)
che contiene tutte le cartelle degli utenti altrettanto esiste una cartella denominata GroupWorkspaces. Viene
creata per default allorquando viene aggiunto un gruppo ed in questa cartella vi è una cartella per ciascun gruppo.
Così se si aggiunge un gruppo denominato Marketing, si potrà trovare una cartella in GroupWorkspaces/Marketing.
Qualsiasi utente del gruppo Marketing avrà il diritto di aggiungere, modificare e cancellare contenuti nell’area di
lavoro Marketing; in altre parole ora abbiamo una cartella per quel gruppo. Questo è equivalente ad aggiungere
un gruppo e poi assegnare un ruolo locale per quel gruppo su quella cartella.
Questo è solo un esempio di quanto può essere utile un gruppo; un altro è l’uso dei gruppi nel controllo di flusso.
Nel capitolo precedente abbiamo trattato i workflow e com’è possibile inviare una mail a certe persone quando
accade qualcosa. Se un membro del gruppo Marketing ha aggiunto un elemento, per esempio, si può inviare una
mail a tutti gli appartenenti a quel gruppo piuttosto che singolarmente a ciascuno. La sezione Determinare gli
altri utenti in un certo gruppo descrive come farlo.
Nel sito web di Plone, per esempio, gli utenti sono in gruppi di sviluppo ciascuno responsabile di una parte di
Plone, come il team che gestisce i rilasci del software e quello dedicato alla documentazione.
254 INDICE

Figura 9.5: Figura 9-5. Modifica degli utenti


9.2. STRUMENTI PER LA REGISTRAZIONE DEGLI UTENTI 255

Amministrazione dei gruppi

Ci sono due modi per amministrare i gruppi dal pannello di controllo di Plone. Si può sia selezionare un utente
e cliccare sui gruppi per quell’utente che andare in un gruppo e cliccare sugli utenti per quel gruppo. Nello
stesso modo è possibile aggiungere ed eliminare gruppi per un utente. Per aggiungere un utente ad un gruppo,
comunque, recarsi nella pagina di ricerca utenti e cliccare un utente, poi cliccare la scheda associato ai gruppi
che mostrerà i gruppi di quell’utente. Per esempio la Figura 9-6 mostra i gruppi per l’utente azazel.

Per aggiungere l’utente ad un gruppo, spuntare il box del gruppo e poi cliccare su aggiungi l’utente ai gruppi
selezionati.
Allo stesso modo è possibile rimuovere un utente da un gruppo selezionando il box accanto al gruppo e poi
cliccando su rimuovi i gruppi selezionati. Si accede ad una interfaccia simile, ma per la gestione dei gruppi,
cliccando su configurazione di plone, selezionando Amministrazione utenti e gruppi e cliccando gruppi. Cliccare
un gruppo e si otterrà un’elenco degli utenti appartenenti al gruppo e da lì si potrà aggiungere o rimuovere i
membri.

Assegnare dei ruoli ai gruppi

Quindi abbiamo visto che gli utenti possono avere dei ruoli ma anche che i gruppi possono avere ruoli. Può
sembrare un po’ eccessivo ma si pensi, per esempio, ad un gruppo di supervisori che abbiano la necessità di
fare qualsiasi cosa sul contenuto aggiunto da uno dei loro collaboratori. Per far questo in un sito devono avere
il ruolo di revisore. Per impostare un gruppo di supervisori cliccare su Configurazione di Plone, selezionare
Amministrazione utenti e gruppi, cliccare gruppi e poi aggiungi un gruppo. Dare al gruppo il nome di Supervi-
sore e completare la scheda. Nella scheda successiva c’è un elenco dei gruppi e dei ruoli ad essi assegnati. Per
assegnare il ruolo di revisore a questo gruppo spuntare il box in corrispondenza del ruolo di revisore per quel
gruppo come mostrato nella Figura 9-7.

È stato semplificato il modo di assegnare il ruolo di revisore agli utenti ed ora è possibile amministrare i revisori
tramite l’interfaccia Plone. Inoltre è facile conoscere programmaticamente i revisori potendo esaminare il gruppo
ed ottenere l’elenco dei suoi membri.
L’idea dei gruppi con dei ruoli è in verità un leggero scostamento di paradigma rispetto allo sviluppo standard di
Zope dove si è abituati al fatto che i ruoli vengono assegnati ai singoli utenti. È possibile fare ancora così anche
in Plone ovviamente, ma in Plone è facile assegnare i ruoli ad un gruppo.

Nota
Per definizione, quando vengono controllati i permessi di un utente su un oggetto sono presi
in considerazione alcuni fattori. Prima sono controllati i ruoli assegnati all’utente. Seconda-
riamente vengono controllati i ruoli che l’utente ottiene dai gruppi a cui appartiene. Questo
da il gruppo di permessi complessivo che l’utente può utilizzare.

9.2 Strumenti per la registrazione degli utenti


Prima che gli utenti diventino membri di un sito devono iscriversi nel sito. Gli utenti possono agevolmente iscri-
versi cliccando sul collegamento iscriviti nell’angolo in alto a destra del sito Plone (standard n.d.r.). L’abbiamo
trattato nei dettagli all’inizio del ‘Capitolo 3‘_ dove abbiamo visto come gli utenti possono entrare e registrarsi
ad un sito. Il processo di registrazione degli utenti è già molto avanzato ma sono disponibili ulteriori opzioni.
Questo processo è gestito da tre strumenti chiave: portal_registration, portal_memberdata e portal_membership.
Le sezioni che seguono presentano questi tre strumenti.
256 INDICE

Figura 9.6: Figura 9-6. I gruppi di questo utente


9.2. STRUMENTI PER LA REGISTRAZIONE DEGLI UTENTI 257

Figura 9.7: Figura 9-7. Impostare il ruolo di revisore per il gruppo Supervisor
258 INDICE

9.2.1 Iscrizione nel portale


Lo strumento portal_registration fornisce azioni e in particolare una azione chiave di Plone: l’iscrizione. Clic-
cando su questo collegamento si accede alla scheda di iscrizione. Per default qualsiasi utente (anonimo incluso)
che non si sia ancora loggato può cliccare questo collegamento per registrarsi.
Quando gli utenti usano il modulo di iscrizione hanno due opzioni in Plone: validare l’indirizzo e-mail o non va-
lidarlo. L’unica maniera sicura per validare un indirizzo e-mail è quella di inviare un messaggio a quell’indirizzo
e controllare se si ottiene una risposta adeguata. Come opzione predefinite in Plone la validazione non è attiva;
cioé quando gli utenti si registrano, per default, forniscono a Plone il loro nome, l’indirizzo ed una password.
Possono quindi loggarsi ed usare normalmente il sito. È la stessa scheda che abbiamo visto nel ‘Capitolo 3‘_.
Se invece è attivata la validazione dell’indirizzo e-mail, gli utenti possono dare solo un nome, un username e un
indirizzo e-mail, come mostrato in Figura 9-8: la password verrà generata automaticamente dal sistema e spedita
all’utente usando l’indirizzo email specificato.

Dopo aver salvato l’indirizzo e-mail saremo riportati alla maschera di login ed il processo di registrazione potrà
continuare nel modo normale.
Per abilitare la validazione degli indirizzi nell’interfaccia Plone cliccare Configurazione di Plone e selezio-
nare Configurazione del Portale. In Politica della Password selezionare Genera la password iniziale dei
collaboratori e cliccare Salva per confermare le modifiche.
Se si desidera vedere o modificare il messaggio e-mail che ricevono gli utenti è possibile modificare il page
template che lo genera. Lo si trova cliccando su plone_skins, poi su plone_templates ed ancora su registe-
red_notify_template.

Azioni per gli utenti


Se si desidera aggiungere qualche altra azione per gli utenti, prima della registrazione, que-
sto è il posto per farlo. Per esempio se si vuole aggiungere una pagina che evidenzi la
politica della privacy questo è un buon posto. Per farlo, prima si aggiunga la pagina con tutto
le informazioni che si vogliono in questa politica. Avrà senso dare alla pagina un ID utile.
per esempio privacy.html e metterlo nella root del sito Plone.
Nella ZMI andare in portal_registration ed aggiungere una nuova azione con le
seguenti informazioni:

Name: Privacy
Id: privacy
Action: string: ${portal_url}/privacy.html
Condition: not: member
Permission: Add portal member
Category: user
Visible: selected
Ora, se non si è loggati, si ottiene il collegamento privacy alla propria pagina sulla privacy.
L’impostazione della categoria ad user assicura che esso appaia nella barra personale.

9.2.2 Dati dei Collaboratori del Portale


Lo strumento portal_memberdata contiene i dati del collaboratore per ogni utente. L’utente Plone ha una serie di
informazioni come stile, ultimo login, il tipo di editor preferito (WYSIWYG editor) e così via. Quando un utente
si registra in un sito viene creato un record con dati di default nel portal_memberdata. È possibile impostare le
proprietà di questo record in questo strumento: cliccare su portal_memberdata e selezionare la scheda Properties
per vedere i valori di default. In Plone sono i seguenti:
9.2. STRUMENTI PER LA REGISTRAZIONE DEGLI UTENTI 259

Figura 9.8: Figura 9-8. Iscrizione di un utente con la validazione della email abilitata
260 INDICE

e-mail Questo è l’indirizzo e-mail.

portal_skin Questa è deprecata; ignorare questa proprietà.


listed Mostra questo utente nella cartella Collaboratori (Boolean). Per default questa opzione è abilitata.
login_time Questa è la data del login dell’utente per questa sessione.
last_login_time Questa è la data dell’ultimo login dell’utente.
fullname Questo contiene il nome completo dell’utente.
error_log_update È usato dalla maschera dei log degli errori, ignorare questa proprietà.
formtooltips Nelle vecchie versioni di Plone c’erano delle opzioni su come devevano essere visualizzati gli
aiuti. Ciò non è più rilevante e quindi si ignori questa opzione.

visible_ids Questo mostra gli ID degli oggetti. Abilitandolo il primo campo della scheda di ogni contenuto è
Nome che può essere cambiato per rinominare gli oggetti. Per default questa opzione è abilitata.
wysiwyg_editor Questo è l’editor da usare nelle maschere di modifica dei dati.

Tramite l’interfaccia di Zope è possibile aggiungere o togliere elementi da quest’elenco. Comunque, aggiungere
o togliere elementi da qui non cambia automaticamente l’aspetto dell’interfaccia che l’utente sta modificando.
Nel ‘Capitolo 3‘_ abbiamo visto che, cliccando su preferenze personali, gli utenti possono accedere e modificare
molte di queste preferenze. Se si vogliono modificare queste preferenze si deve personalizzare questa scheda. I
valori di questi campi sono quelli che vengono dati per default ad ogni nuovo utente quando si registra; per esem-
pio, l’impostazione predefinita è che tutti i Collaboratori siano elencati nella Tabella dei Collaboratori, a meno
che gli utenti non decidano altrimenti esplicitamente. Quindi, per esempio, se si desidera che per default nessun
Collaboratore sia elencato nella ricerca, è necessario cambiare l’impostazione in questa scheda. Nella scheda
portal_memberdata trovare listed tra le Properties e deselezionare quell’opzione. Poi cliccare Save Changes per
confermare: i nuovi utenti non saranno più elencati.
Lo strumento portal_groupdata contiene i medesimi dati ma per i gruppi. Le proprietà di default per i gruppi
sono:

title Il titolo per il gruppo


description Una descrizione per il gruppo
email Un indirizzo e-mail
listed Se elencare il gruppo agli utenti

Questi strumenti mantengono i dati negli strumenti stessi piuttosto che nella cartella acl_users principale.
Se si desidera trasportare le informazioni utente tra server Plone sarà necessario farlo anche per gli strumenti:
spostare la cartella acl_users non è sufficente. È possibile farlo importando ed esportando questi strumenti;
comunque, prima di importarli in un nuovo sito Plone è necessario eliminare gli strumenti esistenti altrimenti si
riceverà un errore.

9.2.3 Portal Membership


Lo strumento portal_membership gestisce alcune altre proprietà; specificamente mappa i dati del collaboratore
con i Collaboratori. L’accesso tramite la ZMI a portal_membership presenta molte opzioni. quelle che
seguono sono le più importanti:
9.2. STRUMENTI PER LA REGISTRAZIONE DEGLI UTENTI 261

Set members folder Questa è la cartella che contiene tutte le cartelle utente. Questa cartella deve esistere.
L’impostazione predefinita è Member.
Control creation of member areas Per default alla registrazione viene creata un’area utente. Questa crea-
zione è opzionale comunque. Deselezionare Turn folder creation off per disabilitarla. L’impostazione
predefinita è on.

Nella scheda Action si trovano tutta una serie di azioni che sono correlate all’utente che si registra, come my
favorites, my preferences e così via. Tutte queste hanno la categoria user cosicché appaiano tutte nell’angolo in
alto a destra.
Lo strumento portal_groups fornisce attrezzi simili a quelli in portal_membership ma per i gruppi. Ugualmen-
te, quando viene creato un gruppo, viene creato un’area del gruppo dove ciascun componente del gruppo può
aggiungere e modificare contenuti.

9.2.4 API utili


Lo strumento portal_membership ha uno dei più usati set di funzioni API. Spesso si vogliono trovare informazio-
ni chiave come gli utenti attualmente loggati, se l’utente è anonimo e così via. Lo strumento portal_membership
fornisce questi metodi; i seguenti sono i più importanti:

isAnonymousUser() Questo ritorna true se l’utente è anonimo.


getAuthenticatedMember() Questo ritorna gli utenti attualmente registrati completi delle proprietà in por-
tal_metadata. Se nessun utente è registrato ritorna uno speciale utente nobody con nessuna mappatura
per le proprietà di portal_metadata.
listMemberIds() Questo ritorna l’ID di tutti gli utenti.
listMembers() Questo ritorna tutti gli oggetti dell’utente.
getMemberById(id) Questo ritorna tutti gli oggetti utente per un dato ID.
getHomeFolder(id=None) Questo ritorna la cartella home per un dato ID . L’ID è opzionale e se non viene
dato ritorna la cartella dell’utente corrente.
getHomeUrl(id=None) Questo ritorna l’URL della cartella home dell’utente. L’ID è opzionale e se non viene
dato ritorna l’URL della cartella dell’utente corrente.

L’utente che viene ritornato da queste funzioni viene completato con i dati provenienti da portal_memberdata
in modo che le sue proprietà siano attribuite all’oggetto dell’utente. Quindi, per esempio, quello che segue è un
piccolo oggetto Script (Python) per trovare l’indirizzo e mail dell’utente andrea.

##parameters=
u = context.portal_membership.getMemberById("andrea")
return u.email

9.2.5 Autenticazione tramite Cookie


Per default Plone usa l’autenticazione tramite cookie per i suoi utenti, il che significa che gli utenti devono avere
i cookie attivati nei loro browser per potersi registrare. Questa autenticazione è fornita al sito Plone dall’oggetto
cookie_authentication che contiene la funzionalità per il login degli utenti. Se veramente si vuole utilizzare
l’Hypertext Transfer Protocol (HTTP) per l’autenticazione si può semplicemente rimuovere questo oggetto; ma
non viene sinceramente raccomandato in quanto l’autenticazione HTTP in moltissimi siti non funziona.
Questo oggetto fornisce i seguenti elementi che si possono modificare dalla ZMI:
262 INDICE

Authentication cookie name Questo è il nome del cookie che verrà usato per conservare l’autenticazione del-
l’utente. Questo vien fatto mantenendo una chiave per quell’utente, che conserva i dati per il login. Il
valore di default è __ac
User name form variable Questo è il nome della variabile che contiene l’username nella scheda di login. Il
valore di default è __ac_name.
User password form variable Questo è il nome della variabile che contiene la password nella scheda di login.
Il valore di default è __ac_password.
User name persistence form variable Questo è il nome della variabile che contiene la chiave di persistenza. Il
valore di default è __ac_persistent.
Login page ID Quando un utente desidera registrarsi, questa è la pagina che gli viene inviata per effettuare la
registrazione. Il valore di default è require_login.

Logout page ID Se un utente sta per fare il logout gli può essere inviata una pagina con un bel messaggio. Il
valore di default è logged_out.
Failed authorization page ID Quando fallisce l’autenticazione questa è la pagina che viene mostrata. Per
default questo valore è blank perché Plone usa un sistema diverso.
Use cookie paths to limit scope Questo imposta che il cookie sia locale alla cartella corrente e a tutte le cartelle
sotto questa. Lasciandolo a blank significa che indipendentemente dalla pagina dove ci si autentica lo si
fa per l’intero sito.

Per cambiare il cookie che dev’essere usato piuttosto che quello predefinito semplicemente cambiare il valore
in questa scheda e cliccare Save. Comunque si lasci mettere in guardia rispetto a questo, se si modifica il nome
del cookie, tutti i cookie esistenti nei computer degli utenti saranno ignorati e quindi questi dovranno registrarsi
nuovamente. Se si desidera una pagina differente per il login si può anche personalizzare il page template
require_login o modificare il valore di quella variabile.

9.2.6 L’effettiva cartella dell’utente


È possibile accedere alla affettiva cartella dell’utente di un sito Plone cliccando sulla cartella acl_users nella
ZMI. Questo apre l’interfaccia Group User Folder (GRUF) che consente di scegliere tra varie opzioni.
L’interfaccia di GRUF è veramente simile alle opzioni che si hanno tramite il pannello di controllo di Plone. È
possibile aggiungere e modificare gli utenti ed i gruppi tramite una interfaccia comoda ed avanzata. Cliccando
sugli utenti e sui gruppi è possibile modificare questi elementi. Cliccando sulla scheda Contents si può scegliere
tra utenti e gruppi; cliccare su Utenti e poi su acl_users*. Finalmente si arriva alla reale cartella di un utente.
Appare come la cartella utente standard. È possibile vedere l’elenco degli utenti e, per modificarne uno, basta
semplicemente cliccare sull’username come viene mostrato in Figura 9-9.

Da qui è possibile modificare la password ed i ruoli di un utente. A questo punto si sarà notato che il gruppo
Management è rappresentato come un ruolo in modo da non provocare collisioni nei nomi. Il nome è storpiato in
group_Management. Se si desidera che questo utente diventi un utente di questo gruppo si deve farlo qui. Non
c’è molto altro da fare qui che non si possa fare al livello più alto, quindi non si viene quaggiù se non quando si
devono cambiare la password o impostare un dominio.
9.2. STRUMENTI PER LA REGISTRAZIONE DEGLI UTENTI 263

Figura 9.9: Figura 9-9. Modifica dei dati dell’utente


264 INDICE

9.3 Impostare i permessi


Abbiamo trattato ora gli utenti, i ruoli ed i gruppi ma c’è ancora altro; il livello più basso delle impostazioni
relative alla sicurezza è un permesso. Come suggerisce il nome stesso, dare un permesso ad un utente significa
dargli la capacità di fare qualcosa, come vedere un oggetto, aggiungere un documento, ottenere l’elenco dei
contenuti di una cartella e così via. Ogni tipo di permesso è identificato univocamente con un nome significativo
come View, Add portal content, o List folder contents.
I permessi non vengono applicati al singolo utente ma ad un ruolo. Ogni ruolo possiede determinati permessi, e
l’utente assume quei ruoli particolari. Tramite la ZMI e la scheda Security è possibile trovare tutte le impostazioni
relative alla sicurezza di Zope, incluse quelle per il sito Plone, per la cartella root di Zope, per tutti gli oggetti
ed i contenuti oltre che per l’aspetto. Cliccando sulla scheda Security si vedono tutti i permessi ed i ruoli che li
mappano in una griglia come mostra la Figura 9-10.

Nella Figura 9-10 si può vedere la serie di impostazioni di sicurezza di questo oggetto. Vengono mostrate in una
griglia di campi di spunta: a sinistra vi sono i permessi in ordine alfabetico e quasi in cima ci sono i ruoli anch’essi
in ordine alfabetico. Questa pagina è decisamente lunga e ingombrante, così ci sono due scorciatoie. Cliccare su
Permission per ottenere tutti i ruoli per questo permesso; per esempio la Figura 9-11 mostra le impostazioni per
il permesso Access future portal content.

Cliccando su un ruolo si ottengono tutti i permessi per quel ruolo, che è molto più facile che nel lungo elenco,
come mostrato in Figura 9-12.

Per tutti questi permessi si tratta di cliccare sui box per i permessi che si desiderano oppure selezionare le opzioni
nel box di scelta e cliccare Save. Quando viene spuntato il box Acquire Permission le impostazioni di sicurezza
per questo oggetto sono ereditate (acquisite), se non è spuntato i permessi non sono acquisiti. L’acquisizione
è la capacità di un oggetto di cercare nella gerarchia degli oggetti per trovare i permessi (da ereditare n.d.t) e
combinarli nei permessi definitivi (complessivi).

Nota
Tramite la pagina dei permessi si possono cambiare anche le (proprie) impostazioni di si-
curezza dell’utente manager; bloccare l’utente manager potrebbe essere una pessima idea,
quindi è bene che ciò sia possibile per default.

Ora si vedano i permessi di Access contents information. Nella ZMI andare nella cartella radice e scegliere
la scheda Security. L’impostazione predefinita per questo permesso è che nessun ruolo vi è abilitato; cioè le
impostazioni per ciascun utente sono a vuote. Invece l’opzione Acquire Settings è attiva, il che significa che si
deve guardare negli oggetti contenitori nella gerarchia per determinare i permessi di questo oggetto. Si vada ora
nella cartella root di Zope e si clicchi sulla scheda Security. Si aprirà l’elenco dei permessi per la cartella root
e quasi certamente vi saranno delle opzioni per il permesso Access contents information per questa cartella; in
particolare, i ruoli anonymous e manager hanno questo permesso.
Quando i permessi vengono acquisiti, anche tutte le sottocartelle acquisiranno le medesime impostazioni dei per-
messi. Questo significa che il sito Plone ed ogni oggetto del sito Plone avranno questi permessi. Di conseguenza
se si intende impostare un permesso per l’intero sito è sufficente configurare il permesso nella root di Plone e
tutti gli oggetti acquisiranno quei permessi.

Nota
L’eccezione è rappresentata dagli oggetti che hanno un workflow che specificatamente disa-
bilitano l’acquisizione. Ciò è trattato nella sezione Sicurezza e Workflow, più avanti in questo
capitolo.
9.3. IMPOSTARE I PERMESSI 265

Figura 9.10: Figura 9-10. Impostazioni di sicurezza


266 INDICE

Figura 9.11: Figura 9-11. Le impostazioni di un permesso


9.3. IMPOSTARE I PERMESSI 267

Figura 9.12: Figura 9-12. Le impostazioni per il ruolo di Revisore


268 INDICE

È possibile impostare permessi su qualsiasi oggetto in Zope tramite la ZMI. Questo può essere la cartella radice
di Zope, un sito Plone, una cartella come la cartella Members o anche una parte di contenuto. Ogni oggetto ha il
proprio insieme di permessi ma non tutti gli oggetti hanno la stessa scelta di permessi. Per esempio il permesso
Add ... è disponibile in ogni cartella. Ma siccome questo permesso non avrebbe senso per oggetti non-contenitori
(per definizione un oggetto deve essere una cartella per poter avere degli oggetti aggiunti), non sono presenti.
Qualsiasi prodotto o parte di codice Python nel proprio sito Zope può definire la propria sicurezza, quindi può
essere un po’ difficile definire esattamente cosa lascia fare un permesso. La Tabella 9-1 descrive alcuni dei
permessi chiave e cosa fanno.

Tabella 9.1: Tabella 9-1. I permessi più comuni di Plone

Permesso Descrizione
Access contents informa- Questo permesso consente l’accesso ad un oggetto senza necessariamente
tion consentire di vedere l’oggetto. Per esempio un utente potrebbe voler vede-
re il titolo dell’oggetto in un elenco di risultati, anche se l’utente non può
vedere il contenuto di quel file.
Add. . . Ci sono numerosi permessi Add, ciascuno relativo ad un tipo di oggetto
che un utente può aggiungere. Per un normale sito Plone tutti i permessi
sono raggruppati insieme in Add portal content.
Add portal member Abilita la possibilità di registrarsi ed un sito Plone e di ottenere un account.
Copy or Move Questo permesso da il diritto di copiare o muovere un oggetto. Di conse-
guenza se gli utenti hanno questo permesso hanno pure bisogno di avere il
permesso per incollare l’oggetto a destinazione.
Delete objects Questo permesso da il diritto di cancellare un oggetto. In un ambiente Zope
standard, questo permesso è impostato sulla cartella, in Plone il controllo
è su ogni oggetto.
List folder contents Questo permesso da un’elenco dei contenuti di una cartella; non controlla
se si hanno i permessi per vedere gli oggetti elencati.
List portal members Questo permesso da il diritto di elencare i Collaboratori (members) del sito
e di ricercare tra essi.
Modify portal content Questo è il permesso prendi-tutto, consente qualsiasi modifica ad un og-
getto come cambiarne il contenuto, le sue parole chiave o altre proprietà.
Questo permesso è applicato a quasi tutti gli oggetti.
Set own password Questo permesso da il diritto di modificare la propria password in un sito
Plone.
Set own properties Questo permesso da il diritto di cambiare le proprie proprietà in un sito
Plone.
View Questo permesso consente all’utente di vedere l’oggetto in questione. View
non significa solo poter visualizzare l’HTML ma anche accedere via File
Transfer Protocol (FTP), WebDAV, ed altre forme di accesso.

9.3.1 Aggiungere un ruolo


Assegnare ruoli agli utenti significa trovare una serie compatibile di permessi per ogni ruolo in modo che questo
raggruppamento di permessi abbia un senso. Questo non è sempre possibile. Un determinato utente può aver
bisogno talvolta di qualcosa di differente da utenti simili.
Comunque, dal punto di vista dello sviluppatore, meno numerosi e più semplici sono mantenuti i ruoli tutto
risulta più facile. Non è troppo complicato, ma iniziare urgentemente creando un ruolo per ogni opzione di
9.3. IMPOSTARE I PERMESSI 269

sicurezza concepibile può essere una pessima idea. Si andrebbe velocemente in gran confusione. Si raccomanda
quindi di mantenere limitato il numero di ruoli e che siano generici per l’intero sito.
Per aggiungere un ruolo, andare nella cartella Plone, cliccare sulla scheda Security e scorrere fino in fondo (è
assai lunga). In fondo c’è un semplice modulo per aggiungere o rimuovere altri ruoli. Aggiungere il nome del
nuovo ruolo e cliccare su Add Role.

9.3.2 Operazioni tipiche


È possibile impostare alcune opzioni di sicurezza in modo da far eseguire regolarmente dei compiti. Prima di
effettuare profonde modifiche alle impostazioni di sicurezza, comunque, si raccomanda di eseguire un back-up
del sito Plone. Questo è trattato nel Capitolo 13.

Bloccare l’iscrizione al sito

Per impedire l’iscrizione al sito da parte di nuovi utenti si deve impostare il permesso Add portal member per
gli utenti anonimi nella cartella root di Zope. Si potrà sia deselezionare qui questa impostazione per l’utente
anonimo come andare al sito Plone e togliere l’impostazione Acquire Permission.

Bloccare la possibilità di fare ricerche

Per impedire le ricerche nel sito da parte degli utenti si imposta, nella cartella root del sito Plone, il permes-
so Search ZCatalog per gli utenti anonimi. Quindi modificare quel permesso deselezionando Anonymous o
qualsiasi altro utente.

Bloccare l’accesso al sito da parte degli utenti anonimi

Ah, bene, per fermare l’accesso al proprio sito da parte dell’utente anonimo serve un piccolo trucco in quanto
sarebbe abbastanza complicato rimuovere completamente l’accesso anonimo: gli utenti devono pur essere in
grado di accedere al login! Ciò che realmente si vuole in questa situazione è di essere in grado di restringere
l’accesso ai contenuti. Ciò è possibile restringendo i permessi del proprio controllo di flusso (workflow).

9.3.3 Sicurezza e workflow


Come abbiamo sviscerato nel Capitolo 7, il controllo di flusso gestisce la sicurezza di ogni oggetto del workflow.
Fa questo modificando i reali permessi di quell’oggetto. Abbiamo appena visto come si possono vedere le
impostazioni di sicurezza di ciascun oggetto; si potrànno quindi controllare come le impostazioni di sicurezza
degli oggetto in un determinato stato possano essere differenti dalle impostazioni di sicurezza di un oggetto in un
altro stato. Se si clicca su portal_workflow, si seleziona la scheda Contents, si clicca su plone_workflow e quindi
ancora sulla scheda States si vedranno gli stati disponibili. Cliccare su uno stato e quindi scegliere la scheda
Permission si vedranno i permessi per quel determinato stato, come mostrato in Figura 9-13.

Come si può vedere, quando un oggetto è stato messo nello stato pubblicato, l’utente anonimo ha il permesso
Access contents information e View. Ciò significa che gli utenti possono vederne il contenuto. Si noti come
collaboratori o possessori non possono modificare i loro contenuti poiché non hanno quel permesso. I permessi
applicati dal controllo di flusso sono applicati nella tabella Permission dov’è possibile impostare tutti i permessi
che sono gestiti dal controllo di flusso.
Dopo aver modificato le impostazioni di sicurezza è necessario andare nello strumento plone_workflow e cliccare
su Update security settings altrimenti la sicurezza degli oggetti ed il controllo di flusso rimarranno differenti.
270 INDICE

Figura 9.13: Figura 9-13. I permessi dello stato pubblicato


9.3. IMPOSTARE I PERMESSI 271

Nota
Siccome i permessi cambiano quando vi è una transizione sull’oggetto, qualsiasi altra mo-
difica ai permessi di un oggetto fatta tramite la ZMI viene rimossa se (e non solo se) tali
permessi sono gestiti dal controllo di flusso. Per questa ragione si deve trattenersi dalla
fretta di fare piccoli interventi sulla sicurezza dei tipi di contenuto della ZMI, frenarsi dal
modificare l’oggetto sito Plone ed il suo controllo di flusso.

Sentinelle

Tutte le transizioni hanno una loro sentinella che consente all’amministratore di selezionare i permessi autorizzati
prima che l’utente completi la transizione. Quando si verifica se un utente può fare una transizione il controllo
avviene in questo ordine: controllo dei permessi, controllo dei ruoli e quindi controll dell’espressione. Se passa
ogni controllo la transizione può avvenire.
Quelle che seguono sono tutte le impostazioni di una sentinella:

Permission È l’elenco dei permessi concessi, separati da punto e virgola - per esempio, Review portal content;
Modify portal content.
Roles È l’elenco dei ruoli che sono accettabili da questa transizione, separati da punto e virgola - per esempio,
Manager; Reviewer).
Expression Questa è una espressione di controllo di flusso scritta con il linguaggio Template Attribute Language
Expression Syntax (TALES) che può applicare una condizione personalizzata. Per esempio, la seguente
transizione, avverrà solo se è in una cartella di nome Members; non è un permesso reale, ma è nettamente
un trucco:

python: if ’Members’ in state_object.getPhysicalPath()

Nota
getPhysicalPath è un metodo di tutti gli oggetti di Zope che ritorna la posizione nella
gerarchia degli oggetti di Zope ignorando qualsiasi posizione virtuale (virtual hosting n.d.t.).

9.3.4 Ruoli proxy


Nel precedente capitolo abbiamo discusso alcuni metodi validi per la notifica agli utenti e per spostare del con-
tenuto quando questo è sottoposto a controllo di flusso. Quando ciò accade, lo script è eseguito appena l’utente
lancia la transazione controllata. In questo caso il nostro script potrebbe fare qualcosa che l’utente può o non
può avere il permesso di fare. Per esempio si potrebbe non volere che un utente possa aggiungere qualcosa alla
cartella di nome public tranne che tramite il controllo di flusso. Questo è il problema: vogliamo che lo script sia
eseguito con un ruolo più alto.
Un ruolo proxy è qualcosa con cui il nostro utente non interagisce e non è tenuto a conoscere ma c’è un metodo
per aggirare questo problema. Per esempio, diciamo che vorremmo che l’utente fosse in grado di scegliere un
qualsiasi altro utente del sito. Non vogliamo che possa vedere l’elenco di tutti gli utenti ma semplicemente
l’elenco di utenti in questo particolare contesto. Per eseguire lo script l’utente deve avere il permesso List portal
members per ottenere appunto l’elenco dei collaboratori, e però non vogliamo darlo all’utente anonimo.
Allo script che esegue quel comando dovrà essere dato un ruolo proxy più alto, probabilmente Member. Per far
questo andiamo allo script tramite la ZMI, clicchiamo sulla scheda Proxy e clicchiamo Member. Se questo script
si basa sul file system, allora queste informazioni possono essere aggiunte al file dei metadati. Per esempio, il file
.metadata avrebbe le seguente riga: proxy = Member. Ora questo script sarà eseguito come member, risolvendo
i nostri problemi di sicurezza!
272 INDICE

9.4 Manipolazione degli utenti con degli script


Ora abbiamo un intero gruppo di utenti nel nostro sito Plone ed abbiamo bisogno di alcuni script di aiuto per
l’amministrazione degli utenti di quel sito. Oltre qualche centinaia di utenti diventa veramente difficile effettuare
modifiche via web; le prossime sezioni danno alcuni esempi di script per svolgere alcuni importanti lavori.

9.4.1 Registrazione in massa di utenti


Se si deve registrare un gran numero di utenti si ha bisogno di uno script per importarli. Questi utenti possono
venire importati in Plone da qualsiasi sistema. Ma comunque, se questi utenti sono già in una risorsa esterna
come possono essere LDAP, un database relazionale o altre fonti, è possibile integrarli direttamente con quella
fonte.
Per ora prendiamo un file con un gruppo di utenti separati da virgole, con i seguenti contenuti: username, nome
completo, indirizzo e-mail e gruppi. Nell’esempio che segue, andremo in questo elenco, aggiungeremo cia-
scun utente con quelle impostazioni e poi modificheremo le loro proprietà in modo che abbiano le impostazioni
corrette. Il file .csv conterrà quindi qualcosa simile a:

"User Name", "Full Name", "Email", "Groups"


"Andy", "Andy Mckay", "andy@enfoldsystems.com", "Systems,Sales,Development"
...

Un file .csv è un file dove i valori sono separati da virgole, che può essere creato e modificato con qualsiasi
programma di fogli di calcolo, come Microsoft Excel o OpenOffice. È possibile quindi esportare il file con quel
formato (valori separati da virgole) e finalmente importarlo dentro Plone. Siccome questo comporta l’uso di
svariati metodi che sono protetti (restricted) è necessario farlo con un metodo esterno:

# An external method to import user


import csv

# the full path to your csv file


fileName = "/var/zope.zeo/Extensions/test.csv"

def importUsers(self):
reader = csv.reader(open(fileName, "r"))
pr = self.portal_registration
pg = self.portal_groups
out = []

# if your csv file contains a header line that


# explains the contents of each column
ignoreLine = 1

Questo è solo il codice di setup; in altre parole esso imposta tutte le variabile che useremo nello script. All’inizio
importiamo il modulo csv che è un modulo compreso nel Python 2,3 e consente un veloce parsing dei file .csv.
Il file .csv è nella variabile fileName, che contiene il path completo del file; se si inserisce un path relativo Plone
potrebbe andare a finire a guardare nel posto sbagliato. Come detto in precedenza viene passato al metodo
il parametro self e da questo sarà possibile ottenere i due strumenti necessari: portal_registration per fornire
l’accesso alle API di registrazione e portal_groups per fornire l’accesso alla API dei gruppi.

for row in reader:


if ignoreLine:
9.4. MANIPOLAZIONE DEGLI UTENTI CON DEGLI SCRIPT 273

ignoreLine = 0
continue

# check we have exactly 4 items


assert len(row) == 4
id, name, email, groups = row
groups = groups.split(’,’)

# make a password
password = pr.generatePassword()

poi cicliamo su ogni riga ed otteniamo l’ ID, il nome, l’indirizzo e-mail ed i gruppi. Poi generiamo una password
casuale invocando generatePassword. Questo genera una password casuale formata da sei caratteri maiuscoli,
minuscoli e numeri. Se si vogliono basare gli ID o la password sulle informazioni in arrivo nello stesso modo
dell’username o dell’indirizzo e-mail, qui si può farlo. In questo caso, abbiamo messo tutti i gruppi nello stesso
campo separati da virgole (per esempio “Sales,Marketing”). Quindi è necessario separarli in un elenco di nomi
unici del tipo:

try:
# add in member
pr.addMember(id = id,
password = password,
roles = ["Member",],
properties = {
’fullname’: name,
’username’: id,
’email’: email,
}
)
# groups are separated by commas
for groupId in groups:
group = pg.getGroupById(groupId)
group.addMember(id)

out.append("Added user %s" % id)

except ValueError, msg:


# if we skipped this user for a reason, tell the person
out.append("Skipped %s, reason: %s" % (id, msg))

# return something
return "\n".join(out)

Fatto questo abbiamo tutte le informazioni necessarie per poter registrare i nostri utenti, possiamo fare la effettiva
registrazione. La eseguiamo invocando la funzione addMember che è una funzione di portal_registration e che
registra gli utenti. Viene passato alla funzione un dizionario delle coppie chiave/valore come sono indirizzo e
username. Quindi, per ogni gruppo, viene chiamata getGroupById per ottenere il gruppo e poi viene invocata
addMember sul gruppo. Come suggerito dal nome questa registra l’utente in quel gruppo. Fatto questo rimane
il problema di stampare qualcosa per la persona per cui si è effettuata l’importazione.
Per farlo per il proprio sito, è necessario metterlo nella cartella Extension nel server Plone e denominarlo
import_users_with_groups.py. Poi si devono aggiungere manualmente i gruppi che si vogliono nel proprio
sito, questo script infatti non crea i gruppi per noi. Preparare il file .csv; se i propri utenti sono memorizzati
274 INDICE

in qualche sistema sarà necessario trovare la strada per esportarli in questo formato. Modifichiamo il nome del
file nello script in modo che punti al nostro file. Poi aggiungiamo un metodo esterno al nostro sito Plone con i
seguenti valori:

ID : import_users_with_groups
Module name: import_users_with_groups
Function name: importUsers

Una volta aggiunto questo metodo esterno lo si prova con il pulsante Test e si ottiene il risultato voluto!

9.4.2 Modifica delle impostazioni degli utenti


Se si installa un nuovo prodotto o si fa una nuova impostazione può essere necessario modificare in blocco i
metadati dell’utente. Per esempio, installando un nuovo editor WYSIWYG e volendo che questo sia il nuovo
default per ogni utente sono necessarie due cose:

• Cambiare le impostazioni di default per ogni nuovo utente. Per questo cliccare su portal_metadata
e selezionare la scheda Properties. Impostare qui il default e tutti i nuovi utenti otterranno quel
valore.
• Cambiare le impostazioni per ciascun utente esistente; può essere fatto solo con un metodo
esterno come il successivo:

def fixUsers(self):
pm = self.portal_membership
members = pm.listMemberIds()

out = []
for member in members:
# now get the actual member
m = pm.getMemberById(member)
# get the editor property for that member
p = m.getProperty(’wysiwyg_editor’, None)

out.append("%s %s" % (p, member))


if p is not None and p != ’Epoz’:
m.setMemberProperties({’wysiwyg_editor’: ’Epoz’,})
out.append("Changed property for %s" % member)
return "\n".join(out)

Mettiamo questo codice in un modulo Python nella cartella Extension della nostra istanza Plone. Denominiamo
il modulo fixUserScript.py. Poi, dalla ZMI aggiungiamo un metodo esterno con i seguenti parametri:

ID : fixUsers
Module name: fixUserScript
Function name: fixUsers

Usiamo la scheda Test per provare il codice. Lo script girerà su ciascun collaboratore del sito ed imposterà il
valore per l’editor WYSIWYG a “Epoz”. Lo fa ottenendo innanzitutto l’elenco di tutti i Collaboratori; c’è un me-
todo in portal_membership denominato listMemberIds che lo fa per noi. Per ciascuno dei Collaboratori, esamina
la proprietà usata da Plone per determinare l’editor preferito (in questo caso la proprietà wysiwyg_editor). Se
questa proprietà non ha il valore “Epoz” allora invocherà setMemberProperties per cambiarla.
Questo è un buon sistema per girare su tutti i Collaboratori. Quindi, usando i metodi setMemberProperties e
getProperty, è possibile esaminare o cambiare le proprietà di Collaboratore possedute da ciascun utente.
9.4. MANIPOLAZIONE DEGLI UTENTI CON DEGLI SCRIPT 275

9.4.3 Determinare gli altri utenti in un certo gruppo


Abbiamo accennato in precedenza della possibilità di inviare messaggi e-mail a tutti i componenti del gruppo di
lavoro di un oggetto. È possibile aggiungerlo al controllo di flusso ma prima è necessario creare uno script per
far questo. Nell’esempio che segue usiamo una coppia di funzioni per applicarlo agli utenti. Quello seguente è
lo script getGroupUsers che prende un oggetto e ritorna un elenco di utenti:

##parameters=object=None
# object is the object to find all the members of the same group for
users = []
# get the creator
userName = object.Creator()
user = context.portal_membership.getMemberById(userName)
pg = context.portal_groups

# loop through the groups the user is in


for group in user.getGroups():
group = pg.getGroupById(group)

# loop through the users in each of those groups


for user in group.getGroupUsers():
if user not in users and user != userName:
users.append(user)

return users

In questo script stiamo dando un oggetto e dobbiamo trovare il suo creatore chiamando il metodo Creator. Una
volta ottenuto questo utente, si può chiamare getGroups, un metodo dell’oggetto dell’utente, che elenca tutti i
nomi di tutti i gruppi a cui appartiene quell’utente. Dopo, prendiamo ciascuno di quei gruppi e da quell’elenco
troviamo gli username di un gruppo. Quindi, finalmente, abbiamo tutti gli username. Ora per ciascuno di questi
utenti non vogliamo duplicati e vogliamo che non coincidano con la persona che ha fatto la modifica all’oggetto.
L’elenco utenti così ottenuto, conterrà tutti gli altri utenti che sono negli stessi gruppi di chi possiede l’oggetto.
Sarà possibile quindi innestarlo nello script di notifica via e-mail del controllo di flusso tratto dal Capitolo 7. Per
esempio per lo script di notifica via e-mail del controllo di flusso è possibile richiamare quanto fatto nel seguente
modo:

for user in mship.listMembers():


if "Reviewer" in mship.getMemberById(user.id).getRoles():

Questo gira su ciascun utente e controlla se ha il ruolo di Collaboratore. Lo script precedente va denominato
getGroupUsers e messo nella cartella portal_skins/custom. Ciò significa la possibilità di accedervi
tramite l’acquisizione del namespace contestuale; in breve context.getGroupUsers(object) ci ritornerà gli utenti:

users = context.getGroupUsers(object)
for id in users:
user = mship.getMemberById(id)

In questo modo ora invieremo una e-mail a ciascun componente del gruppo piuttosto che a tutti i revisori!

9.4.4 Accedere alle informazioni utente dai page template


Nel Capitolo 6 abbiamo fatto un modello di pagine (page template) che consente ad un utente di inviare feedback
all’amministratore del sito tramite un modulo. In quel modulo un campo di inserimento permette all’utente di
276 INDICE

inserire un indirizzo e-mail che poi sarà possibile validare. Comunque, se un utente è registrato e se ne conosce
l’indirizzo e-mail sarebbe bello presentarglielo automaticamente.
Il codice esistente per quel campo è questo che segue:

<input type="text" name="email_address"


tal:attributes="tabindex tabindex/next;
value request/email_address|nothing" />

Ora, se esiste un valore per l’indirizzo e-mail nella request da un precedente tentativo di riempimento dovremo
mostrare quello. Altrimenti dovremo vedere se esiste un indirizzo e-mail per l’utente corrente. Le modifiche al
modulo che seguono assicurano che (il campo del - n.d.t.)) l’indirizzo e-mail sia riempito:

<input type="text" name="email_address"


tal:define="user context/portal_membership/getAuthenticatedMember;
email user/email|nothing"
tal:attributes="tabindex tabindex/next;
value request/email_address|email|nothing" />

9.4.5 Correzione e comprensione della sicurezza


Abbiamo capito che la sicurezza non è solo una delle parti più dure di Plone ma anche che è una delle più difficili
da correggere e collaudare. Siccome il modello è granulare e complicato, può essere estremamente difficile
trovare perché e dove avviene un errore. Talvolta il messaggio di errore o le informazioni ricevute sono difficili
da decifrare o addirittura è proprio difficile trovare informazioni specifiche.
Collaudare la sicurezza è ancora più difficile poiché nei siti con molti ruoli, si dovrebbe fare un test completo di
regressione per ciascuno di quegli utenti per ciascuna di quelle situazioni. Ma spesso, visto il costo che implica,
non vengono affatto eseguiti questi collaudi di regressione. Avere un difetto nella sicurezza, però, è probabil-
mente una delle cose peggiori che possono succedere per quei siti che contengono informazioni confidenziali.
Plone consente di fare ciò che si vuole; lascia tranquillamente spararsi nei piedi, quindi fare attenzione!

VerboseSecurity

VerboseSecurity è un prodotto autonomo incluso nell’installer. È possibile scaricare VerboseSecurity da http://hathaway.freezo


Come suggerisce il nome, fornisce un messaggio dettagliato dell’errore (che si riceve - n.d.t.) quando non si rie-
sce a fare qualche cosa in Plone poiché non si è autorizzati. Purtroppo, se si sono fatte impostazioni della
sicurezza troppo lasche, questo prodotto non può aiutare granché.
VerboseSecurity può girare tranquillamente su un server Plone senza creare problemi di prestazioni quindi è
possibile farlo girare sul server di produzione e di sviluppo. Possono esserci solo dei piccoli spunti di impegno
extra quando qualcuno non è autorizzato a fare qualcosa e viene sollevato un errore e i nuovi moduli di sicurezza
lo intercettano.
Comunque, siccome il messaggio di errore è molto dettagliato, non si vuole esporlo agli utenti. Dice molto di più
di quanto gli utenti debbano sapere sul nostro sistema! Non dovrà mai rivelare informazioni protette da password
su utenti, ruoli e permessi. Ovviamente , il server di produzione deve poter lavorare sempre in modo perfetto
quindi non vi è necessità di installarlo li.
L’implementazione originale della routine di controllo dei permessi è scritta in Python. Appena si è stabilizzata
la API e gli sviluppatori hanno intuito il sovraccarico causato dalla sicurezza, essa è stata riscritta in C. Per
default gira la implementazione più veloce di C ma ciò significa che VerboseSecurity non può aggiustare il
modulo dei permessi per essere più verboso. Si ha raramente bisogno di impostare un tale livello di dettaglio,
abitualmente sono sufficenti le informazioni che già si ottengono. Altrimenti, se si ha la necessità di ricevere
maggiori informazioni, si dovrà lanciare Plone con la seguente variabile d’ambiente:
9.4. MANIPOLAZIONE DEGLI UTENTI CON DEGLI SCRIPT 277

ZOPE_SECURITY_POLICY=PYTHON

Per far funzionare VerboseSecurity basta assicurarsi che VerboseSecurity sia nella cartella Products (per
maggiori dettagli vedere il Capitolo 10) e quindi riavviare Plone. Andare all’oggetto cookie_authentication,
che è l’elenco delle opzioni per l’autenticazione al sito e, nel modulo, cambiare l’opzione per login_page da
require_login a bank (empty), come mostrato in Figura 9-14

Ora si andare a ricreare le circostanze dell’errore che si deve correggere. Ricordarsi di registrarsi come l’utente
che ha ricevuto l’errore. Questo è il motivo per cui è comodo avere due differenti browser che accedono al sito.
Uno per amministrare, uno per collaudare. Quando avviene l’errore, un dialogo di autenticazione HTTP viene
lanciato nello schermo. A quel punto, premere Cancel e si otterrà un dettagliato messaggio di errore, come quello
mostrato in Figura 9-15.

Il messaggio è piuttosto lungo ed autoesplicativo. A questo punto, normalmente, si passa all’altro browser
esaminando le impostazioni dei permessi per l’oggetto considerato per vedere quale causa può esserci.

Problemi tipici

Ci sono un paio di errori che è facile individuare quando si lavora con Plone. Il primo non è correlato direttamente
a Plone ma stimabilmente ripetitivo: controllare che l’utente che genera l’errore sia proprio quello che si crede.
Spesso si sente dire “Funziona in un browser ma non in un altro”. Questo dipende abitualmente dal fatto che
oltre ad aver scambiato i browser si è anche cambiato utente.
Continuando con le ovvietà, ricontrollare che l’utente abbia il ruolo che ci si aspetta debba avere. Questo può
significare andare nella acl_users, per vedere quale ruolo ha realmente l’utente ricontrollando che sia quello
atteso. Poi si pensi ad ogni gruppo a cui l’utente appartiene. Guardando di nuovo nella acl_users vedremo se
e perché gli utenti possono ottenere ruoli extra in un gruppo. Finalmente, ricordando che un ruolo di un utente
può anche essere alterato dai ruoli locali delle cartelle o degli oggetti, questo è un po’ più difficile da definire
chiaramente in quanto non vi è un sistema per dire quale cartella o quale oggetto abbia ruoli locali.
Una volta sicuri di chi realmente sia l’utente e del ruolo che ha sull’oggetto, si è in grado di sapere quali sono
realmente i permessi sull’oggetto stesso. Come si è visto, due oggetti simili (per esempio due documenti) possono
avere impostati differenti permessi e differenti ruoli. L’utente che ha creato l’oggetto ha il ruolo di possessore
per quel documento mentre un’altro ha su di esso solo il ruolo di collaboratore. Siccome il controllo di flusso
cambia i permessi su un documento mano a mano che passa da uno stato ad un altro, anche questo può cambiare
i permessi.

Bloccare il sito Plone

Non c’è un modo semplice per farlo in quanto è inconcepibile un sito bloccato. Comunque il principio base
è che gli utenti siano abilitati a fare il minimo necessario e niente più - per questo è il caso di ricontrollare le
impostazioni di default e di rimuovere quelle (i permessi n.d.t.) di cui eventualmente non si ha bisogno.
Chi è veramente paranoico può addirittura iniziare a rimuovere funzionalità dall’interfaccia utente e fermare il
girovagare degli utenti mediante la modifica del Cascading Style Sheets (CSS). Ovviamente bisogna ricordarsi
che non è sufficente rimuovere la scheda di una azione o impedire l’accesso al modello di pagina (page template)
se l’utente può ancora, per esempio, modificare un documento. Con un po’ di conoscenza di Plone egli può
lanciare la pagina tramite uno script o qualche altro malizioso meccanismo. Ci si accorge ben presto, se si prova
abbastanza, che in Plone è possibile ottenere la pagina di modifica di un (qualsiasi n.d.t.) documento che si sta
visualizzando semplicemente agendo sull’indirizzo URL (Uniform Resource Locator). Comunque non si può
realmente modificare quella pagina; si può solo riuscire a chiamare la sua scheda di modifica.
278 INDICE

Figura 9.14: Figura 9-14. Modifica delle impostazioni di login per il sito
9.4. MANIPOLAZIONE DEGLI UTENTI CON DEGLI SCRIPT 279

Figura 9.15: Figura 9-15. Un ben dettagliato messaggio di errore


280 INDICE

Se il server gira liberamente senza restrizione di accesso ci si assicuri che vi sia un web server davanti al nostro
ZServer Zope. Come abbiamo detto nel Capitolo 10 lo ZServer fornito con il pacchetto è una implementazione
semplice senza quei controlli e la sicurezza che un vero server web deve avere. Per gli altri servizi di Zope, come
13
FTP e WebDAV, si introduca un server proxy , se possibile, se si ha l’intenzione di permettere l’accesso a tali
servizi da parte di utenti insicuri (normalmente non è così).

9.5 Integrazione di Plone con altri servizi


Le sezioni che seguono trattano della sicurezza esterna all’istanza Plone (per esempio tutte le impostazioni di
sicurezza necessarie per avviare effettivamente Plone sul Server). Parleremo poi dell’uso di Plone con LDAP in
modo da poter riutilizzare in Plone utenti di un server esterno.

9.5.1 La sicurezza del proprio server


Abbiamo trattato la sicurezza degli utenti dentro un sistema Plone ma c’è un altro importante argomento: la
sicurezza e l’impostazione del server Plone all’interno del proprio sistema operativo. Come per qualsiasi altra
applicazione web, l’operazione di impostazione dei permessi di accesso per il server prima di mostrarlo al mondo,
è abbastanza critica. Il meccanismo di installazione di Zope è bravo e fa molte di queste cose per noi, ma ci sono
alcuni aspetti da conoscere che presentiamo qui avanti.

L’utente che esegue Zope

Ci si assicuri che l’utente che esegue Zope abbia il minimo dei permessi necessari per completare l’operazione.
L’utente che esegue Zope deve poter leggere e scrivere in tutto il file system di Zope. Deve poter scrivere le
cartelle con i file di log ed il database dell’istanza Zope: le cartelle var e log della nostra istanza Zope.
Il modo migliore per far questo in Linux è quello di aggiungere un account dedicato con un utente denominato
plone che lo gestirà; si può inoltre limitare l’accesso a questo utente nel malaugurato caso di un tentativo di
manomissione di Plone.
In Linux, se si vuole che Plone si appoggi su porte con un numero basso (sotto la 1024), come la 21 o la
80, è necessario far girare Plone come root. Ci si collegherà a quelle porte come root per poi cambiare con un
altro utente esistente. Per far questo si dovrà specificare un valore per l’effective-user nel file di configurazione;
zope.conf. Questo cambia le porte di ascolto e l’utente; un esempio è effective-user zope. La migliore
alternativa è non fare nulla di tutto ciò e invece far girare Zope su una porta più alta, come la 8080. Si può poi
proteggere questa porta con un firewall e usare Apache o qualche altro web server che giri sulla 80 e con un
proxy verso la 8080. Il Capitolo 10 tratta più in dettaglio questo argomento.
L’equivalente in Windows è l’utente che lancia il servizio; per default che lo fa è l’account LocalSystem. Anche
qui è possibile cambiare l’utente che fa partire Plone. Se si sta cercando di far partire Plone su un computer
Windows che non ha servizi (cosa che non raccomandiamo o supportiamo), Plone partirà localmente con l’utente
che ha avviato manualmente il server.
Alcuni prodotti possono richiedere l’installazione di software aggiuntivo per la fornitura di funzionalità come
la manipolazione di immagini, la conversione di documenti e così via. Se si sta installando qualcuno di questi
strumenti, si ricordi che possono richiedere un po’ di lavoro per interagire con successo con il proprio sito Plone.
Per esempio, installando pdftohtml per la conversione di documenti PDF in Windows, è necessario, affinché il
comando sia letto, lanciare il servizio con un utente che abbia i permessi sufficenti affinché Zope possa interagire
con quel software. In questo caso, se il server è dietro ad un firewall, non vi sono problemi.

13
in modo che il sistema di autenticazione sia assolutamente sicuro. (n.d.t.)
9.5. INTEGRAZIONE DI PLONE CON ALTRI SERVIZI 281

Ottenere l’accesso di emergenza

Se si ha un sito Plone ma non si può accedere alla ZMI in quanto non si conosce o si è persa la password, vi
si può accedere tramite un account di emergenza. Per crearlo è necessario avere un accesso al file system della
nostra istanza del sito Plone. Se non lo si ha si dovrà prima in qualche modo provvedere ad ottenerlo.
Si vada quindi nella root della propria istanza Plone allo script zpasswd.py . Lo si trova nella cartella Zope (in
ZOPE_HOME). Sul nostro computer lo script zpasswd.py è in /opt/Zope-2.7/bin/zpasswd.py. Quindi
per creare una password si faccia quanto segue:

$ cd /var/zope
$ python /opt/Zope-2.7/bin/zpasswd.py access

Username: emergency
Password:
Verify password:

Please choose a format from:

SHA - SHA-1 hashed password


CRYPT - UNIX-style crypt password
CLEARTEXT - no protection.

Encoding: SHA
Domain restrictions:

Ciò crea un file access nell’istanza Zope. Si riavvii Zope e ci si logghi nella ZMI usando l’username e la
password inseriti in quello script. Questo utente ha un significato speciale per Plone ed è detto emergency user.
Una volta loggati come utente di emergenza non è possibile creare oggetti ma è però possibile crearsi un nuovo
utente e successivamente loggarsi con quello. Per motivi di sicurezza è opportuno, in seguito, eliminare il file
access.

Ottenere l’accesso di emergenza su Windows

L’installazione Windows di Plone fornisce una interfaccia grafica per creare con facilità l’accesso di emergenza.
Selezionare Start - Program Files - Plone - Plone e scegliere l’opzione Emergency User. Questo consente di
creare un nuovo utente, modificare la password attuale dell’utente di emergenza o rimuovere qualsiasi utente di
emergenza esistente, come mostrato in Figura 9-16.

Per creare un nuovo utente cliccare su Create User. Nella maschera di dialogo aggiungere un username ed una
password. Questo crea un file sul file system che contiene il nome e la password. Nello stesso modo, cliccando
su Change Password si modifica la password di questo utente. Dopo aver aggiunto l’utente o modificato la
password è necessario riavviare Zope. Per riavviare Plone, andare nella scheda Control, cliccare Stop, quindi
cliccare Start. Cliccare poi Manage Root e inserire l’username e la password appena impostati. Si entrerà come
utente di emergenza, il che significa che non si possono creare oggetti ma si può creare un nuovo utente per
potersi loggare successivamente con quell’account.

9.5.2 Utilizzo di sistemi di autenticazione esterni


Plone tiene tutti i suoi utenti nel database ad oggetti di Zope in un’elenco separato, come si è visto nel Capitolo
8. Come sempre ciò non è la perfezione e verrà il momento che si vorrà usare un altro servizio per autenticare
282 INDICE

Figura 9.16: Figura 9-16. Creazione di un nuovo utente di emergenza

gli utenti. Il sistema alternativo più diffuso è LDAP o Microsoft’s Active Directory, che comunica usando il
protocollo LDAP.
Comunque vogliamo effettivamente integrare una applicazione che conserva gli utenti in un database relazionale.
Al momento che scriviamo il sito ASPN di ActiveState usa Zope per i contenuti ma gli utenti possono utilizzare
il sistema di autenticazione degli utenti Microsoft Passport. L’installazione di schemi di autenticazione esterni è
ora abbastanza semplice grazie all’eccellente lavoro di molti sviluppatori. Provando ad impostarlo si nota che la
parte più difficile è stata costruire il software ed impostare l’integrazione tra sistemi.

Cautela!
Nella prossima sezione lavoreremo sulla cartella acl_users di un sito Plone. Mai cancel-
lare o alterare la cartella acl_users nella radice dell’istanza Zope! Se lo si fa e la propria
cartella utenti per qualche ragione si corrompe (per esempio se va giù il server), l’intero
sito sarà bloccato e non sarà più possibile ottenere un qualsiasi accesso, neppure come
amministratore. Ci si assicuri di modificare solo la cartella utenti del sito Plone.

Utilizzo di LDAP

Prima è necessario impostare un server LDAP o qualche cosa che comunichi con LDAP, come Active Directory
(anche se apparentemente Active Directory ha alcune irregolarità). In questo esempio installiamo openLDAP
su un server Red Hat e su un server Windows. Per Windows si trova una versione precompilata all’indirizzo
http://www.zope.org/Members/volkerw/LdapWin32. È stata testata con Python 2.3.
Scaricare e decomprimere il file e mettere i contenuti in c:\Program Files\Plone\Python\lib\site-packages
Poi installare LDAPUserFolder.
Su Linux per scaricare openLDAP recarsi all’indirizzo http://www.openldap.org/. La versione da noi provata
includeva i pacchetti RPM 2.0.27-2.8.0 e 2.0.27-2.8.0. Li abbiamo compilati seguendo le istruzioni, andando poi
al http://python-ldap.sourceforge.net/, per scaricare le appropriate librerie LDAP Python e poi abbiamo compilate
9.5. INTEGRAZIONE DI PLONE CON ALTRI SERVIZI 283

anche quelle. Quella da noi provata è la versione 2.0.0pre05-1.i386.rpm. Assicurarsi di usare il medesimo
interprete Python usato per far girare Plone.
Dopo aver sistemato questi graziosi particolari è necessario assicurarsi che il modulo _ldap.so sia importabile in
Python. La via più semplice per farlo è lanciare il seguente:

$ python -c "import _ldap"

Se non si ricevono errori, è stato importato correttamente. Se si sono ricevuti errori si dovrà tornare sui pro-
pri passi. Quindi andare e prendere LDAPUserFolder da http://www.dataflake.org/software/ldapuserfolder. La
versione da noi provata era la 2.1 beta 2. Scaricare il file, decomprimerlo e muovere il contenuto nella cartella
Products della installazione Zope. Per esempio:

$ tar -zxf LDAPUserFolder-2_1beta2.tgz


$ mv LDAPUserFolder /var/zope/Products

Ora riavviare Plone, andare nel pannello di controllo ed assicurarsi che sia mostrato lì nella pagina Products del
pannello di controllo. Maggiori dettagli nel Capitolo 10.
Quindi, in Plone possiamo cliccare su acl_users, cliccare Sources, e scorrere fino all’opzione Users source #1.
Selezionare quindi LDAPUserFolder, e poi spuntare I’m sure, come mostrato nella Figura 9-17. Ciò crea una
nuova cartella utenti che rimpiazza l’esistente, quindi prestare cura a non perdere alcunché di critico. Infatti
questo è un buon momento per effettuare un back-up. Poi cliccare OK.

Nelle impostazioni di LDAPUserFolder aggiungere le opzioni che corrispondono alle impostazioni LDAP esi-
stenti. Dovrebbe ora essere già possibile cliccare sulla scheda Users e cercare tra gli utenti esistenti nella propria
cartella LDAP.

Database relazionali e altri

exUserFolder, extensible user folder, è un eccellente sostituto per le cartelle utente. È facile da installare, basta
scaricarlo da http://prdownloads.sourceforge.net/exuserfolder/exUserFolder-0_20_0.tgz, fare la solita danza per
decomprimerlo, e copiarlo nella nostra cartella Products. Di nuovo, dopo aver fatto ripartire Plone, si dovrebbe
poter cliccare su acl_users, selezionare Sources e scorrere fino all’opzione Users source #1. Selezionare quindi
exUserFolder e spuntare I’m sure.
A questo momento exUserFolder può autenticare verso:

• Radius
• SMB
• LDAP
• database relazionali

Per far questo è necessario installare l’adattatore specifico per il database relazionale; fortunatamente sono dispo-
nibili adattatori per i maggiori database relazionali. Ulteriori informazioni sono disponibili; è possibile trovarne
di eccellenti nelle cartelle exUserFolder con un file ReadMe per quasi tutti gli argomenti. IL Manuale di Zope trat-
ta l’impostazione dell’accesso ad un database relazionale in http://docit.bice.dyndns.org/static/Zope/ZopeBook/cap_DatabaseRelazionali.h
(originale: http://zope.org/Documentation/Books/ZopeBook/2_6Edition/RelationalDatabases.stx).
Duplicate explicit target name: “capitolo 3”.
284 INDICE

Figura 9.17: Figura 9-17. Aggiungere un LDAPUserFolder


Capitolo 10

Capitolo 10: Integrazione con altri


Sistemi

285
286 CAPITOLO 10. CAPITOLO 10: INTEGRAZIONE CON ALTRI SISTEMI
Indice

Note alla traduzione del capitolo


Rich Editor: Editor grafico

L’integrazione è un enorme problema per molte imprese che possiedono già un gran numero di altri sistemi in
loco. Dato che Plone è un progetto open source, possiede molti prodotti, add-on, personalizzazioni e strumenti
che offrono gratuitamente funzionalità aggiuntive. Questo è un bene; questi prodotti supplementari spesso sono
forniti a chiunque li voglia. Inoltre, in quanto linguaggio open source, Python possiede un intero ambiente free,
eccellenti prodotti (chiamati spesso pacchetti). La maggior parte di tali prodotti non riguarda comunque diretta-
mente Plone. In altre parole, non forniscono funzionalità solo a Plone, ovvero quello che fanno normalmente i
prodotti Plone. Tuttavia, la gente spesso chiede, “Plone può fare la cosa X?” La risposta spesso è , “sì, se può
farla Python”.
In seguito alcuni dei prodotti Python più popolari:

Python Imaging Library (PIL) Permette di manipolare, convertire, ed analizzare immagini (http://www.Pythonware.com/Products/pil/).
ReportLab Permette di creare dinamicamente file Portable Document Format (PDF) con immagini, grafici, e
le altre amenità (http://www.reportlab.org/).
Windows extensions Fornisce un’interfaccia a tutte le Windows Application Programming Interfaces (APIs);
rende, per esempio, possibile usare oggetti Component Object Model (COM) (http://sourceforge.net/projects/pywin32/).
Pygame E’ un ambiente di lavoro che consente agli utenti di scrivere giochi in Python. Qualcuno in Plone lo
ha usato per avere accesso all’interfaccia del livello media; consente la creazione di immagini o suoni
(http://www.pygame.org/).
OpenOffice.org bindings Offre collegamenti in modo tali da poter fare pressoché qualsiasi cosa sui documenti
di OpenOffice.org, fare anche il parsing di documenti Microsoft Office, per esempio come vedremo nel
Capitolo 13 (http://udk.openoffice.org/python/python-bridge.html).
mxTidy Questo pacchetto localizza e corregge problemi nei file Hypertext Markup Language (HTML), inclusi i
modelli di pagina (http://www.egenix.com/files/python/mxTidy.html).

Questi eccellenti add-ons hanno di solito installer grafici per Windows che ne facilitano l’installazione. Se non si
utilizza Windows, allora il modulo distutils per Python offre una semplice interfaccia a linea di comando per in-
stallare qualsiasi prodotto. Come sempre, la chiave fondamentale per installare ogni cosa è di leggere le istruzioni
contenute nei file scaricati. Questo capitolo si concentrerà sull’installazione di prodotti che offrono funzionalità
aggiuntive a Plone. È possibile trovare un insiene di pacchetti Python presso http://www.python.org/pypi.

287
288 INDICE

Licenze Open-Source
La maggior parte dei pacchetti open source viene rilasciata con una particolare licenza
che descrive come il pacchetto possa essere usato. Prima di usare qualsiasi codice di
terze-parti, si dovrebbe controllare la licenza per vedere se sia compatibile con le proprie
necessità.
Plone è licenziato sotto la General Public License (GPL), che si può trovare presso
http://www.gnu.org/copyleft/gpl.html e nel file LICENSE.txt della propria installazione di
Plone. Se si è lo sviluppatore di un sito web Plone si può felicemente creare e sviluppare
siti web senza alcun problema. Gli utenti del sito web non dovranno preoccuparsi mai della
licenza del codice; loro usano semplicemente un normale sito web. Come per molte licenze,
la licenza limita la redistribuzione e vendita di codice di altre persone.
Di solito le licenze sono facili da leggere e da capire, ma nell’incertezza probabilmente ba-
sta farla guardare da un professionista legale qualificato. Qui ci limitiamo a descrivere le
principali licenze che esistono nel mondo Zope e puntare a dove si possono trovare ulteriori
informazioni:
Zope Public License http://zope.org/Resources/ZPL
Python License http://http://www.python.org/2.3/license.html
GPL http://www.gnu.org/copyleft/gpl.html
Lesser GPL http://www.gnu.org/copyleft/lesser.html

10.1 Installare prodotti Plone


Un prodotto (product) è un modulo da installare all’interno di Plone per offrirgli ulteriori funzionalità. Anche se
il nome prodotto sembra implicare un costo, in questo caso, così non è – la maggior parte dei prodotti sono free
ed a sorgente aperto. Il termine prodotto di fatto descrive qualche cosa scritto nel File System e distribuito per
essere usato in altri siti Plone.
Installare un prodotto generalmente comporta i seguenti due passi:

1. Installarlo affinché sia registrato all’interno di Zope


2. Installarlo in ciascuna istanza di Plone in cui si intende usarlo

La grande varietà di add-on disponibile implica che sia abbastanza difficile fornire regole sicure e veloci su ciò
che si deve fare per installarli. Come suggeriamo ripetutamente in questo capitolo, si devono sempre leggere i
file di installazione del prodotto, che normalmente spiegano come installarli. Se si ha bisogno di ulteriore aiuto,
contattare una mailing list o l’autore del prodotto per ulteriori informazioni; comunque, assicurarsi prima di aver
letto le istruzioni.
Quando si installano prodotti, bisogna ricordarsi che si sta installando codice che potrebbe essere incompleto e
che non è possibile avere garanzie sulla sua qualità. È nella natura dello open source, ove le persone tendono a
scrivere prodotti per poi abbandonarli per indirizzarsi verso altri progetti. In un mondo ideale, prima di installare
qualsiasi cosa, si dovrebbe prendere tempo ed assicurarsi di leggerlo riga per riga. In realtà, non lo si può fare.
Infatti, la maggior parte dei prodotti è veramente buona. Solamente si deve porre attenzione a fare delle prove
prima di installarli nel proprio sito da un milione di dollari.
10.1. INSTALLARE PRODOTTI PLONE 289

10.1.1 Trovare i prodotti


Trovare i prodotti giusti che soddisfano le proprie necessità probabilmente è la parte più difficile dell’integrazio-
ne. Il sito web Zope.org contiene molti prodotti creati e caricati dagli utenti. Questi prodotti si possono trovare
principalmente presso http://www.zope.org/products, ma se si guarda nella home page di Zope.org, sul lato de-
stro, si vedono gli annunci dei prodotti. Alcuni di questi prodotti sono relativi a Plone, altri a Zope, al Content
Management Framework (CMF), o relativi a Python.
L’altra area fondamentale per trovare prodotti è il progetto Collective presso SourceForge (http://sf.net/projects/collective).
I prodotti del progetto Collective risiedono nel Concurrent Versioning System (CVS) di SourceForge. Anche se i
prodotti vengono rilasciati frequentemente come tarball, spesso l’accesso via CVS è il miglior modo per vederli.
In questo momento, non esiste alcuna directory contenente prodotti Plone o il loro stato. (Speriamo che ve ne
sia una on-line su Plone.org al momento in cui questo libro sarà pubblicato). Appena sono rilasciati i prodotti, la
gente tende a metterli sulla pagina File, ma la cosa migliore è guardare nel CVS. Si può trovare una vista visuale
di tutti i file disponibili presso http://cvs.sourceforge.net/viewcvs.py/collective/.
Un repository finale di CVS che contiene utile codice è il repository CVS della Zope Corporations. Pressocché
tutto il codice, reso pubblico, è collocato in questo repository CVS. Se si sta cercando il sorgente di Zope 2, allora
pure questo è il posto adatto. La cartella Products contiene tutti i prodotti (http://cvs.zope.org/Products/). Presso
http://dev.zope.org/CVS/ReadOnlyAccess si possono trovare ulteriori informazioni su come prelevare il codice.

10.1.2 Cos’è un CVS?


Il Concurrent Versioning System CVS è un sistema per mantenere il controllo sul codice sorgente. Gran parte
dello sviluppo di codice avviene in un sistema di controllo di codice sorgente, come CVS o uno dei molti prodotti
similari che competono con lui, come Subversion, Perforce, BitKeeper e così via.
Prelevare file da CVS è semplice, e la maggior parte degli utenti Unix e Linux hanno familiarità con l’uso di
CVS dalla linea di comando. Per prelevare tutti i prodotti del Collective sul proprio computer (potrebbe essere
necessario un bel po’ di tempo), fate cosi:

cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/collective login

Fornite una password vuota blank e continuate con il seguente comando:

cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/collective co *.*

La maggior parte della squadra di sviluppo di Plone che usa Windows utilizza TortoiseCVS il quale si aggancia
direttamente alla shell di Windows Esplorer; in Esplorer si può cicclare con il tasto destro per aggiornare ed
inviare codice. Per ulteriori informazioni su TortoiseCVS, visitate il sito http://www.tortoisecvs.org.

10.1.3 Installare in Zope


Una volta trovato e scaricato un appropriato prodotto, dovremmo installarlo. Prima bisogna installarlo in Zope in
modo che possa riconoscere il nuovo prodotto. Per farlo, abbiamo bisogno di trovare la cartella che contiene tutti
i prodotti esistenti. Per trovarle, andiamo al pannello di controllo nella Zope Managemet Interface (ZMI). Là
possiamo vedere la lista delle cartelle della nostra instanza Plone. Se troviamo un valore per INSTANCE_HOME,
allora la nostra cartella Products sarà posizionata in essa. Se non troviamo un valore, troveremo la cartella
Products in SOFTWARE_HOME. Pressocché tutti i metodi di installazione di Plone creano per noi INSTAN-
CE_HOME. Come mostrato in figura 10-1, la nostra INSTANCE_HOME è /var/book, così la nostra cartella
Products è posizionata in /var/book/Products.
290 INDICE

Figura 10.1: Figura 10-1. Localizzare la nostra cartella Products


10.1. INSTALLARE PRODOTTI PLONE 291

Per renderlo parte dell’installazione Zope, prendiamo il prodotto scaricato, decomprimiamolo e poniamolo nella
cartella Products del nostro server. Attualmente fare ciò è un po’ complicato e dipende moltissimo da come
sia pacchettizzato il prodotto che stiamo provando ad installare. Per mostrare questo più in dettaglio, la sezio-
ne seguente spiega come installare un prodotto di esempio, CMFExternalFile, che viene trattato nella sezione
Amministrare un file in Plone.
Una delle cose belle di CMFExternalFile è che in realtà è composto da due parti, con due download separati.
Prima, abbiamo il codice specifico per Zope chiamato ExternalFile. Se si desidera utilizzare questo prodotto al di
fuori di Plone, in pieno Zope, possiamo farlo. Secondariamente, abbiamo il codice specifico per Plone e specifico
per CMF denominato CMFExternalFile. La maggior parte dei prodotti non ha bisogno di due installazioni;
vengono rilasciati autocontenuti in un unico prodotto.

Effettuare un’installazione su Windows

Abbiamo bisogno, prima, di scaricare il prodotto da Zope.org, URL http://zope.org/Members/arielpartners/ExternalFile/1.2.0/ExternalFile-


1-2-0.zip e di salvarlo sul nostro computer.
Successivamente, decomprimiamo il file. Per farlo possiamo usare WinZip che troviamo su molti computer
Windows oggigiorno (noi preferiamo 7-Zip che è disponibile presso http://www.7-zip.org /).
Dopo la decompressione, troveremo una cartella chiamata ExternalFile. All’interno di questa v’è la cartella
del prodotto (si veda figura 10-2). Possiamo dire ciò perché in questa cartella è presente un intero gruppo di file
Python e di testo, incluso INSTALL.txt e README.txt che contengono informazioni su come effettuare
l’installazione.

Successivamente, moviamo la cartella ExternalFile (non il solo contenuto) nella nostra cartella Products.
In Windows è localizzata in C:\Program File\Plone 2\DataProducts. In essa vediamo una serie di
altre cartella incluse CMFPlone, CMFCore e così via. La cartella ExternalFile ora dovrebbe essere fra
queste. Possiamo allora andare a testare l’installazione sul server.

Effettuare un’installazione su Unix

Prima, abbiamo bisogno di scaricare il prodotto da Zope.org presso http://zope.org/Members/arielpartners/ExternalFile/1.2.0/ExternalFile-


1-2-0.zip e di salvarlo sul nostro computer. Successivamente, decomprimere il file; la maggior parte dei sistemi
Unix ha già installato un apposito programma (di unzip). In tal caso, eseguiamo i seguenti comandi:

$ unzip ExternalFile-1-2-0.zip
Archive: ExternalFile-1-2-0.zip
creating: ExternalFile/CVS/
...

Dopo aver decompresso, troveremo la cartella ExternalFile. Sappiamo che la cartella ExternalFile è la
cartella del prodotto perché in essa v’è un intero gruppo di file Python e testo, incluso INSTALL.txt e
README.txt che contengono informazioni su come installarlo.
Ora moviamo la cartella ExternalFile (non il solo contenuto) nella cartella Products. Questo comando
dipende dalla configurazione del nostro server, nel nostro caso è il seguente:

$ mv ExternalFile /var/zope/Products
292 INDICE

Figura 10.2: Figura 10-2. I contenuti della cartella ExternalFile


10.2. USARE UN WEB SERVER ALTERNATIVO 293

Esaminare l’installazione sul Server

Dopo avere installato un prodotto, bisogna (re)inizializzare Plone per i nuovi prodotti che sono stati registrati.
Una volta riavviato il server, andiamo nella ZMI ed accediamo alla schermata Product Management del pannello
di controllo. Questa elenca tutti i prodotti installati sul server. Se abbiamo installato con successo il prodotto, lo
dobbiamo vediamo elencato, come mostra la figura 10-3.

Incidentalmente, possiamo avere, a questo punto, tre cose che possono andare storte. Prima, se non si trova
nulla nell’interfaccia di gestione, allora abbiamo messo la cartella nel posto sbagliato. Per correggere, con-
trolliamo attentamente sia le istruzioni di installazione, sia l’ubicazione della nostra cartella Products, come
precedentemente spiegato.
Successivamente, possiamo vedere se sia visibile, nella lista dei prodotti, un icona rotta; questo vuol dire che si
è cercato di registrare il prodotto in Zope, ma è successo un errore. Clicchiamo su l’icona rotta per visualizzare
un traceback dell’errore che dovrebbe darci una qualche possibilità per ripararlo.
Infine, se non siamo stati capace di accedere all’interfaccia di gestione dopo avere riavviato, può essere che vi sia
un problema più serio. Zope non è stato capace di inizializzarsi poiché Plone trova un errore serio. Per scoprire
quale sia il problema, avviamo Plone dalla linea di comando in modabiltà debug, e ci verrà visualizzato sullo
schermo un traceback.

10.1.4 Installare Plone


Ora che lo abbiamo installato correttamente in Zope, il passo successivo è più facile. Per installare completamente
CMFExternalFile, abbiamo ora bisogno di installare il prodotto CMFExternalFile (http://prdownloads.sourceforge.net/collective/CMFExte
nello stesso modo nel quale abbiamo installato ExternalFile. Dovremo poi riavviare anche Plone.
Dobbiamo installare CMFExternalFile in ciascuna istanza di Plone. Non tutti i prodotti Plone lo richiedono,
ma la maggior parte lo richiedono. L’unico vero modo di saperlo è leggere le istruzioni di installazione. Se
vediamo qualcosa come “installare nel modo standard di CMF” o “nella nostra instanza Plone creiamo un External
Method”, allora abbiamo bisogno di effettuare questo passo.
Fortunatamente, in realtà, possiamo trascurare le istruzioni per creare un External Method poiché Plone ha un
modo molto più semplice di farlo. In Plone, clicchiamo configurazione di plone e quindi Inserimento/rimozione
di prodotti. Vedremo la lista dei prodotti installati sul nostro server e quelli che hanno bisiogno di essere configu-
rati in Plone. Clicchiamo semplicemente il box di spunta vicino al prodotto (in questo caso, CMFExternalFile),
e clicchiamo installa, come mostrato in figura 10-4.

Fatto ciò, il prodotto verrà installato. Bene, può essere che se v’è un errore, allora esso non viene mostrato nella
lista dei prodotti installati. Possiamo essere in grado di risolvere il problema leggendo il file di log, così clic-
cando il collegamento vicino al nome del prodotto visualizziamo il log. Questo modo di installare è un servizio
fornito dallo strumento portal_quickinstaller contenuto in Zope. Per dare un’occhiata a ciò che fa davvero questo
prodotto, fate un salto alla sezione ‘Integrare Plone con il File System‘_.

10.2 Usare un Web Server alternativo


Se appartenete ad un’organizzazione che già utilizza siti web, allora probabilmente state usando una piattaforma
di server web. Virtual Hosting fornisce la capacità di servire diversi siti web su di un server, differenziando i
siti in base al loro indirizzo Internet Protocol (IP) o al loro nome. Questo permette ad un server iniziale, come
Apache, di passare richieste ad una o più istanze Plone.
294 INDICE

Figura 10.3: Figura 10-3. Prodotti correttamente installati


10.2. USARE UN WEB SERVER ALTERNATIVO 295

Figura 10.4: Figura 10-4. La lista di prodotti disponibile all’utente


296 INDICE

Il Virtual Hosting è di solito realizzato mediante regole proxy, sebbene usare un server proxy sia un approccio
desiderabile con Plone, non c’è problema per quanti siti siano ospitati. Un server proxy è posto fra un client ed
un server ed inoltra le richieste del client e del server. Un server proxy dovrebbe essere trasparente all’utente.
Nel Capitolo 14 mostreremo come si possa usare un server proxy per aumentare drasticamente il rendimento di
Plone.
Sebbene Plone usi il web server sottostante Zope, ZServer lavora più che bene - pur non essendo un web server
completo con qualità industriale che possa essere esposto al mondo. Il server ha diversi problemi riguardo a
possibili attacchi Denial of Service (DOS); comunque, questi sono problemi oscuri e difficili da scoprire all’in-
terno di ZServer. Nessun attacco noto è stato compiuto contro ZServer sfruttando questi problemi; forse questo
a causa della sua relativa oscurità nel mondo reale. ZServer non è progettato specificamente per essere un server
di capacità industriale, e per quando sia una feature completa, non è più sviluppato. Usando un server moderno
come Apache, stiamo più tranquili, poiché è un server robusto e sicuro sta affrontando il mondo. Chiaramente, se
stiamo sviluppando una intranet o un’altra applicazione con utenti fidati, questo può non costituire un problema.
La figura 10-5 mostra come dovrebbe essere tale installazione; la figura non mostra in realtà computer, solo
servizi. Una richiesta proveniente normalmente da Internet al firewall e indirizzata ad Apache ed infine a Plone.
Potrebbe essere che siano tutti su macchine diverse. Il punto fondamentale è che non vi dove essere accesso a
Plone da utenti non fidati eccetto che attraverso un proxy.

Mettendo un server web, come Apache prima di Plone offriamo un intero ambiente di servizi utili che ZSer-
ver non possiede. Per esempio, Apache può offrire: riscrivere Uniform Resource Locator (URL), supportare
Secure Sockets Layer (SSL), caching, deflation dei contenuti, hosting virtuale, proxying di altri servizi web,
pulizia (sanitation) delle richieste entranti, e così via. La richiesta più comune è di modificare un URL a
http://localhost:8080/plone in qualche cosa di più amichevole come http://vostrosito.com. Questo viene defi-
nito come riscrivere (rewriting) l’ URL. Anche se un server di proxying non richiede ciò, è molto più facile
avendone uno.
Il metodo preferito per effettuare proxying per Plone è usare un proxy Hypertext Transfer Protocol (Http).
Apache effettua ciò utilizzando il modulo mod_proxy. Quando una richiesta per una pagina entra nel server
proxy, questo esegue varie funzioni. Viene creata e spedita una nuova richiesta allo ZServer. Questa risposta è
passata indietro al server e poi al client. Chiaramente, questo è del tutto trasparente al client che fa solamente
richieste normalmente ad un server.

Nota
Il vecchio modo di connettere Apache a Plone è attraverso Fast CGI o Persistent CGI. Questi
sono più difficili da configurare e in realtà molto lenti quando vengono eseguiti. Anche se su
questi oggetti, esiste molta documentazione vecchia, ora esistono soluzioni più efficienti, e
così non raccomandiamo più questi metodi.

10.2.1 Configurare Plone


Prima di configurare il proxy del nostro server web, abbiamo bisogno di configurare Plone. Visto che solamente
un server per volta può essere connesso ad una porta, modifichiamo Plone in modo che stia in ascolto su una porta
con un numero alto. Normalmente questa porta dovrebbe essere bloccata dal firewall e non accessibile da fuori.
Porte, per esempio, sono 8080, 9090, 9673 e così via. Il Capitolo 2 offre informazioni su come cambiare le
porte su cui è in ascolto un server Plone.
Successivamente, vogliamo ottenere probabilmente la riscrizione degli URL per cambiare l’ URL del nostro sito.
Poiché un oggetto Plone vive all’interno del Zope Object Database (ZODB) ed ha un ID, esso è accessibile, nell’
URL, puntando a quell’ ID , come http://localhost:8080/plone. Per renderlo ancora più amichevole, abbiamo
bisogno di tradurre la richiesta al server web da http://vostrosito.com in una richiesta relativa all’oggetto corretto
in Zope. Ci sono due modi lievemente diversi di farlo, basati sulle proprie necessità. Se stiamo usando un
10.2. USARE UN WEB SERVER ALTERNATIVO 297

Figura 10.5: Figura 10-5. Come lavora un virtual hosting


298 INDICE

server proxy web o stiamo utilizzando siti basati su nomi di dominio, allora possiamo usare un Virtual Host
Monster (VHM). Questo è un oggetto potente e amichevole che renderà la nostra vita molto più semplice, così
che raccomandiamo pienamente di usarlo. Abbiamo bisogno di un solo VHM nella radice di un’istanza di Zope.
L’oggetto VHM risiede alla radice di un sito Zope ed intercetta tutte le richieste entranti; modifica poi la richiesta
così che la richiesta vada nell’area di Zope che desideriamo.
Per creare un VHM, nella ZMI, andiamo alla radice del nostro Zope e selezioniamo Virtual Host Monster dall’e-
lenco a discesa, nel modulo che viene aperto, digitiamo un ID. Digitiamo vhm, per esempio (non è importante
l’effettivo ID).
A questo punto, se stiamo usando un server web proxy dinanzi a Plone, continuiamo la configurazione di questo
server web nella sezione Configurare il Server Proxy.
Il passo successivo è necessario solo se non stiamo usando un server web proxy. Clicchiamo l’oggetto VHM,
aggiunto nella ZMI, e selezioniamo quindi la scheda Mapping che presenterà un lista dei rilevamenti disponibili
per gli host su questo oggetto. Il rilevamento prende una richiesta entrante e la mappa a Plone, con la sintassi
seguente:

host/path

dove host è lo hostname che è stato mappato e path è il percorso attuale dell’oggetto in Zope. Per esempio:

www.somesite.com/Plone

Per assicurare che tutte le variazioni sul nome siano mappate nel percorso, possiamo usare i caratteri jolly nel
rilevamento. Per esempio, ciò che segue mappa tutti i sottodomini di somesite.com:

*.somesite.com/Plone

Per aggiungere questa mappatura, andiamo alla scheda Mapping, digitiamo ciascuna mappatura su una nuova
riga, e clicchiamo Save. Questo significa che non saremo più in grado di accedere alla radice del nostro sito Zope
usando gli indirizzi che abbiamo mappato. Fortunatamente, possiamo ancora accedere alla radice del nostro
server Zope usando un indirizzo IP; questo funzionerà ancora perché la mappatura non viene applicata agli
indirizzi numerici. La figura 10-6 mostra com’è cambia la figura 10-5 quando si accede direttamente al server
attraverso l’ IP e si aggira la riscrittura.

Ora abbiamo mappato un dominio chiamato somesite.com in modo che punti ad una particolare istanza Plone.
Se una richiesta entrante cerca quel nome di sito, viene inoltrata all’istanza Plone.

10.2.2 Configurare il Server Proxy


Ora che abbiamo aggiunto VHM al nostro Plone, è tempo di configurare il server proxy. La configurazione del
server proxy dipende, in realtà, dal server che stiamo utilizzando. Le seguenti sezioni trattano in specifico ogni
server. Comunque, per far funzionare l’hosting virtuale dovremo passare a Plone un URL che l’oggetto VHM
comprenda.
Vale notare che c’è un ulteriore vantaggio dell’hosting virtuale usando un server proxy. Possiamo effettuare tutta
la configurazione dei domini al di fuori da Plone, nel server proxy. Questo vuol dire che il nostro amministratore
di sistema ora può amministrare e può utilizzare uno strumento a lui familiare, senza doversi preoccupare di
Plone.
Il servizio proxying funziona prendendo una richiesta entrante e manipolandola in modo tale, venga spedita a
Plone, che una richiesta con un URL speciale. Questa richiesta verrà manipolata e conterrà tutte le informazioni
di cui Plone ha bisogno di conoscere per fornire una risposta. Quando questa risposta viene prodotta e viene
10.2. USARE UN WEB SERVER ALTERNATIVO 299

Figura 10.6: Figura 10-6. Hosting virtuale con accesso alla radice
300 INDICE

spedita di nuovo alla persona richiedente, tutti gli URL devono puntare correttamente al nostro sito. Questo ci
assicurerà che i collegamenti, all’interno delle nostre pagine, siano tutti corretti. Un URL ha tre componenti
principali:

• L’ IP o hostname e la porta del server sul quale risiede Plone.


• L’ IP o hostname ove Plone risiede affinché tutti i collegamenti, nei documenti risultanti, abbiano l’ URL
corretto.
• L’oggetto reale di Zope a cui accedere e l’ URL ad esso passato passato.

Questa informazione viene passata a Plone trasformando l’ URL in un grande complicato URL dal formato
seguente (le interruzioni di linea sono state aggiunte per renderlo più chiaro):

http://[URL to server]:[port]
/VirtualHostBase/[protocol]/[URL]:[port]
/[path to virtual host root]
/VirtualHostRoot/[actual URL]

Vediamo l’esempio seguente:

• Plone è su un box all’indirizzo IP 192.168.2.1 in ascolto sulla porta 8080. Notate che l’indirizzo IP è un
indirizzo a cui il server proxy può accedere; non è un indirizzo IP esterno: quello viene gestito dal server
proxy.

• Plone dove apparire come www.miosito.it in ascolto sulla porta 80.


• L’effettiva istanza di Plone è /Plone.
• La richiesta in ingresso è per /Members/andrea.
Questo viene tradotto nel lungo URL seguente:

http://192.168.2.1:8080 ~CCC
/VirtualHostBase/http/www.miosito.it:80/Plone ~CCC
/VirtualHostRoot/Members/andrea

La chiave di funzionamento è che, quando l’oggetto VHM vede questo URL, sa precisamente cosa farne. Lo riela-
bora e spedisce la richiesta all’oggetto Plone. Evidentemente, il frammento di pagina effettivo (/Members/andrea)
sarà diverso per ogni richiesta ed avrà bisogno di essere calcolato. Ma se sappiamo cosa desideriamo ottenere,
possiamo ora configurare il nostro server.

Configurare Apache

Apache probabilmente è la scelta più popolare da mettere dinanzi a Plone, ed è disponibile per qualsiasi piat-
taforma, Linux, Unix e Windows (http://httpd.apache.org/). Dopo avere installato Apache, abbiamo bisogno di
passare richieste a Plone usando un proxy Http.
Per configurare Apache, abbiamo bisogno di accedere al file di configurazione di Apache; dove risiede dipende
dalla vostra installazione di Apache; consultiamo quindi la documentazione Apache. In Windows, la configura-
zione è accessibile dal menu Start. In Linux, di default, possiamo trovare la configurazione Apache nella cartella
/etc presso /etc/apache/httpd.conf o /etc/apache2/httpd.conf. Per modificare questo file,
solitamente abbiamo bisogno dei privileggi di root o di avere un accesso come utente privilegiato.
10.2. USARE UN WEB SERVER ALTERNATIVO 301

Nota
Questo esempio utilizza Apache 2, ma tutti questi comandi sono compatibile all’indietro con
le precedenti versioni, come Apache 1.3.2. Le precedenti versioni di Apache (antecedenti
alla versione 1.3.2), comunque, sono conosciute per avere problemi con i cookies.

Il modo più facile di riscrivere un URL in Apache è di usare i moduli incorporati riscrittura (rewrite) e proxy. Ciò
significa abilitare i moduli mod_rewrite e mod_proxy. In Apache, ogni sito, per default è contenuto all’interno di
una cartella host virtuale che comincia con il seguente:

<VirtualHost *:80>
ServerName yoursite.com
# other configuration options

Tutto ciò di cui abbiamo bisogno è abilitare la riscrittura ed aggiungere la relativa regola, così come:

RewriteEngine On
RewriteRule ^/(.*) http://192.168.2.1:8080 ~CCC
/VirtualHostBase/http/www.miosito.it:80/Plone ~CCC
/VirtualHostRoot/$1 [L,P] ~CCC
</VirtualHost>

La regola chiave del reindirizzamento prende ogni stringa di richiesta passatale e vi appende poi alla fine la regola
di reindirizzamento da noi codificata. La [L,P] indica ad Apache che questa è l’ultima regola di reindirizzamento,
e che deve inviarla al server dato. Dopo avere fatto questo, abbiamo bisogno di riavviare Apache per aggiornare
la configurazione. Possiamo trovare ulteriori informazioni sul reindirizzamento leggendo la documentazione
del modulo mod_rewrite presso http://httpd.apache.org/docs-2.0/misc/rewriteguide.html. Notate che in questo
caso abbiamo messo le informazioni delle regola di reindirizzamento all’interno della direttiva dell’host virtuale.
Possiamo quindi avere diversi host virtuali in Apache, siti PHP, Perl e Java abbiano ognuno un proprio posto in
un solo server.

Squid

Squid è la scelta più popolare fra gli utenti per la sua potenza di caching e per le sue opzioni di configurazione.
Squid è disponibile per Unix, e vi sono disponibili, per Windows, anche compilazioni realizzate usando cygwin.
Anche se non abbiamo esaminato specificamente la versione Windows, molte persone ci hanno riferito che fun-
zioni bene. Possiamo trovare il download presso http://www.squid-cache.org/. Queste note trattano la versione
2.5, l’ultima stabile al tempo della stesura.
Installare Squid dalla distribuzione sorgente è piuttosto semplice. Dopo averlo scaricato, i comandi seguenti
installano Squid:

$ tar -xvf squid-2.5.STABLE3.tar.gz


$ cd squid-2.5.STABLE3
$ ./configure --prefix=/usr/local/squid
...
$ make all
...
$ make install
...

Sfortunatamente, Squid non possiede regole di reindirizzamento che permettano di modificare le richieste entranti
prima del proxying. Tuttavia, Squid Guard (http://www.squidguard.org/) può eseguire questo lavoro. Esaminamo
la versione 1.2.0. Dopo averlo scaricato, i comandi seguenti lo installano:
302 INDICE

$ tar -zxvf squidGuard-1.2.0.tar.gz


$ cd squidGuard-1.2.0
$ ./configure
...
$ make
...
$ make install
...

Squid e SquidGuard, ora sono pronti per funzionare; entrambi i file di configurazione hanno ancora bisogno
comunque di essere modificati. Possiamo trovare il file di configurazione di Squid in /etc/squid.conf. È
un lungo file di configurazione, in cui fortunatamente vengono spiegate, con molto precisione, tutte le opzioni.
Queste che seguono, sono le opzioni essenziali da mettere:

http_port 80
httpd_accel_host virtual
httpd_accel_port 0

http_access allow all


http_access allow localhost

Queste ultime due righe sono regole di sicurezza per permettere l’accesso da browser. Visto che è stato posto
dietro ad un firewall, queste sono regole tolleranti. Se stiamo eseguendo Squid all’esterno (non protetto da
un firewall, ndt), dovremmo leggere in dettaglio, le regole di accesso. Il modo più facile di assicurare questo
è cambiare http_access allow all in http_access deny all. In fine, aggiungiamo la riga seguente al file di
configurazione:

redirect_program /usr/bin/squidGuard -c /etc/squid/squidGuard.conf

Questo imposta il reindirizzamento attraverso SquidGuard usando il file di configurazione presente in /etc/squid/squidG
SquidGuard non ha un file di configurazione, ma uno standard, che usa la configurazione dell’host virtuale come
segue:

dbhome /var/lib/squidguard/db
logdir /var/log/squid
acl {
default {
redirect http://192.168.2.1:8080 ~CCC
/VirtualHostBase/http/www.agmweb.ca:80 ~CCC
/Plone/VirtualHostRoot/%p ~CCC
}
}

In ultimo, Squid ha la configurazione che serve per reindirizzare il traffico in modo che il monster host lo
conprenda. Le richieste entranti saranno trattate da Squid e poi verranno passate a Plone.

Microsoft Internet Information Server

Internet Information Server (IIS) non è, come server, la nostra scelta preferita; comunque, visto che molte
società lo usano, abbiamo incluso questa sezione. Sfortunatamente, IIS non può effettuare proxying in modo
identico a Squid e ad Apache; abbiamo bisogno di un plug-in separato. Poco prima che questo libro fosse stato
pubblicato, è stato scritto un proxy gratuito chiamato IIS2Zope che fornisce questa funzionalità.
10.2. USARE UN WEB SERVER ALTERNATIVO 303

Comunque, non abbiamo avuto modo di provarlo in un sito ad alto rendimento. Per ulteriori informazioni, vedete
http://zope.org/Members/freshlogic/index_html.
Tratteremo invece una soluzione che è semplice da mettere su ed è free. I primi utenti di Zope raccomandavano
PCGI, ma, durante il corso degli anni, è divenuto lento e complicato da installare. Abbiamo una soluzione
più rapida, usando il linguaggio ASP di Microsoft e le proprietà di IIS. Si chiama ASP 404 ed esegue il
reindirizzamento attraverso il linguaggio di programmazione ASP di Microsoft.
Da http://www.zope.org/Members/hiperlogica/ASP404 scarichiamo l’ultima versione. Prendiamo in considera-
zione il file ASP404_1-0-b2.zip. Decomprimiamolo, troveremo, in esso, un file, default.asp. Prendia-
molo e poniamolo nella radice del sito di cui vogliamo fare proxy; sul nostro server è c:inetpubwwwroot.
Successivamente, abbiamo bisogno di modificare questo script con le informazioni corrette con l’ubicazione del
nostro sito Plone. Apriamo lo script, in un semplice editor di testo, e cambiamo le due righe che contengono le
variabili per la configurazione del sito. Specificamente, cambiamo la linea 18 da questo:

zopeAddress = "http://127.0.0.1:8080"

all’indirizzo del server di destinazione. In questo esempio, il seguente indirizzo:

zopeAddress = "http://192.168.2.1:8080"

Poi cambiamo la linea 27 da questo:

zopePath = "/"

all’ ID dell’oggetto Plone, in questo modo:

zopePath = "/Plone"

Salviamo il file, e chiudiamo l’editor. Infine, abbiamo bisogno di informare IIS di comunicare con Plone; qui
è dove dobbiamo utilizzare un po’ di inganno. Apriamo Internet Services Manager, di solito posizionato, in
qualche posto, nel pannello di controllo di Windows. Troviamo il sito verso il quale cerchiamo di fare proxy ed
accediamo alle proprietà del sito, come mostrato in figura 10-7.

Nelle proprietà, selezioniamo la scheda Custom Erros, ed andiamo giù finché troviamo l’errore 404. Fatto doppio
click sull’errore 404 lo modifichiamo come segue:
Message Type: URL
URL : /default.asp
La figura 10-8 mostra le impostazioni.

Salviamo le modifiche cliccando OK. A questo punto, il nostro elenco di errori dovrebbe apparire come in figura
10-9. Se così è, dovrebbe essere impostato correttamente. Accediamo ad IIS attraverso il browser e bingo –
vedremo Plone

Ciò che succede è che stiamo catturando l’errore di un elemento che non può essere trovato in IIS. Lo script
ASP, che abbiamo installato, legge allora la richiesta e la inoltra a Plone. Prende la risposta e la passa ad IIS e
quindi indietro al browser. Tutto ciò vuol dire che abbiamo aggiunto un semplice programma proxy ad IIS.
Qui, tuttavia, abbiamo alcune chiavi di lettura. La prima è che una pagina non deve essere trovata in seguito
all’intervento del proxy; altrimenti lo script non viene eseguito. Questo è contemporaneamente un bene ed
304 INDICE

Figura 10.7: Figura 10-7. Accedere alle proprietà di un sito

Figura 10.8: Figura 10-8. Impostare il reindirizzamento dell’errore 404

Figura 10.9: Figura 10-9. Lista degli errori


10.3. INTEGRARE PLONE NEL FILE SYSTEM 305

un male. Possiamo aggiungere cartelle ed immagini ad IIS, e saranno servite al posto di Plone se i nomi
corrispondono alla richiesta dal browser. La seconda, la richiesta entrante è analizzata e mandata avanti; questo
crea un po’ di confusione, in diverse situazioni, con tutte le possibili configurazioni di richiesta HTTP. Troveremo
anche che tutte le nostre richieste verso Plone sono in realtà registrate come errori 404, da IIS, confondendo
gli strumenti di analisi dei file di errori.
In generale, quest’installazione ha funzionato con la maggior parte delle persone che l’hanno utilizzata, ma se è
una soluzione per una azienda che dove affrontare qualsiasi situazione essa è improponibile. Offre, comunque,
una importante base di lavoro per le persone che vogliono lavorare e sviluppare.

Eseguire il debug del Proxy Server

Una volta preparato il server e riavviato il tutto, possiamo collaudarlo usando il nostro browser per visitare il
sito. Dopo averlo fatto alcune volte, possiamo utilizzare i seguenti consigli quando le cose sembrano non andare
completamente come dovrebbero:

Testare il sito La regola d’oro per la correzione degli errori (debug) del server proxy è sempre di
testare il sito registrandosi e bypassare il proprio proxy server. È possibile farlo accedendo di-
rettamente all’IP ed alla porta del vostro server Plone. Nel caso dell’esempio precedente, potet
accedere al sito puntando a http://192.168.2.1:8080/Plone, ed aggirando così completamente
il server proxy. Se non avete, in questo modo, nessun problema accedendo e registrandovi
all’interno di Plone, ma ne avet, quando cercate di accedervi attraverso il server proxy, si han-
no molte probabilità che gli errori si stiano creando sul lato server del proxy. Le versioni più
vecchie di Apache 1.3 hanno problemi con i cookies quando si effettua il login; così dovete
aggiornarlo con una versione più recente.
Controllare l’URL Controllate due volte che il vostro server proxy stia inviando l’URL corret-
to che può essere piuttosto lungo e complicato. Spezzatelo, in corrispondenza delle barre
inclinate, per esaminarlo in ogni parte. Ricordate che affinché Plone restituisca l’URL cor-
retto, gli si devono passare valori corretti. Quindi dovete assicurarvi che la sezione /[proto-
col]/[URL]:[port]section sia corretta. Se il vostro sito sta usando SSL, per esempio, assicura-
tevi che la parte relativa al protocollo sia https, non http.

10.3 Integrare Plone nel File System


Può sembrare un po’ strano integrare Plone con il File System, ma stiamo parlando di abilitare Plone all’uso
dei contenuti dal File System. Chiaramente, Plone già esiste come insieme di file installati ed eseguiti dal File
System. Tutti i contenuti, in un sito Plone, comunque, sono conservati all’interno del ZODB, ma molte persone
ci richiedono di voler conservare e di voler servire i loro contenuti direttamente dal File System.
In verità, molte persone, osservando Zope e Plone e vedendo le piccole icone di cartelle, presumono che si
riferiscono direttamente a cartelle ed elementi del File System. La realtà non è proprio così. Se stessimo usando
un database relazionale, come fa la maggior parte dei Content Management Systems (CMS), vorremo ancora fare
ciò ? Molte persone ci saltano entro pensando che sia un problema; quelle che seguono sono delle ragioni perché
si vorrebbe fare ciò:

Abbiamo molti brani di contenuto veramente grandi Plone può amministrare file veramente grandi senza
nessun problema. Database di oltre 10 gigabyte sono comuni e lavorano più che bene. Se state usando bra-
ni, veramente grandi, di contenuti (per esempio, un cliente per cui lavoriamo usa Plone per amministrare il
suo DVD - cioè il contenuto reale del DVDs), allora diamo un’occhiata a CMFExternalFile ed ad Apache.
Per cose veramente grandi una buona via è usare Apache o un altro server per fornire il vostro contenuto .
306 INDICE

Vogliamo amministrare i contenuti usando programmi che leggono dal File System, come Microsoft Word
Possiamo usare un External Editor per modificare un contenuto, conservato in un sito Plone, usando i no-
stri programmi residenti in locale. Se abbiamo installato Microsoft Word, possiamo caricare un documento
Word e quindi modificarlo sul nostro computer.
Siamo stufi di modificare codice via web, in piccole aree di testo Di nuovo, prima utilizziamo un External Edi-
tor. Secondo, perché fare lavoro, in ogni modo, attraverso il web ? Come mostrato nel Capitolo 7, possiamo
scrivere tutti gli skin ed i modelli CSS nel File System.
Vogliamo poter usare gli strumenti del nostro File System sul contenuto Bene, possiamo montare Plone tra-
mite File Transfer Protocol (FTP) e WebDAV. Entrambi forniscono interfaccie simili al File System che
funzionano con Plone.

Vogliamo effettuare facilmente il backup del contenuto

Nel Capitolo 14 mostriamo come effettuare un backup, come sia semplice fare backup incremen-
tali ed amministrare Plone. Un metodo alternativo d’archiviazione, chiamato DirectoryStorage
http://dirstorage.sf.net, può occuparsi di ciò.

Vogliamo usare CVS / Subversion / BitKeeper o qualche altro sistema di controllo dei sorgenti sul contenuto
Ah questo avrebbe senso ma, sfortunatamente, non è ancora pienamente integrato . In versioni future, di
cui una è denominata provvisoriamente Plone 3, questo potrà essere completamente integrato.

Con questi punti in mente, guardiamo ora ai vari modi in cui si possono servire contenuti che risiedono nel File
System attraverso Plone.

10.3.1 Usare il Proxying Web Server


Cosi, abbiamo preparato il server Web come precedentemente descritto in questo capitolo. A rischio di ripetersi,
quel server web è migliore per fornire semplice contenuto di quanto lo possa essere Plone. Se abbiamo un gran
numero di download, mettiamoli semplicemente in una cartella del nostro server che non abbia proxy a Plone e
poi colleghiamoli da Plone. Gli utenti cliccheranno solo il collegamento e scaricheranno come al solito.

Fare questo con IIS è facile perché IIS, automaticamente, controlla prima per vedere se il file esiste pri-
ma di sollevare un errore

Definition list ends without a blank line; unexpected unindent.

404. Apache invece richiede solamente due linee aggiuntive nel file di configurazione, come nel seguente
codice:

<VirtualHost *:80>
ServerName yoursite.com
# other configuration options
DocumentRoot /var/downloads
RewriteEngine On
RewriteRule ^/download(.*) - [L]
RewriteRule ^/(.*) http://192.168.2.1:8080 ~CCC
/VirtualHostBase/http/www.miosito.it:80 ~CCC
/Plone/VirtualHostRoot/$1 [L,P]
</VirtualHost>
10.3. INTEGRARE PLONE NEL FILE SYSTEM 307

In questo esempio, mettiamo il contenuto in /var/downloads, e gli URL per scaricarlo, attraverso Apache,
inizieranno con /download.
Il motore di reindirizzamento vede che l’URL comincia con /download e non vi applica quindi alcuna modifi-
ca; questo è il significato della lineetta (-). Specificando il [L] alla fine della riga, nessuna ulteriore regola di
reindirizzamento verrà applicata, così il proxy non interviene ed Apache continua come al solito, servendo il file.
Questo trucco è utile se cerchiamo di ospitare altri servizi sullo stesso virtual host. In un sito, che noi ospitiamo,
Mailman, un gestore di mailing list, tutti gli URL, relativi a Mailman, iniziano con /mailman e /pipermail.
Dopo aver impostato correttamente Mailman ed aver fatto tutta la configurazione, abbiamo aggiunto le due righe
seguenti alla configurazione e così lavora bene:

RewriteRule ^/mailman(.*) - [L]


RewriteRule ^/pipermail(.*) - [L]

Di nuovo, qui l’unico vincolo è che non potete aggiungere oggetti, a Plone, i cui nomi possano essere in contrasto
con le vostre regole, come aggiungere cartelle con nomi simili. Per esempio, mailman, pipermail o download,
in questo esempio, sarebbero non corretti in quanto gli utenti non potrebbero mai vedere questi oggetti. Potete
usare questo metodo per restringere accesso a certe parti del vostro sito, ma raccomandiamo per ciò di usare
invece la sicurezza di Plone. A questo punto, Plone, in realtà, non sta amministrando contenuti, così che non
vengono gestiti sicurezza, controllo di flusso, o metadati. Il contenuto è completamente fuori da Plone. A volte,
tuttavia, questo può essere una buona soluzione.

10.3.2 Amministrare un file in Plone


CMFExternalFile è un prodotto che permette di amministrare contenuto dall’interno di Plone ed avere ancora il
cuore del contenuto nel File System. Se abbiamo installato ExternalFile e CMFExternal, precedentemente nel
capitolo, allora abbiamo tutto impostato; altrimenti ritorniamo alla sezione precedente ‘Installare prodotti in
Plone‘_.
Dopo averlo installato, ritorniamo alla nostra interfaccia Plone. Notiamo che se andiamo in Plone, ora possiamo
aggiungere un nuovo tipo di contento, chiamato External File. Aggiungiamo un External File, digitato nello stes-
so modo di come facciamo con un file normale, come abbiamo descritto nel ‘Capitolo 3‘_. Infatti, se scaviamo
nel codice del programma, notiamo che usa lo stesso template.
Comunque, osserveremo una piccola differenza qui. Il file di fatto è stato aggiunto al File System. È messo in
una cartella nuova localizzata nella cartella var della nostra installazione Plone. Se non siamo sicuri dove questo
sia, andiamo al pannello di controllo e cerchiamo la cartella elencata dall’istanza home; la nostra cartella var
è localizzata in /var/zope/var. In questa cartella c’è una cartella chiamata externalfiles. In questa
cartella saranno creati tutti i file caricati all’interno di Plone. Se guardiamo in questa cartella, dovremmo trovare
il file che abbiamo caricato.
Ciò che abbiamo ora è una soluzione di memorizzazione ibrida che conserva il file nel File System ed i metadati
dell’oggetto (descrizione, parole chiave ed altro) in Plone. Questo è migliore della soluzione con il solo server
web, poiché permette al contenuto di avere sicurezza, metadata, e cosi via. Se realmente lo desiderate, confi-
gurando correttamente il vostro server di web, potrete avere il contenuto servito da Apache che legge la cartella
dalla cartella externalfiles.

10.3.3 Accedere mediante FTP all’interno di Plone


Usare FTP è un buon modo per posizionare e trovare contenuto così che si possa modificarlo senza dover usare
un browser. Per abilitare l’FTP in Plone, assicuratevi che sia attivato nel server. Ritornando al Capitolo 2,
possiamo osservare come aggiungere e modificare servizi come questo. In breve, assicuratevi che il vostro file di
configurazione di Zope, zope.conf, abbia al suo interno ciò che segue:
308 INDICE

<ftp-server>
address 21
</ftp-server>

Nota
Se abbiamo il nostro server in ascolto sulla porta 21, dobbiamo assicurarci che null’altro
stia ascoltando quella porta. Nella maggior parte dei sistemi Unix, avete bisogno inoltre, di
avviare il vostro servizio come root così che abbiate i permessi per connettersi ad una porta
di basso numero. Per fare ciò, avremo bisogno di impostare l’utente effettivo nel vostro file
di configurazione di Zope. Si veda la sezione La sicurezza del proprio server nel ‘Capitolo
9‘_.

Successivamente, avete bisogno di un client FTP per accedere al server. Se siate su Windows, allora potete usare
solamente Internet Explorer digitando l’indirizzo del server nella barra degli indirizzi. Per esempio, impostiamo
l’indirizzo del percorso del vostro server Zope (come ftp://localhost:8021/), e avrete accesso agli oggetti nel
vostro sito, come mostrato in figura 10-10.

Se per accedere al server servono un username ed una password, dobbiamo allora aggiungerli all’URL nella
configurazione seguente: ftp://user:password@localhost:8021 /. Se questo piace, sono disponibili molti altri
client FTP che permettono di avere un’interfaccia più sofisticata. Molti client FTP sono disponibili in Linux, per
linea di comando o con GUI, come gFTP e Konqueror.

10.3.4 Accesso WebDAV in Plone


WebDAV è un sistema per l’authoring dei contenti, usando HTTP, in sistemi come Plone. Questo permette di
progettare un server Plone come un File System. Per abilitarlo, dovremo modificare il file di configurazione di
Zope come descritto nel Capitolo 2 così che il file di zope.conf contenga ciò che segue:

<webdav-source-server>
address 1980
</webdav-source-server>

Il programma WebDrive, per Windows, è disponibile presso http://www.webdrive.com/. E’ disponibile, una


prova gratuita (free trial), così che possiamo provarlo. Dopo averlo installato, aggiungiamo la connessione al
server Plone, e tutto ciò di cui abbiamo bisogno, allora, è accedere direttamente al nostro sito dal File System
andando in Windows Explorer, come mostrato in figura 10-11.

Possiamo provare Cadaver (http://www.webdav.org/cadaver), per Unix, che è un client a linea di comando pieno
di caratteristiche. Dopo averlo installato, possiamo connetterci ad un sito Plone dalla linea di comando. Per
esempio:

cadaver http://192.168.2.1:8080/Members/Plone

10.3.5 Modificare il contenuto con Editor grafici


Modificare il contenuto in una text area è un pessimo modo di costringere gli utenti a scrivere ed a modificare
contenuti, una cosa che abbiamo commentato parecchie altre volte. Alcuni editor offrono soluzione per questo.
Uno è Epoz che permette, agli utenti, di modificare direttamente documenti nel browser senza dovere conoscere
HTML. Se avete molti utenti che inseriscono contenuto, installando Epoz permetteremo ai nostri utenti di modi-
ficare i contenuti HTML senza dover davvero conoscere l’HTML. Per una redazione, veramente avanzata, potete
utilizzare un External Editor che permette di modificare contenuto con un programma locale come Microsoft
Word.
10.3. INTEGRARE PLONE NEL FILE SYSTEM 309

Figura 10.10: Figura 10-10. Accesso FTP con Internet Explorer


310 INDICE

Figura 10.11: Figura 10-11. Accedere al nostro contenuto Plone usando WebDrive

Editor WYSIWYG per il browser

Potete trovare la versione esaminata di Epoz 0.7.4 presso http://zope.org/Members/mjablonski/Epoz/0.7.4. Epoz


richiede un browser moderno, cui molti utenti Plone, comunque hanno bisogno. I browser richiesti sono Internet
Explorer 5.5+, Mozilla 1.3.1+, e Netscape 7.1+.
Scaricate ed installate come al solito Epoz; dopo averlo installato, dovete modificare le vostre preferenze perso-
nali, in Plone, per poterlo usare. Dovete accedere a Plone, cliccare preferenze personali, e quindi selezionare
Preferenze Personali. Sulla pagina delle preferenze, apriamo il box a cascata Editor del contenuto, selezionate la
scelta Epoz, e poi clicchate Salva per inviare le nostre modifiche.
Ora avete scelto il vostro editor, andate in un documento (qualsiasi documento lo fa) e cliccate la scheda modifica.
Notate che il campo Corpo del testo è ora cambiato significativamente in un editor grafico. L’editor dovrebbe
essere abbastanza auto esplicativo, con pulsanti famigliari come B per grassetto, I per italico, e così via (si veda
Figura 10-12).

External Editor

External Editor è uno strumento che potete usare, in Plone, per tutti i tipi di contenuto, di template e di codice.
Permette di modificare localmente gli oggetti Plone conservati su un sito Plone con programmi di vostra scelta.
Per esempio, potete modificare localmente in Microsoft Word un documento Word, conservato sul vostro sito
Plone. Quando salvate il documento, viene spedito automaticamente a Plone.
l’External Editor viene fornito con l’installer Plone ed impostato automaticamente sul server. L’applicazione è
insolita in quanto possiede due componenti: uno per il server ed uno per ogni client che vuole utilizzarlo.
Installare il prodotto, lato server, non è necessario se si è usato un installer per installare il proprio Plone. Se non è
il nostro caso, il prodotto lato server è disponibile all’indirizzo http://zope.org/Members/Caseman/ExternalEditor.
Installare il prodotto nel modo standard, che abbiamo discusso all’inizio di questo capitolo, e poi riavviare Zope.
10.3. INTEGRARE PLONE NEL FILE SYSTEM 311

Figura 10.12: Figura 10-12. Modifica di un documento in Epoz


312 INDICE

Quindi, accedete come amministratore in Plone, cliccate configurazione di plone e poi selezionate impostazioni
del portale. Selezionate l’opzione Abilita la funzionalità External Editor per assicurare che si possano modificare
oggetti con questo strumento.
Su ogni computer che accede al sito Plone, avete bisogno di installare questo prodotto sul client. Giusto come
installare Flash o QuickTime nel vostro browser, installiamo il codice External Editors lato client. Questo è
maneggevole nelle intranet o sul nostro computer ma può essere un po’ più difficile per un sito pubblico.
Per Windows 2000 e XP, scaricate l’installer eseguibile Windows chiamato zopeedit-win32-0.7.1.exe.
Fate doppio click sull’installer, e verrà eseguita l’installazione grafica. Avete bisogno solamente di selezionare
tutti i default. Questo preparerà le opzioni per Internet Explorer. Per verificare se questo è stato installato
correttamente, fate come segue:

Per Unix, scaricate i tarball chiamati zopeedit-0.7-src.tar.gz. Avete bisogno di decomprimerli e di


eseguire l’installazione come dettagliato nelle istruzioni di installazione per Unix presso http://zope.org/Members/Caseman/Ex
uni*. Ciò che segue è un esempio per la versione 0.7:

$ tar -zxf zopeedit-0.7.1-src.tgz


$ cd zopeedit-0.7.1-src
$ python setup.py install
...

Dopo aver installato il client, avete bisogno di configurare ciascun browser che volete usare. Istruzioni per
Konqueror, Galeon, e gli altri browser sono disponibili on-line su Zope.org. Le seguenti sono le istruzioni, passo
a passo, per la configurazione di Mozilla:
Zope Editor
application/x-zope-edit
L’External Editor apre un editor basato sui contenuti di un file di configurazione. Per vedere invocato un editor
di vostra scelta, modifichiamo questo file. Potete trovarlo sotto nomi diversi nei seguenti posti, in dipendenza
dalla vostra installazione:

• In Windows, se installate Plone usando un installer, potete trovarlo in C:\Programmi\Plone\Zope\pwi\zopeed


• In Windows, se usate l’installer autonomo di External Editor, potete trovarlo nella cartella dove viene in-
stallato External Editor; di default si trova in C:\Programmi\Zope\ExternalEditor\zopeedit.ini.
• In Unix, questo file è stato chiamato .zope-external-edit e localizzato nella cartella home del-
l’utente che esegue il programma, per esempio /home/andrea/.zope-external-edit. È nella
cartella home dell’utente perché ogni utente può avere impostazioni diverse.

Questo file contiene una mappatura di estensione e l’editor invocato; per cambiare l’editor per i modelli di pagine,
per esempio, cercare le linee seguenti che contengono meta-type:Page-Template:

[meta-type:Page Template]
extension=.pt

Per esempio, potete usare Scite, un editor di testo gratuito. Per usare questo editor per i modelli di pagine,
dovremmo cambiare il file cosi da leggervi quanto segue:

[meta-type:Page Template]
extension=.pt
editor=scite
10.3. INTEGRARE PLONE NEL FILE SYSTEM 313

Figura 10.13: Figura 10-13. File di configurazione tipo su Windows


314 INDICE

Affinché l’External Editor possa funzionare, ogni chiamata dell’editor deve aprire un processo separato. Questo
vuol dire che il programma External Editor client può controllare quel processo per vedere quando è finito.
Questo causa problemi con alcuni editor che tentano di aprire file multipli, nello stesso processo. Per esempio,
per caricare VIM in KDE, dobbiamo eseguire una shell separata come:

editor=konsole -e vim

Modificare un documento Word

Per modificare un documento Microsoft Word è, in realtà, veramente facile da impostare; tutto ciò di cui abbiamo
bisogno è Microsoft Word, installato sul vostro computer locale. Caricate il vostro documento Microsoft Word
in Plone come un file standard e poi vedete il file in Plone. Cliccate la piccola icona a matita nell’angolo in alto a
destra della nostra pagina. Microsoft Word verrà aperto sul vostro computer, ed il documento verrà visualizzato
dal server. Ora potete modificare il contenuto come volete, e cliccando Salva salverete automaticamente il file in
Plone.

Modificare un modello di pagina attraverso un External Editor

Per creare un modello di pagina, usiamo la ZMI. Certamente, quando visualizziamo la cartella che contiene il
modello di pagina, vedremo un’icona a forma di matita aggiunta alla destra dell’oggetto. Cliccando la matita
attiverete l’External Editor ed aprirete il modello di pagina nell’editor che avete impostato. Tutto ciò di cui
avete bisogno di fare è scoprire un buon editor per modificare i modelli di pagina. Siccome i modelli di pagina
sono proprio Extensible HTML (XHTML), usate un semplice editor che supporti l’Extensible Markup Language
(XML). Le seguenti sezioni discutono due editor: Dreamweaver e HTML-Kit.

Dreamweaver MX

Cambiate la parte [meta-type:Page Template] del file di configurazione per puntare a Dreamweaver. Per
esempio, nella vostra installazione questo è così:

[meta-type:Page Template]
extension=.pt
editor=C:\Program Files\Macromedia\Dreamweaver MX\Dreamweaver.exe

Cliccando l’icona della matita per modificare in External Editor ora si apre direttamente Dreamweaver, come
mostrato in figura 10-14. Sfortunatamente, Dreamweaver non aprirà ciascun file in una istanza separata che
significa che potete modificare solamente un file alla volta.

HTML-Kit

HTML-Kit è un editor HTML molto potente, libero ed è il preferito da molti sviluppatori Plone. Per usare
HTML-Kit con External Editor, modificate il vostro file di configurazione per puntare a HTML-Kit. Per esempio,
nella vostra installazione questo è come segue:

[meta-type:Page Template]
extension=.pt
editor=C:\Program Files\Chami\HTML-Kit\Bin\HTMLKit.exe
10.3. INTEGRARE PLONE NEL FILE SYSTEM 315

Cliccando ora l’icona della matita per modificare in External Editor apre direttamente l’HTML-Kit. Potete inoltre
modificare una impostazione per aprire ciascun file in un processo separato; selezioniamo Edit - Preferences -
Startup, e spuntiamo Limit to a single HTML-Kit instance. Ogni file ora aprirà un processo nuovo.
Duplicate explicit target name: “capitolo 3”.
Duplicate explicit target name: “capitolo 9”.
316 INDICE

Figura 10.14: Figura 10-14. Modifica di modelli di pagine in Dreamweaver


Capitolo 11

Capitolo 11: Manipolare e categorizzare i


tipi di contenuto

317
318 CAPITOLO 11. CAPITOLO 11: MANIPOLARE E CATEGORIZZARE I TIPI DI CONTENUTO
Indice

Nel libro abbiamo mostrato come aggiungere un contenuto al nostro sito ed abbiamo trattato i tipi di contenuto di
cui Plone è fornito, come documenti, immagini e così via. Così, comunque, siamo limitati ai soli tipi di contenuto
forniti con i prodotti che si possono trovare in internet. Ma la parte più importante di Plone è l’argomento
principale di questo capitolo: la manipolazione dei tipi di contenuto.

11.1 Panoramica dei tipi di contenuto

319
320 INDICE
Capitolo 12

Capitolo 12: Scrivere un prodotto in


Python

321
322 CAPITOLO 12. CAPITOLO 12: SCRIVERE UN PRODOTTO IN PYTHON
Indice

Scrivere un prodotto per Plone ci consente di fare quasi ogni cosa che con Plone ci piace fare. La maniera migliore
per fornire il massimo della flessibilità è usare Python per scrivere tipi di contenuto o strumenti. Se abbiamo un
urgente bisogno che Plone faccia qualcosa di specifico, e questo non è trattato altrove, qui abbiamo la possibilità
di aggiungere questa funzionalità scrivendo un prodotto. Può essere archiviare qualche tipo di contenuto specifico
della nostra azienda o qualche manipolazione personale. Nel precedente capitolo abbiamo mostrato che possiamo
personalizzare un tipo di contenuto. Questa personalizzazione può però non portarci molto lontano; per esempio
non possiamo aggiungere nuovi attributi ai nostri tipi di contenuto. E quindi probabilmente vogliamo scrivere un
nostro tipo di contenuto.

323
324 INDICE
Capitolo 13

Capitolo 13: Sviluppare con Archetypes

325
326 CAPITOLO 13. CAPITOLO 13: SVILUPPARE CON ARCHETYPES
Indice

Note alla traduzione del capitolo


built-in: nativo
field: campo
framework: struttura
ovveriding: sovrascrivere
marshaling: ordinare
schema: schema
statement: istruzioni
validations: validatori

Archetypes è un ambiente di lavoro per automatizzare lo sviluppo di prodotti Plone. Una volta scritta una
descrizione per un tipo di contenuto in Python, Archetypes gestisce quasi tutto il resto, incluso la creazione di
viste e la modifica di moduli per lo sviluppatore. Questo permette di sviluppare rapidamente tipi di contenuto
con una minima quantità di codice. E meno codice scritto significa minore probabilità di errori, meno codice da
mantenere ai cambiamenti di Plone, un ciclo di sviluppo rapido, e generalmente costi più bassi.
Poiché l’intero prodotto è basato su questa descrizione di oggetto, permette di utilizzare tools per generare questo
prodotto. Per esempio, ArchGenXML che tratteremo in un secondo tempo, permette di generare un prodotto
in un tool Unifield Modeling Language (UML). Si può poi prendere il risultato del modello UML e passarlo
ad ArchGenXML per avere immediatamente un prodotto da pubblicare in Plone; Non dovete davvero scrivere
nessuna riga di codice. Se avete trovato quello script, il prodotto in Python del capitolo 12, che fosse un piccolo
piacevole ma troppo duro lavoro, allora questo capitolo sara qualche cosa da apprezzare.
Questo non significa che Archetypes è giusto per ogni prodotto; qualche volta abbiamo trovato Archetypes essere
un po’ troppo piccolo. Per esempio, in un caso il nostro tipo di contenuto aveva un campo, ove erano presenti circa
16 diverse permutazioni sui dati di quel campo, che voleva dire poco della struttura esistente di Archetypes usata.
Quell’era un caso estremo, comunque. La maggior parte del tempo troverete che Archetypes è precisamente ciò
di cui avete bisogno.
Molte persone si lagnano del fatto che Archetypes renda la vita un poco troppo facile agli sviluppatori, e chia-
ramente è difficile addebitare molto alle persone per un lavoro che può richiedere dieci minuti. Personalmente
non abbiamo mai avuto un problema per questo, ed Archetypes ci ha tirato fuori da molte situazioni incresciose
allorquando all’improvviso le specifiche sono cambiate da quattro tipi di contenuto a quattordici.
Abbiamo sentito un aneddoto riguardante una società di sviluppo di siti web. Quando la società visita dei clienti,
si porta dietro un programmatore. Quando il client descrive le proprie necessità, il programmatore digita fu-
riosamente attraverso Archetypes. Prima che la riunione sia finita, possono dimostrare un rapido prototipo del
prodotto di lavora al client.

327
328 INDICE

In generale, la maggior parte del team di sviluppo Plone ha adottato Archetypes come via per sviluppare prodotti,
così ha molta parte di mente e realmente è divenuto lo standard per lo sviluppo di Plone. Alcune delle altre
caratteristiche fondamentali di Archetypes sono le seguenti:

• Crea automaticamente le pagine di vista e di modifica, così che non dovete davvero scrivere alcun codice
nella modello di pagina.
• Mantiene un unico Id oggetto. Ogni oggetto creato ha un Id unico che gli utenti non possono cambiare.
Questo vuol dire che potete trovare un oggetto sempre, anche se è stato mosso.
• Crea riferimenti tra gli oggetti. Ogni oggetto può avere qualsiasi numero di relazioni con alcuni altri
oggetti. Per esempio, può avere qualsiasi numero di oggetti collegamento attaccati ad un item di notizie.
• Possiede un’installazione di sicurezza standard. Tutto il lavoro di sicurezza è fatto per voi, così se volete
l’installazione default, non deve cambiare nessuna cosa.
• Ha svariate opzioni di memorizzazione, come conservare i vostri dati in un database relazionale invece che
nel database standard di Zope.
• Ha capacità di trasformazione dei dati, come cambiare, per esempio, Microsoft Word in Hypertext Markup
Language (HTML).

Archetypes non è specifico per Plone ma può essere usato anche con altri framework (strutture) di Zope come
Content Management Framework(CMF); al momento comunque è usato soprattutto da Plone. Eventualmente,
quando Plone migrerà a Zope 3, è progettato che gli schemi di Archetypes e di Zope convergeranno. Usare quindi
Archetypes è un buon modo di rendere . . . (impermeabile al futuro) il vostro prodotto così che sia compatibile
con le future versioni di Plone.
In questo capitolo, tratteremo la costruzione di nuovi tipi di contenuto con Archetypes. In questo capitolo real-
mente collaboreranno insieme tutte le informazioni che avete imparato piuttosto rapidamente negli ultimi capitoli
e corre attraverso dei concetti di base. Dopo avere dimostrato come installare Archetypes, prenderemo attraverso
come creare un tipo di contenuto di base.

13.1 Introduzione a Archetypes


Archetypes viene fornito con l’installer e con pacchetti per Plone, così che avete delle opportunità che abbiate già
installato Archetypes nella vostra distribuzione. Se non siete sicuri che questo sia il caso, dovreste essere capace
di vedere Archetypes nei parte Products del pannello di controllo di ZMI. In questo esempo, abbiamo esaminato
Plone con Archetypes versione 1.2.5-rc4. Se avete installato Archetypes, saltate alla sezione “Sviluppare con
Archetypes”.
Per installare Archetypes, avrete bisogno di andare nel sito web presso http://sf.net/projects/archetypes, cliccate
File e troverete l’ultima distribuzione di Archetypes. Nel nostro esempio, questo è, archetypes-1.2.5-rc4.tgz.
Avrete bisogno di unzip esso, come così:

$ tar -zxf archetypes-1.2.5-rc4.tgz


$ cd archetypes-1.2.5-rc4l

A questo punto avrete bisogno di decidere cosa installare. Il minimo da installare è la directory Archetypes ed il
generatore e moduli di validazione. Per installare questi moduli, muoveteli all’interno della directory Products
della vostra instanza home. Di nuovo, nel nostro caso questo è / var/zope, così che il comando è il seguente:

$ mv Archetypes /var/zope/Products
$ mv generator /var/zope/Products
$ mv validation /var/zope/Products
13.1. INTRODUZIONE A ARCHETYPES 329

ArchExample ed ArchGenXML sono entrambi opzionale, e non avete bisogno di loro per lavorare in Plone;
comunque, li trattiamo entrambi come esempi in questo capitolo, così vorrete probabilmente installarli.
Per installare ArchExample, muovete il prodotto ArchExample all’interno della directory Products della vostra
instanza home, come così:

$ cd ..
$ mv ArchExample /var/zope/Products

Se volete usare ArchGenXML, non avete bisogno di installarlo in un luogo particolare, così lo potete porre in
qualsiasi directory ove non lo dimenticherete. Solitamente lo posizioniamo assieme nella directory Products
della nostra istanza home. Non fa danno, e non lo dimentichiamo. Per esempio:

$ mv ArchGenXML /var/zope/Products

Come affermato nella documentazione di ArchGenXML, ArchGenXML richiede l’installazione PyXML. Di


nuovo, se usate un installer Windows od un installer Mac, questo viene già incluso. Se non, allora andate presso
http://pyxml.sf.net e scaricate il pacchetto. Nel nostro caso, l’ultimo pacchetto disponibile era 0.8.3, così dopo
averlo scaricato, eseguimo il seguente:

$ tar -xvf PyXML-0.8.3.tar.gz


$ cd PyXML-0.8.3
$ python setup.py install

Nota
Solitamente, l’installazione eseguita in questo modo richiede su Unix i diritti di root per
installare nella cartella Python.

Ora che avete settato tutto ed installò, vedremo alcuni esempi.

13.1.1 Tuffarsi in Archetypes


Un intero gruppo di grandi esempi è disponibile per Archetypes, così piuttosto che costruirne uno per il libro, mo-
striamo ArchExample, che viene fornito con l’installazione di Archetypes. Questo aggiunge un tipo di contenuto
chiamato article che fornisce un esempio grezzo della potenza di Archetypes.
Article.py contiene il codice del prodotto principale. Vedete che il codice sembra piuttosto diverso dagli esempi
precedenti. Contiene schema

StringField("blurb",
searchable = 1,
widget = TextAreaWidget(),
),

Questo pezzo di codice denota che avete un attributo sul tipo di contenuto chiamato fascetta (blurb), che è una
stringa, e verrà mostrata come una text area HTML. Discuto tutte le opzioni per campi e widgets in un momento.
Per ora, diamo un sguardo al tipo di contenuto Plone. In figura 13-1, abbiamo aggiunto tipo di contenuto blurb.
Con solo queste quattro linee di codice, avete aggiunto un campo al vostro tipo di contenuto. Gli elementi del
modulo standard che si aspetterebbe Plone sono presenti; se modificate qualche cosa e ritornate in un secondo
tempo, il vecchio valore è mostrato, gli errori sono tattati con eleganza, e così via. Come dimostrazione di come
sia facile modificare, cambiate l’etichetta nel modulo per visualizzarlo come Article Blurb, e cambiate il campo
per essere richiesto. Per fare questo, fate le seguenti modifiche:
330 INDICE

Figura 13.1: Figura 13-1. La parte di blurb del tipo di contenuto


13.1. INTRODUZIONE A ARCHETYPES 331

StringField("blurb",
required = 1,
searchable = 1,
widget = TextAreaWidget(label="Article Blurb"
),

Qui avete aggiunto il parametro required = 1 che rende questo campo obbligatorio, ed un parametro all’etichetta.
Se riavviate Plone ed aggiunge un nuovo article, l’interfaccia utente è ora cambiata per riflettere il nuovo schema.
Il campo è ora chiamato Artiche Blurb.

Figura 13.2: Figura 13-2. La parte del tipo di contenuto di Article Blurb

Questo non è solamente un cambio estetico; il cambio riflette la modifica dello schema fondamentale, e questa è
la vera potenza di Archetypes. Solamente comparando questo con lo scrivere prodotti in Python, potete vedere
che tutto il lavoro faticoso dallo scrivere un prodotto è stato rimosso. È come questo: se si può definire un
schema, poter mettere insieme completamente un archetipo è assolutamente immediato. Una volta che avete
fatto, potete modificarlo facilmente e potete vedere le modifiche prendere effetto.
Se fate qualsiasi di queste modifiche per provare gli esempi seguenti, dovrete riavviare Plone. Solamente allora
tutti i nuovi cambiamenti saranno caricati e propriamente registrate. Per ulteriori informazioni su questo, vedete
successivamente la sezione “Sviluppare con Archetypes” in questo capitolo.

13.1.2 Spiegare Schema, Campi e Widgets


La definizione fornita dal dizionario di Merriam-Webster di schema è la seguente:
schema:
Nel linguaggio Archetypes, un schema
<manca qualcosa - Ugo >
Ogni campo ha un widget definito. Un widget
Figura 13-3 Mostra la relazione tra schema, campi, e widgets.

Schema ed il BaseSchema

Per creare un schema, passate i campi che desiderate nell’oggetto schema come un tuple di campi. Per esempio,
lo schema dell’article ha tre campi: group, blurb, e body. Il seguente codice avvia lo schema:

Schema((
StringField(’group’,
vocabulary=ARTICLE_GROUPS,
widget=SelectionWidget(),
332 INDICE

Figura 13.3: Figura 13-3. La relazione tra schema, campi, e widgets


13.1. INTRODUZIONE A ARCHETYPES 333

),
# other fields here
)

È possibile aggiungere schema per trovare una sommatoria di più di uno schema. Questo è precisamente quel-
lo che fa davvero ArchExample: aggiunge gli schemi definiti nel tipo di contenuto ad un schema chiamati
BaseSchema.
Il BaseSchema contiene due elementi che ogni tipo di contenuto di Plone dovrebbe avere, un titolo (title) ed un
Id. Il titolo è richiesto così che qualche cosa possa essere visualizzata nell’interfaccia utente, e lo Id, o in breve
nome, corrispondete alle convenzioni standard di Plone per un schema chiamante. I due schema sono aggiunti
semplicemente per creare un schema più grande. In ArchExample, per fa questo aggiungete lo schema per il tipo
di contenuto al BaseSchema già esistente. Per esempio:

schema = BaseSchema + Schema((


StringField(’group’,
vocabulary=ARTICLE_GROUPS,
widget=SelectionWidget(),
),
...

E’ chiaro che gli items sono restituiti dalla query dello schema nell’ordine con cui sono aggiunti allo schema.
Questo vuol dire che potete riordinare l’ordine degli elementi che appaiono nell’interfaccia utente solamente
muovendo i campi all’interno dello schema. Ecco anche perché il BaseSchema è aggiunto all’inizio così che lo
Id ed il campo titolo appariranno in cima alla vista e della pagina di modifica, piuttosto che al fondo.

Campi

Quindi avete visto che il campo StringField è un campo comune che rappresenta una stringa nel vostro tipo di
contenuto. Un numero di campi è disponibile in Archetypes, come descritto in tabella 13-1. Con il tempo, più
campi sono aggiunti, e se avete bisogno, è possibile creare il vostro proprio.
Ogni campo ha un widget di default che verrà usato, a meno che ne specificate uno. Nell’esempio precedente
blurb, specificamo un TextAreaWidget. (Widget sono trattati nella prossima sezione.) Tutti questi campi sono
importati dal modulo pubblico di Archetypes; per esempio:

from Products.Archetypes.public import BooleanField

Tutti i campi sono instanziati allo stesso modo – creando un campo e passando nell’unico parametro richiesto per
il campo: name. Potete passare opzionalmente qualsiasi numeri di parametri fondamentali secondo necessità.
Per esempio:

from Products.Archetypes.public import IntegerField


# a simple field for age
age = IntegerField(’age’)

Tabella 13.1: Tabella 13-1. I campi ottenibili in Archetypes

Nome Tipo Default Descrizione


Widget
BooleanField Boolean ComputedWidget
Simple storage of true or false for a field.
values
334 INDICE

Tabella 13.1: Tabella 13-1. I campi ottenibili in Archetypes

Nome Tipo Default Descrizione


Widget
DateTimeFieldDate CalendarWidget
For storing dates and times.
and time
objects
FileField Files FileWidget Storage for large chunks of data such as plain-text files, Microsoft Word
documents, and so on.
FixedPointField
Fixed- DecimalWidget
For storing numerical data with fixed points.
point
numbers
FloatField Floats DecimalWidgetFor storing numerical data with floating points.
ImageField Image ImageWidget Stores an image and allows dynamic resizing of the image.
IntegerField Integer StringWidget For storing numerical data as integers.
LinesField Lists LinesWidget A list of data such as keywords.
PhotoField Image PhotoWidget Same as an image field but has more default image sizes.
ReferenceFieldReference ReferenceWidget
Contains a reference between this object and another.
StringField String StringWidget A string field optimized for smaller strings—say, fewer than 100 words.
TextField String TextWidget A string field optimized for larger strings—say, larger than 100 words.
The string can also be transformed into multiple formats.

Ciascuno dei campi hanno attributi che possono essere assegnati al campo. Già ne avete visto almeno due: il
name e l’attributo widget. L’attributo name è l’unico parametro richiesto ad un campo e dovrà essere unico,
minuscolo, e senza spazi o punti. L’attributo name verrà usato solamente all’interno, conficcarsi cosi che questa
regola chiamate sia importante. Tutti gli altri valori sono opzionali. Tabella 13-2 descrivono gli attributi.

Tabella 13.2: Tabella 13-2. Gli attributi dei Campi

Nome Descrizione Possibile Valore


accessorThe name of the method to get the value of the field, See the ’Overriding Default Methods” section
so you could change how this field is retrieved Any later in this chapter.
method name (for example, specialGetMethod)
default The default value for the field. Should be appropriate to the field.
default_method
A string for obtaining a value for the field; one is Any string (for example, getSpecialDescrip-
created for you by default if you don’t define one. tion). See the ’Overriding Default Methods”
section later in this chapter.
edit_accessor
The name of a method to get the raw value of a field. Any method name (for example, rawGetMe-
thod). See the ’Overriding Default Methods”
section later in this chapter.
enforceVocabulary
If enabled, you won’t accept anything outside the True or False.
vocabulary.
index If you want this field to be placed in its own catalog The name of any index, such as KeywordIndex
index, then specify the type of index here as a string. or KeywordIndex:schema.
If you append :schema onto the end of the schema,
then this will also be added as a metadata column.
13.1. INTRODUZIONE A ARCHETYPES 335

name A unique name for this field. Any string, lowercase conforming to standard
Python variable rules (for example, description,
user_name, or coffee_bag_6).
mode The read and write mode of field, as a string; the For read only: r, for write only: w, for read and
default is to be read and write. write: rw.
multiValued
If this field can have multiple values, this is useful for True or False.
things such as drop-down lists.
mutatorThe name of the method to alter the value of the field, Any method name (for example, specialSetMe-
so you could change how this field is set. thod). See ’Overriding Default Methods” later
in this chapter.
primaryIf True on a field, then this will be the field that re- True or False.
sponds to File Transfer Protocol (FTP) and WebDAV
requests. There can be only field that does this; if
multiple are defined, the first one in the schema will
be used. You normally do this for the main body
attribute.
requiredSpecifies that some value for this field required. True or False.
schemataPlace the field into the grouping of other fields called
schematas
default
metadata
user_information
searchable
A boolean that specifies if this field will be added to True or False.
the searchable text and can be used in the searches.
validators
The validations that will be performed on the field as Any validator; see the ’Validations of Input”
a tuple of strings; it starts at first and validates against section later.
each validation.
vocabulary
A list of values that a user can choose from, for List of strings (for example, [“Green”, “Red”,
example, the values to show in a drop-down list. “Blue”]).
storage Where to store the value; the default is Attribute Sto- Any valid storage object such as AttributeSto-
rage, which stores the field as an attribute of the rage or SQLStorage. You can find these in the
object. Archetypes Application Programming Interface
(API). For more information, see the ’Storing
Your Content in a SQL Database” section later
in this database.
widget The widget that will be used to display this field. Any widget object.

Ora che abbiamo trattato i campi di default e gli attributi, è ora di muoversi sopra l’attuale widgets che sia
disponibile.

Widgets

Un widget contiene le informazioni di come l’oggetto verrà rappresentato visivamente. La vista di un attributo
visualizzato è spesso riferita da vicino al tipo dell’attributo; comunque, avete opzioni per visaulizzare – una
stringa può essere selezionata in molti modi. Dato il set di widgets, l’oggetto widget può essere pressocché
qualsiasi cosa. Potete importare qualsiasi widgets dal modulo * pubblico* di Archetypes. Per esempio:

from Products.Archetypes.public import BooleanWidget


336 INDICE

Tutti i widgets sono instanziati allo stesso modo – creando un widget e passando in parametri fondamentali come
necessita. Per esempio:

from Products.Archetypes.public import IntegerField


from Products.Archetypes.public import IntegerWidget
# a simple field for age
age = IntegerField(’age’,
widget=IntegerWidget(label="Your age")
)

Widgets può avere anche attributi extra, dipendendo dal tipo di widget. In molti casi, questi attributi addizionali
corrispondono direttamente agli attributi HTML; per esempio, su un StringWidget potete mettere un attributo
size. Questo produrrà l’adatto widget HTML con settato l’attributo size HTML. Cosi che per avere un input che
sia grande 20 caratteri, dovete creare il seguente widget:

bankAccountNumber = StringField(’bank’,
widget=StringWidget(
label="Bank account number",
size=20)
)

La tabella 13-3 descrive di tutti i widgets disponibili in Archetypes.

Tabella 13.3: Tabella 13-3. I Widgets disponibili

Nome Descrizione Altri Attributi


BooleanWidget
Shows two checkboxes for the possible values. --
CalendarWidget
Returns a set of input boxes with a link to a helper --
pop-up box so that a user can select a date.
ComputedWidget
Returns the computed value as HTML. --
DecimalWidget
A simple HTML input box for a string. size.
EpozWidgetAn HTML Epoz widget that shows the Epoz rich- You can provide format, rows, mode, and cols
text editor for the content. (for columns).
FileWidgetDisplays an HTML file element for users to upload --
files.
IdWidget A simple HTML input box that’s used for rendering --
autogenerated IDs.
ImageWidget
Shows and allows the editing of images. You can provide a display_threshold that al-
lows you to set the size of an image; if it’s
below this size, the image will display in the
Web page.
IntegerWidget
A simple HTML input box for a string. size.
KeywordWidget
This displays a list of keywords from the catalog --
in a complicated widget, such as the one in the
Properties tab on a normal object.
LabelWidgets
Used to display labels on forms; no values or form --
elements.
LinesWidget
Displays a text area that users can enter values. rows and columns.
MultiSelectionWidget
A selection widget; by default it’s an HTML select format, which can be one of select or
widget. checkbox.
13.1. INTRODUZIONE A ARCHETYPES 337

Tabella 13.3: Tabella 13-3. I Widgets disponibili

Nome Descrizione Altri Attributi


PasswordWidget
An HTML password element. --
RichWidgetAllows the input of a file in multiple formats that are You can provide rows, cols *(columns), and
then transformed. See ’Transforming Data,” later in *format.
this chapter for more information.
ReferenceWidget
Shows an HTML select element of a list of possible --
references.
SelectionWidget
Shows a selection widget. If it’s flex (the default), format, which can be one of flex, select, or
then if the number of choices is more than four, a radio.
select element is used; otherwise a radio button is
used.
StringWidget
A simple HTML input box for a string size and maxlength.
TextAreaWidget
A text area widget that allows the uploading of the You can provide allowed_content_types, whi-
content in multiple formats ch is a list of string; each string represents a
meta_type of the type of content uploaded.

Per ciascun widgets elencato in tabella 13-3, la tabella 13-4 descrive tutti gli attributi che sono comuni ad ogni
widgets. Avete già visto l’attributo label che sette la descrizione sul vostro widget. In congiunzione con gli
attributi extra per ciascun widget, avete un set completo di attributi dei widget.

Tabella 13.4: Tabella 13-4. Valori possibili per i Widgets

Descrizione Valori possibili


No-
me
label The label that will appear in the user interface with this field. Any string, for example, Start Date
for a field start_date.
modesThe modes that this widget will be shown in; by default there are A list of modes as strings; by
two modes: view and edit. default it’s (“view”, “edit”).
populate
If this is enabled, the view and edit fields will be populated. Usually True or False
this enabled, but for fields such as a password field, this shouldn’t
be the case. Usually this is true by default.
postback
If this is enabled, then when an error is raised, the field is repopu- True or False
lated; for fields such as a password field, this shouldn’t be the case.
Usually this is true by default.
visibleIf the attribute should be visible in the user interface. This is a dic- For example, {’view’: ’visible’, ’e-
tionary mapping the view mode to a string, describing the visibility. dit’: ’hidden’ } means that the
Choices are visible, hidden (shown in an HTML hidden form value), view will show, but the edit page
invisible (not shown at all). will hide the value.

13.1.3 Alcuni esempi di combinazione di campi e di widget


Questa sezione contiene alcune combinazioni utili che sembrano essere usate comunemente e che potete trovare
utili come esempi. Per questo esempio, creiamo un casella a discesa della vostra frutta preferita. Definiremo
l’attributo vocabulary come un lista di stringhe. Ognuno dei valori della lista è una stringa del tipo fruit; per
338 INDICE

cui, il tipo di campo è un StringField. Poiché stiamo definendo il widget come un SelectionWidget, si presenterà
come un casella a discesa, così come:

StringField(’fruit’
vocabulary = ["Apple", "Orange", "Mano", "Banana"],
widget = SelectionWidget(label = "Favourite Fruit")
)

La ImageField è utile per creare e mantenere immagini in un sito Plone. Per avere un bel semplice campo dove
gli utenti possono caricare [upload] immagini, usiamo il seguente:

ImageField(’portrait’,
widget = ImageWidget(label = "My picture"),
)

Il tipo seguente è un tipo veramente complicato di contenuto. La maggior parte dei contenuti digitati possiedono
un campo principale che può ricevere dati. Se pensate al tipo di documento di base, osserverete un campo corpo
(body) ove digitate e modificate. Questo unico campo body è il testo principale del tipo di contenuto. Quindi per
questo campo standard, avete solamente alcuni attributi che dovranno essere aggiunti.
Per primo, desiderate che questo campo sia ricercabile, così dovete impostare l’attributo searchable. Succes-
sivamente, vorrete che questo campo risponda alle richieste FTP e WebDAV, così dovete impostare l’attributo
primary (potete trovare ulteriori informazioni su questo nel sidebar “Il campo primary: Ordinare e Rispondere a
FTP e WebDAV”). Desiderate che siano caricati [upload] molteplici tipi di contenuto, così, per questa ragione,
settate * allowable_content_types*. Avete bisogno di sapere chiaramente, poi, come visualizzare il campo, così,
per questo ponete * default_output_type*. Tutto questo allora fornisce il campo seguente:

TextField(’body’
searchable = 1,
primary = 1,
default_output_types = ’text/html’,
allowable_content_types = (’text/plain’,
’text/structured’,
’text/restructured’,
’text/html’),
widget = RichWidget(label = ’Body’),
)

Il campo primary: Ordinare (Marshaling) e Rispondere a FTP e WebDAV

Plone è un sistema orientato agli oggetti dove un oggetto possiede molti attributi e non può essere rappresentato
semplicemente come un file in chiaro [plain]. Sfortunatamente, molti dei protocolli esistenti come FTP e Web-
DAV trattano contenuto precisamente in questo modo. Avete bisogno quindi là di qualche strada per tradurre fra
i due, e il campo primary fa questo. Avendo settato il campo primary su un oggetto, questo campo diverrà l’unico
che spedisce e riceve da questi protocolli – piuttosto che l’oggetto intero.
Questa è una soluzione imperfetta ad un problema ingannevole, chiaramente. Se avete usato FTP o External
Editor su un file, saprete che tenta di risolvere questo posizionandoun numero di linee in cima alla pagina che
contengono chiavi/valori per i metadata sull’oggetto. Questo è un altro tentativo di risolvere lo stesso problema.
Per impostare il campo primary marshaling, abbiamo bisogno di aggiungere il seguente al vostro schema: mar-
shall=some_marshaller (). Ci sono attualmente, solamente due marshalers: un PrimaryFieldMarshaller che
prende l’intero contenuto e lo posiziona all’interno del vostro oggetto ed un RFC822Marshaller. Questo secon-
do marshaler si occupa del contenuto per il campo name/value come usato nella posta elettronica. Per gli scopi
di questo capitolo, useremo il PrimaryFieldMarshaller per occuparci del contenuto con External Editor.
13.2. VALIDARE UN INPUT 339

13.2 Validare un Input


Sebbene i moduli si occupino del contenuto e degli errori di base, cosi come ommettere il contenuto, piuttosto
bene, probabilmente vorrete avere una gestione degli errori più sofisticata. Potete fare una serie di validazioni
per esaminare che il contenuto nel vostro tipo di contenuto sia corretto. Per esempio, se avete un campo numero
intero, vorrete probabilmente controllare che i dati che sono stati aggiunti siano quello che si è voluto dire di
essere.
Potete aggiungere un parametro di validazione al campo per fare ciò. Per controllare che il vostro IntegerField
sia un numero intero, per esempio, in realtà farete questo:

from Products.Archetypes.public import IntegerField


from Products.Archetypes.public import IntegerWidget
# a simple field for age
age = IntegerField(’age’,
validators=("isInt"),
widget=IntegerWidget(label="Your age")
)

Da dove viene isInt? Bene, isInt è il nome di un validatore registrato nella struttura di validazione. Sola-
mente alcuni sono là, ma sono piuttosto utili; la tabella 13-5 li descrive. Per i dettagli esatti di ciascuno
di essii, raccomandiamo di leggere il codice e guardare all’expressione regolare – potete trovarli nel modulo
validation/validators/__init__.py della vostra directory Products:

Tabella 13.5: Table 13-5. Validatori disponibili

Name Description
isDecimal This validates that the string is a decimal, including positive and negative,
exponentials, and so on.
isInt This validates that it’s an integer.
isPrintable This validates that this is a letter or a number.
isSSN This validates that it’s nine numbers (the length of a U.S. Social Security number).
isUSPhoneNumber This validates that it’s ten numbers and is optional.
isInternationalPhoneNumber
This validates that it’s at least one number and is optional.
isZipCode This validates that it’s five or nine numbers.
isURL This validates that the input starts with http://, ftp://, or https://.
isEmail This validates that this conforms to the standard e-mail syntax.

Potete registrare anche le vostre proprie validazioni. Un Validatore di fatto è una semplice classe che implementa
l’interfaccia ivalidator. Due sono sempre fatte: un RegexValidator che verifica un’espressione regolare ed un
RangeValidator che verifica una serie di valori. Per registrare un nuovo validatore che controlli che un utente ab-
bia un’età compresa fra 0 e 150 anni (sembra ragionevole), aggiungerete ciò che segue al vostro tipo di contenuto
nel modulo Python, prima di creare il campo:

from validation.validators.validator import RangeValidator


from validation import validation

# the RangeValidator takes a name for the validator


# and a start and end value
validAge = RangeValidator("validAge", 0, 150)
validation.register(validAge)
340 INDICE

Poi potete cambiare il vostro validatore al seguente:

validators=("isInt","validAge"),

Per primo, il codice verificherà che abbiate un numero intero valido; successivamente, controllerà che il numero
intero sia all’interno dell’intervallo di età ragionevole. Se volete aggiungere un Validatore totalmente nuovo che
esegua qualche cosa di diverso di un’espressione regolare o della validazione di serie, avrete bisogno di aggiun-
gere un nuovo sistema di validazione. Per questo esempio, create una validazione che una data sia compresa
fra due valori. Nell’esempio seguente, questo è chiamato DateRangeValidator e restituirà un valore di booleano
se la data fornita è compresa tra due date date. Questo potrete essere utile per affermare che una vacanza sia
all’interno delle vacanze scolastiche.
Quindi, ora definite un nuovo validatore chiamato DateRangeValidator nel modulo validators. Questo permette
di registrare lìintervallo delle date per affermare che la data richiesta cada nel mezzo. Userete, per fare ciò,
l’oggetto Zope DateTime (che verrà trattato più in dettaglio Nell’Appendice A). Un validatore è semplicemente
- è una classe che ha un nome e che risponde al metodo __call__ * di controllo della data. Ciò che segue è la
classe *DateRangeValidator , che è stata aggiunta al modulo validator:

from DateTime import DateTime

class DateRangeValidator:
__implements__ = (ivalidator,)

def __init__(self, name):


self.name = name

def __call__(self, value, *args, **kwargs):


min, max = args[:2]
if not isinstance(value, DateTime):
value = DateTime(value)

return min < value and value < max

Dopo riavviate Zope, ora potete registrare una nuova validazione, come:

from validation.validators.validator import DateRangeValidator


from validation import validation
from DateTime import DateTime

christmas = DateRangeValidator("ChristmasHolidays",
DateTime(’12/18/2004’),
DateTime(’01/09/2005’),)
validation.register(christmas)

Infine potete creare un validazione nel vostro schema nella seguente maniera:

validators=("christmas",)

13.2.1 Sovrascrivere [Overrindig] Viste ed Actions nella classe Base


Archetypes crea viste predefinite ed azioni basate su un set standard di requisiti che vanno bene per molte ne-
cessità. Le azioni sono vedere, modificare, e le proprietà, chiaramente; i riferimenti sono un’altra azione che
13.2. VALIDARE UN INPUT 341

guarderà a lui un momento. Non trovete i modelli di pagina dell’oggetto per vista od edita; questi sono generati
automaticamente da Archetypes. Comunque, potete modificarli.
Ci aspettiamo che in molti casi vorrete avere la priorità sul metodo vista e di offrirne uno proprio vostro; Di
default è base e non è mirata all’inizio una pagina perfetta (chiaramente, essendo una pagina Plone, è migliore
del vostro sistema di gestione dei contenuti medio). Comunque, potete avere specifiche necessità che fanno
riferimento al contenuto; forse è una questione di presentare il vostro contenuto in un certo modo.
Archetypes di fatto crea una classe per ogni tipo di contenuto. Molto nello stesso modo in cui avete creato
una classe per il tipo di codice sorgente nel capitolo precedente, potete creare una classe base per il vostro
archetipo. Questa classe base è stata chiamata BaseContent ed è disponibile nel modulo public di Archetypes
per l’importazione. Questa classe BaseContent definisce ogni cosa di cui Archetypes ha bisogno di conoscere.
Realizzando questa classe vi viene offerta un’opportunità di avere la priorità pressocché su qualsiasi cosa che
desiderate nella classe.
Come ora mostriamo, ci sono due parti per questo. Prima, create un’azione che verrà usata dalle informazioni di
tipo di fabbrica [factory]; in Archetypes fate questo assegnando l’attributo action della classe. Per esempio:

from Products.Archetypes.public import BaseContent

class Article(BaseContent):
# other stuff
actions = ({ ’id’: ’view’,
’name’: ’View’,
’action’: ’string:${object_url}/article_view’,
’permissions’: (CMFCorePermissions.View,)
},)

Secondo, avete bisogno di creare un modello di pagina, chiamato article_view, per la vista attuale dell’oggetto.
Questa stringa definisce un modello di pagina che il tipo di contenuto localizzerà nello skin per questo prodotto.
In questo caso, troverà il modello di pagina corrispondente nel File System nella directory dello skin/archexample
di ArchExample. Potete trovare anche una copia di questo modello di pagina nell’Appendice B. Questo può
essere un semplice o un complicato un modello di pagina come desiderate.
Per prendere efficacia, dovete ravviave Plone per le modifiche. In questo caso, state modificando un’azione
installata all’interno del tool portal_types allorquando il prodotto è stato installata. Per questa ragione, se cam-
biamente questa azione, avrete bisogno di reinstallare il prodotto. Per fare questo nell’interfaccia Plone, cliccate
Plone setup.
Tutti gli elementi nel tipo d’informazione di factory possono essere soprascritte [overriden] creando un attri-
buto di quel nome sull’oggetto. Per sovrascrivere content_icon create un attributo chiamato content_item. Per
esempio:

class SomeProduct(BaseContent):
""" Some product """
content_icon = "some_icon.gif"

13.2.2 Sovrascrivere i metodi di Default


Nella Tabella 13-2, abbiamo menzionato la possibilità di sovrascrivere alcuni metodi di default che occorrono
sui tipi di contenuto, come accessor e mutator. Questa è un opzione avanzata che permette la manipolazione dei
campi al momento della modifica (da rivedere).
Giusto come il progetto open source dell’ultimo capitolo, potete accedere a questi attributi od a questi campi
usando i mediti accessors e mutator. Alcuni metodi default sono disponibili. Se il vostro nome del campo è
blurb, allora questi metodi saranno getBlurb e setBlurb. Il termine get <manca qualcosa – Ugo >
342 INDICE

Comunque, potete volere fare qualche cosa di diverso in accessor o mutator. Supponete di voller filtrare il valore
di un campo, come correggere sempre l’ortografia del nome della vostra società o cambiare il valore di alcune
altri campi quando un certo compo viene modifica. Allora potete fare così avendo la possibilità di sovrascrivere
i metodi predefiniti. Nell’esempio seguente, realizzerete un nuovo metodo chiamato getSpecialBlurb che prende
il blurb che qualcuno ha digitato e lo manipolerete prima di ritornarlo al client. In questo caso, state sostituendo
il testo Perl
getSpecialBlurb Article

class Article(BaseContent):

def getSpecialBlurb(self):
""" The view for an article """
blurb = self.getField(’blurb’).get(self)
blurb = blurb.replace(’Perl’, ’Python’)
return blurb

Avrete bisogno di modificare anche il vostro campo così che usi questo metodo:

StringField(’blurb’,
searchable=1,
widget=TextAreaWidget(),
accessor="getSpecialBlurb",
),

In questo esempio, in qualsiasi momento che il campo blurb ha accesso, per esempio, ad una pagina di vista o di
modifica viene restituito il valore di getSpecialBlurb. Archetypes conosce l’accesso al metodo poiché il nome del
metodo è definito come un valore stringa passato al parametro accessor. C’è un bit di frode voluta – per accedere
al valore crudo dell’attributo, avete bisogno di trovare il campo e poi invocare il metodo get. Questo è una linea
piuttosto confusa blurb=self.getField (’blurb’). get(self). Il pattern getting il campo e quindi (ri)chiamare un
metodo su lui è davvero piuttosto comune in Archetypes [da rivedere. . . ndt].
L’esito pratico di questo ora è che, non vi è nessuna questione quando o come una persona digiti la parola Perl

13.2.3 Mettere insieme il resto del tipo di contenuto


Ora abbiamo trattato tutti gli elementi principali del tipo di contenuto. Il listato 13-1 mostra tutto insieme il
codice. Noterete che il resto del codice è più compatto del prodotto Python perché Archetypes lavora così molto
per voi.

Listato 13-1. Article.py

from Products.ArchExample.config import ARTICLE_GROUPS


from Products.Archetypes.public import BaseSchema, Schema
from Products.Archetypes.public import StringField, TextField
from Products.Archetypes.public import SelectionWidget, TextAreaWidget
from Products.Archetypes.public import RichWidget
from Products.Archetypes.public import BaseContent, registerType
from Products.Archetypes.Marshall import PrimaryFieldMarshaller
from Products.CMFCore import CMFCorePermissions
from config import PROJECTNAME

schema = BaseSchema + Schema((


13.2. VALIDARE UN INPUT 343

StringField(’group’,
vocabulary=ARTICLE_GROUPS,
widget=SelectionWidget(),
),
StringField(’blurb’,
searchable=1,
widget=TextAreaWidget(),
),
TextField(’body’,
searchable=1,
required=1,
primary=1,
default_output_type=’text/html’,
allowable_content_types=(’text/plain’,
’text/structured’,
’text/restructured’,
’text/html’,
’application/msword’),
widget=RichWidget(label=’Body’),
),
),
marshall=PrimaryFieldMarshaller(),
)

class Article(BaseContent):
"""This is a sample article; it has an overridden view for show,
but this is purely optional
"""

schema = schema

actions = ({
’id’: ’view’,
’name’: ’View’,
’action’: ’string:${object_url}/article_view’,
’permissions’: (CMFCorePermissions.View,)
},)

registerType(Article, PROJECTNAME)

A parte un gruppo di importazioni in alto e lo schema, abbiamo trattato tutti i contenuti di questo codice, con
un’eccezione: registerType. Questa funzione registra il vostro oggetto con il prodotto. Ciascun prodotto può
avere moltiplici tipi di contenuto, così questa funzione prende l’oggetto ed il nome del progetto. In questo caso,
il nome del progetto è importato dal file di configurazione, come visto precedentemente. Il file di configurazione,
config.py contiene variabili similari per la configurazione del prodotto, come mostrato nel listato 13-2.

Listato 13-2. Il file di configurazione di ArchExample

from Products.CMFCore.CMFCorePermissions import AddPortalContent


from Products.Archetypes.public import DisplayList

ADD_CONTENT_PERMISSION = AddPortalContent
344 INDICE

PROJECTNAME = "ArchExample"
SKINS_DIR = ’skins’

GLOBALS = globals()

ARTICLE_GROUPS = DisplayList((
(’headline’, ’Headline’),
(’bulletin’, ’Special Bulletin’),
(’column’, ’Weekly Column’),
(’editorial’, ’Editorial’),
(’release’, ’Press Release’),
))

La variabile ARTICLE_GROUPS è un tuple di un tuple di stringhe per usarla nel group widget. Potrete usare solo
una semplice tuple di stringhe, ma in questo caso l’esempio sta usando la classe DisplayList che è un’occassione
di mostrare un diverso valore all’utente da quello che sarà messo nel modulo. In questo caso, lo HTML per
ArticleGroups è visualizzato in un elemento HTML scelto, come così:

<option value="headline">Headline</option>
<option value="bulletin">Special Bulletin</option>
...

Un altra intuizione insolita è l’uso della funzione globals - che è una funzione nativa [built-in] di Python, che
contiene tutti i simboli globali. Questo calcola il path della directory dello skin nel File System così che possiate
costruire una vista delle directory del File System dello skin per il tool skin. La funzione di inizializzazione del
prodotto, __init__.py è anche molto più semplice. Con una nuova inclusione, il processo e la lista delle funzioni
tipo sembrano questi:

from Products.Archetypes.public import process_types, listTypes


content_types, constructors, ftis = process_types(
listTypes(PROJECTNAME),
PROJECTNAME)

La funzione listTypes è un’utilità di Archetypes che restituirà tutti i tipi che prima avete registrato. Questi quindi
verranno passati alla funzione process_types che a turno ritorna tutti i tipi di contenuto, i costruttori, e gli oggetti
tipo factory information. Questi sono tutti gli stessi items che avete registrato nel prodotto Python; è solo che
questa funzione di utilità rende tutto un pò più facile.
Finalmente, avete la funzione di installazione nel Extensions install.py. Questo script è ora imbarazzantemente
piccolo perché di tutto il lavoro che avete fatto prima si sono occupati due funzioni di utilità, installTypes ed
install_subskin. Il termine subskin <manca qualcosa – Ugo >

Listato 13-3. Script d’installazione

from Products.Archetypes.public import listTypes


from Products.Archetypes.Extensions.utils import installTypes,
install_subskin
from Products.ArchExample.config import PROJECTNAME, GLOBALS

from StringIO import StringIO

def install(self):
out = StringIO()
13.3. SVILUPPARE CON ARCHETYPES 345

installTypes(self, out, listTypes(PROJECTNAME), PROJECTNAME)


install_subskin(self, out, GLOBALS)
out.write("Successfully installed %s." % PROJECTNAME)
return out.getvalue()

La versione completa di ArchExample è disponibile nel sito web del Plone Book presso http://Plone-book.agmweb.ca,
e dovreste essere capace di lasciar cadere questo e di eseguirlo sul vostro sito. Come avete visto, questo tipo di
contenuto è rapido e facile da sviluppare ed è facile da modificare, senza dovere scrivere molto codice.

13.3 Sviluppare con Archetypes


Questa sezione fornisce ulteriore approfondimentio su alcune delle caratteristiche più avanzate di Archetypes.
Queste caratteristiche offrono dei tools utili per lo sviluppo dei vostro tipi di contenuto. Questo includerà la
creazione di riferimenti, di nuovi widgets, e la trasformazione del contenuto.
Per questo capitolo, è importante conoscere come le modifiche che farete possono essere portati attraverso Plone.
Come avete visto precedentemente, avete differenti scenari per il setup del vostro prodotto. Quando effettuate
una modifica al vostro prodotto, aiuta conoscere i passi necessari da fare.
Se cambiate qualche cosa in uno skin, giusto eseguendolo in modalità debug vi assicura che le modifiche sono
propagati. Se cambiate qualche cosa che passa sul tool portal_actions come azioni od icone, allora avete bisogno
di riavviare Plone e di reinstallare il prodotto attraverso Add/Remove Products.
Se cambiate uno schema, allora avete proprio bisogno di riavviare Plone, e tutti le nuove instanze della vostra
classe saranno aggiornate in Plone. Comunque, questo riguarda tutte le vecchie instanze del prodotto? Fortunata-
mente, Archetypes ha previsto un tool di aggiornamento dinamico che naviga attraverso tutte le vecchie instanze
del vostro prodotto e li aggiorna al nuovo schema. Nella ZMI, cliccate archetype_tool

13.3.1 Usare Id unici


Il concetto di Id unico è semplice ma è qualche cosa che è stato perso in Zope. Originalmente gli sviluppatori
di Zope hanno presupposto di utilizzare il percorso ad un oggetto; sfortunatamente, questo ha mostrato di essere
inadeguato. Come semplice esempio, si consideri quello che succede quando qualcuno cambia l’ubicazione di
un documento – il vostro unico riferimento a quel documento è stato perso. Un Id unico è un tool veramente
utile da avere. Archetypes crea un Id unico su ogni oggetto creato e lo salva nell’oggetto. Lo salva anche in un
catalogo separato chiamato uid_catalog.
Potete vedere uid_catalog nella ZMI, ed è come l’oggetto di portal_catalog eccetto che ommette un piccolo pezzo
di extra Application Programming Interface (API) avvolto e tutti gli indici che il primo contiene. È abbastanza
semplice ora da ottenere un oggetto passando attraverso questo catalogo. Tutto ciò che dovete fare è ricercare
nel catalogo il vostro oggetto. Per esempio, il seguente oggetto script (Python) può tirare qualsiasi l’oggetto
registrato, se conoscete il relativo UID:

##paramaters=objectId
results = context.uid_catalog(UID=objectId)
return results[0].getObject()

Ma dove è realmente utile è nei riferimenti fra oggetti esistenti. Dite che cercate di riferirvi ad una o più immagini
separate con vostro articolo. Queste immagini possono essere immagini caricate da altri utenti da un’altra data,
forse parte di un database di immagine. Se queste immagini sono oggetti di Archetypes, allora potrete aggiungere
un campo al vostro schema dell’articolo che leggete come segue:
346 INDICE

ReferenceField("images"
allowed_types=("Archetype Images",),
multivalued=1,
),

L’utente ora troverà una casella a discesa di tutti gli oggetti Image di Archetype e sarate capaci di sceglier-
li. Dietro alle quinte state facendo riferimento all’UID di quel oggetto attraverso il catalogo. Troverete un
esempio eccellente sui riferimenti in un prodotto chiamato ACME nel repository CVS di Archetypes presso
http://sf.net/projects/archetypes.

13.3.2 Modificare i Widgets


Una domanda comunemente richiesta è, perché questi widget fanno questo? Un altro è, perché questi widget
appaiano come questo? Spesso la risposta è qualche cosa come, perché ora – non andate a scrivere proprio i
vostri. Siccome i widgets sono quelli che il client vede, questi requisiti sono client orientati. Tutti i widgets sono
rappresentati come macro modello di pagina nel File System. Quindi è abbastanza semplice modificare i widgets
o farne proprio i vostri. Se cliccate portal_skin
portal_skins Davvero, il termine macro < manca qualcosa qui – Ugo >
La macro view è visualizzata sulla pagina view ed è a sola lettura, di facile uso dall’articolo. La macro edit è
quella mostrata sulla pagina di edit, ed è la macro ove un utente edita i dati. La macro di ricerca è chiamata
quando state assemblando pagine di ricerca per il codice; qualche volta guardate proprio la macro edit, anche se
può non essere. Un campo stringa può essere modificato come un campo stringa e può essere visualizzata come
una stringa, ma è ricercabile usando una casella a discesa per selezionare tutte le opzioni disponibile.
Quindi, nel prodotto di esempio, assumiamo che avete un campo stringa che è l’indirizzo e-mail di una persona,
e che volete mostrare che questo sia un collegamento e-mail cliccabile. Per questo creerete una nuova macro. In
questo caso, non avete bisogno in realtà di sovrascrivere la macro di edit o di search – dopo tutto è giusto una
stringa. Quindi, fate un nuovo modello di pagina chiamato email_widget.pt, come segue, che metterà nello skin
del vostro prodotto:

<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
i18n:domain="plone">

<body>
<div metal:define-macro="edit">
<div metal:use-macro="here/widgets/string/macros/edit" />
</div>

<div metal:define-macro="search">
<div metal:use-macro="here/widgets/string/macros/search" />
</div>

Per la vista, avete bisogno di realizzare la stringa mostrata come un collegamento malto che è solamente la
semplice rettifica seguente:

<div class="field" metal:define-macro="view">


<a href="#" tal:attributes="href string:mailto:${accessor}"
tal:content="accessor">email</a>

</div>
</body>
</html>
13.3. SVILUPPARE CON ARCHETYPES 347

Ora che avete definito un modello di pagina che contiene il vostro codice, potete semplicemente far riferimento al
nome del template come la macro nel vostro widget. Nel codice seguente, definite il campo posta elettronica ed un
StringWidget come normale. Cambiate poi la vostra macro per usare la vostra bella nuova macro email_template,
come così:

StringField(’email’,
validators = (’isEmail’,),
widget = StringWidget(
label=’Email’,
macro=’email_template’
)
)

A questo punto state proprio cambiando la macro di un widget esistente. Fare un widget completamente nuovo è
solo questione di definire un nuovo widget e quindi registrarlo. Tutti i widgets condividono la stessa classe base.
Il seguente è un nuovo modulo chiamato EmailWidget.py che è collocato nella directory ArchExample. Create un
nuovo widget e quindi registratelo all’interno del registro. Notate che la proprietà macro del widget (evidenziata)
sia settato al valore del template:

from Products.Archetypes.Widget import TypesWidget


from Products.Archetypes.Registry import registerWidget

class EmailWidget(TypesWidget):
_properties = TypesWidget._properties.copy()
_properties.update({
’macro’ : "email_template",
’size’ : ’30’,
’maxlength’ : ’255’,
})

registerWidget(EmailWidget,
title=’String’,
description=’Renders a clickable email field’,
used_for=(’Products.Archetypes.Field.StringField’,)
)

Per includere questo nel vostro articolo, ora potete importare direttamente EmailWidget e potete usarlo senza
dovere definire esplicitamente la macro, così come:

from EmailWidget import EmailWidget

StringField(’email’,
validators = (’isEmail’,),
widget = EmailWidget(
label=’Email’,
)
)

13.3.3 Sviluppare oggetti Folderish


Avete già lavorato molto con gli oggetti folderish in Plone, ma potevate non saperlo. Un oggetto folderish
possiede caratteristiche simili ad una cartella od ad una directory, vale a dire che può contenere separati oggetti
348 INDICE

individuali. Non v’è realmente nulla di speciale in un oggetto folderish - giusto eredita da una certa classe base
per offrire le sue proprietà, e nuovi contenuti possono essere aggiunti.
Gli oggetti di Folderish sono utili molte ragioni per costruire. Loro offrono un semplice modo di creare raccolte
di oggetti disparati in un’ubicazione. Loro inoltre permettono agli utenti di amministrarere i contenuti usando
l’interfaccia utente standard di Plone, senza dover fare niente altro. Generalmente, è [abitudine -ndt] migliore
tenere la cartella piuttosto semplice, e la logica dovrebbe essere nei vostro oggetti e nei workflow degli oggetti.
Comunque, sempre delle eccezioni a ciò esistono ed un esempio classico è la famiglia dei raccoglitori, CMFCol-
lector e PloneCollector entrambi dei quali sono del tutto oggetti complicati raccoglitori che offrono logica per
un gruppo di problemi dei raccoglitore.
Di nuovo, il modo più facile per creare un oggetto folderish è usare Archetypes. Avete visto che c’èra un tipo
BaseContent che per maneggiare tutto il lavoro ha avuto bisogno di creare un oggetto nonfolderish. Bene, c’è
anche un tipo di contenuto BaseFolder che contiene ogni cosa [necessaria – ndt] per creare una cartella. Più
avanti, troverà un schema speciale per le cartelle, da quando folderish obiettano anche di default abbia una
descrizione. Fare un folderish dattilografare, solo assicura che cambiamentia le Sue classi vili ed i Vostroi
schemi. Per esempio, la più semplice cartella possibilmente è il seguente:

from Products.Archetypes.public import BaseFolder, BaseFolderSchema

schema = BaseFolderSchema

class SimpleFolder(BaseFolder):
"""A simple folderish archetype"""
schema = schema

registerType(SimpleFolder)

If you’re going to store a huge amount of content in a folder, then a folder tends to become inefficient at about
100 objects. That’s a rather arbitrary figure that should be taken with a pinch of salt; normal folderish objects
are designed to be fast for small numbers of object. If you wanted, you could use a binary tree folder, which
stores the objects internally in a more efficient binary tree, rather than a Python dictionary. To use this, just
import BaseBTreeFolder and BaseBTreeFolderSchema and use these in your object instead. As far as developing
a product is concerned, they work just the same, but unless you put a lot of data into them, you wouldn’t likely
notice any difference. I’ve stored more than 100,000 objects in BTreeFolder, and it’s always responded well.

13.3.4 Maneggiare contenuto Microsoft Office


Maneggiare contenuto Microsoft Office, come documenti Word e Excell, è una sventura che tutti i sistemi di
gestione di contenuto affrontano ad un certo punto. Comunque, questo in realtà è il caso per qualsiasi tipo di
contenuto – Microsoft Office, OpenOffice.org, Portable Document Format (PDF), immagini, e così via. Usare
queste forme di contenuto sui siti Web di solito causa alcuni problemi; questo è conosciuto bene, chiaramente.
Modificare è poco pratico perché cliccando un documento si causa il suo download od, anche peggio, l’apertura
nel vostro browser. Quando avete finito, dovete (ri)caricarlo di nuovo sul sito Web che normalmente può voler
dire cliccandolo un po’ di riaverlo.
Quando il contenuto è on-line, i contenuti non sono ricercabili perché non sono in formato semplice-testo [che –
ndt] il catalogo potete capire. Ulteriormente, non potete vedere il contenuto on-line perché di nuovo non è in un
formato Web-amichevole.
Avete un paio di soluzioni per risolvere il primo problema di modificare il contenuto. Se di nuovo presumete che
la maggior parte dei vostri utenti stia usando Windows, allora usare WebDAV può essere ingannevole in quanto
la realizzazione della cartella Web di Microsoft è di qualità discutibile. Invece, External Editor adempie del tutto
bene a questa funzione – se Plone può dire ad External Editor che questo è un file Word, lo aprirà in Word.
13.3. SVILUPPARE CON ARCHETYPES 349

Come per il resto, bene, Archetypes ha un pacchetto di trasformazione incorporato, chiamato Portal Trasforms,
questo si occupa della trasformazione dei tipi di contenuto. Questo può prendere un file in un certo formato e può
trasformarlo in HTML che sarà poi catalogato e lo HTML verrà visualizzato all’utente nell’interfaccia utente. Fa
questo usando un processo di trasformazione esterno per trasformare i dati e leggere i risultati. Per esempio, se
state usando Windows (sul server), poi Portal Trasforms prenderà il documento di Word caricato ed avvierà un
oggetto Component Object Model (COM) che lo trasforma.
Tutto questo succede dietro alle quinte; tutto ciò di cui vi dovete preoccupare è di essere sicuri che ogni requisiti
per la vostra trasformazione sia installata ed operativa. Potete fare molti tipi diversi di trasformazioni, e ci sono
molti modi di trasformare i dati.
La suite di OpenOffice.org offre un’eccellente trasformazione del contenuto di Microsoft, così che se state ese-
guendolo su una piattaforma non-Microsoft, questo è un modo eccellente di trasformare quel contenuto. Ab-
biamo usato anche wvWare (http://wvware.sourceforge.net /) piuttosto con successo come un altro modo di
trasformare contenuto. Tutti queste opzioni sono disponibili; comunque, loro non sono banali da installare. Una
volta che sono installati, le persone di solito risultano soddisfate, trovando trasformazioni di alta qualità come
quando usano un server Microsoft.
Raccomandiamo di pensare precisamente quello che volete trasformare prima e di dare poi un sguardo al codice
sorgente di Portal Trasforms per vedere se potete trovare una trasformazione che faccia il lavoro per voi.

Setting up un Tipo di contenuto

Ora creeremo un semplice tipo di contenuto per maneggiare un documento Microsoft Word, probabilmente il
tipo più comune di contenuto che dovrete amministrare. Per questo esempio, eseguimo la trasformazione su
Windows. Comunque, se volete preparare un sistema alternativo, la maggior parte di ciò che segue funziona
su Linux. In questo caso, la cosa più facile da fare è usare Windows per installare la vostra instanza Plone.
Questo creerà un installazione con tutto i moduli di API Win32 installati e funzionandi. Abbiamo Microsoft
Office installato sul server. Avete bisogno quindi di creare un tipo di contenuto, chiamato * WordExample*,
per occuparsi dell’esempio. Essenzialmente un unico campo dello schema si occupa del contenuto così che lo
schema sembra essere seguente:

schema = BaseSchema + Schema((


TextField(’body’,
searchable=1,
required=1,
primary=1,
default_output_type=’text/html’,
allowable_content_types=(’application/msword’,),
widget=RichWidget(label=’Body’),
),
),
marshall=PrimaryFieldMarshaller(),
)

L’unica differenza è che avete aggiunto un tipo Multipurpose Internet Mail Extensions (MIME) per il documento
Word, application/msword. Per ciascuno tipo di contenuto da essere trasformato, aggiungete un tipo MIME in*
allowable_content_types*. Per esempio, se ì volete occuparsi dei documenti di Word e PDF, avrete la seguente
linea:

allowable_content_types=(’application/msword’,’application/pdf’),

Questo tipo di contenuto è proprio semplice come potete vedere a questo punto. Ma potete collegare molte
cose in questo tipo di contenuto - come una descrizione o molte proprietà. Se state facendo molto lavoro, allora
350 INDICE

sarebbe anche auspicabile che sia possibile prelevare le informazioni metadata dal documento Word e metterlo
come metadata in Plone.

Setting up una trasformazione su Windows

La trasformazione dovrebbe essere settata automaticamente nel tool portal_transforms. Non c’è veramente
molto da guardare nel tool; offre soltanto un lista delle trasformazioni che sono disponibile. Una trasforma-
zione ha un lista di tipi MIME entranti che trasformerà (come application/msword) e ll’output che verrà pro-
dotta (come text/html). Ogni trasformazione è un modulo nel File System; in questo caso, potete trovarlo in
PortalTransforms/transforms/word_to_html.
Per questa trasformazione da lavorare, tuttavia, dovete eseguire un’utilità per generare i collegamenti COM per
Python. Per fare questo, selezionate Start - Plone - Pythonwin e quindi selezionate Tools - COM Makepy Utility.
Questo elenca tutte le interfacce COM disponibili; se avete installato Office, vedrete un ingresso per Word in
qualche parte della lista. Sul nostro particolare server Windows, questo è chiamato Microsoft Word 9.0 Object
Library (8.1). Selezionate questa scelta, e cliccate OK. Pythonwin ora genererà le informazioni adatte. Una volta
che avete fatto questo, troverete un messaggio che riguarda di nuovo ’Generating to.. “
Ora potete chiudere Pythonwin e riavviare Plone.

Testare il tipo di contenuto

Per esaminare il vostro tipo di contenuto, avete bisogno di ravviare Plone, assicurarvi che il prodotto sia registrato
come al solito, ed installato usando lo schermo Add/Remove Products. Per aggiungere un nuovo documento
Word, andate all’interfaccia di Plone e nella casella a discesa selezionate Document Word; è abbastanza ovvio
visto che vedrete anche un piccolo logo di Word.
Successivamente, selezionate il vostro file dal File System, e cliccate Salva per caricare il vostro file. Una volta
che questo è stato fatto, il file sarà caricato, e sarà portato nella pagina di vista. Questo può prendere un po’ di
più di quanto vi aspettate – avete caricato il documento nel server e poi effettuato la trasformazione. Ma sarà
portato alla pagina di vista dal vostro tipo di contenuto, e certamente sarà mostrato in HTML, come mostrato in
figura 13-4.
Ora che è caricato, vorrete modificarlo; per questo, la vostra scommessa migliore è usare External Editor. Se
avete installato External Editor sul vostro client locale, cliccate l’icona di matita nell’angolo in alto a destra, e il
file si aprirà in Word, come mostra in Figura 13-5. Ora potete alterare e modificare il vostro documento Word.
Ogni volta che salvate il file, verrà caricato all’interno di Plone e verrà trasformato.

Suggerimento
Vedi
• http://sf.net/projects/archetypes

• http://www.logilab.org/projects/portaltransforms/documentation

13.3.5 Andare oltre: scrivere tipi di contenuto in un diagramma UML


Così avete un tipo di contenuto complicato e l’idea di scriverlo a mano vi sta annoiando? Bene, niente paura,
perché ArchGenXML è qui! Questo è un prodotto pulito che permette di scrivere il vostro contenuto in un
tool di modellizzazione grafico UML e svilupparsi un prodotto dritto da questo. Filippo Auspberg sviluppò
ArchGenXML, e Jens Klein ha offerto della documentazione eccellente. Con gentile permesso, riprodurremo
alcuni di quei diagrammi qui.
13.3. SVILUPPARE CON ARCHETYPES 351

Il tool di modellazione UML deve supportare uno sistema standard Extensible Markup Language (XML) di
generazione chiamato XML Metadata Interchange (XMI). Questo tool è stato testato con i seguenti programmi:

• ObjectDomain (commerciale, con una demo gratis per 30 classi) presso http://www.objectdomain.com
• ArgoUML (libero) presso http://argouml.tigris.org

• Poseidon (commerciale, basato su ArgoUML) presso http://www.gentleware.com


• Sybase Powerdesigner (commerciale, demo download) presso http://www.sybase.com

Ci sono lievi differenti proprietà di esportazione per ognuno di questi, ma se date un sguardo negli esempi di
ArchGenXML, vedrete esempi di output dai tools UML. La figura 13-6 mostra un progetto di classe che espone
alcuni oggetti: room, person project, resource e task. Ci sono relazioni fra tutti questi oggetti, e c’è regolare
codice Python specificato su alcuni degli oggetti.
Il modo più rapido di esaminare questo è andare nella cartella di ArchGenXML sul vostro File System che avete
ottenuto dall’originale installazione e poi modificatelo nella cartella examples. In questa cartella vedrete lo script
mkdemo. Eseguitelo, digitando giusto ./mkdemo

python ../ArchGenXML.py outline.zargo outline_argo

Avete bisogno di copiare quindi la cartella di prodotto creata (per esempio, outline_argo) nella vostra directory di
Products e riavviate la vostro istanza di Zope. Se date una sbirciatina alla directory outline_argo, vedrete che tutto
è stato creato per voi – l’intera directory e tutta l’inizializzazione attinente al prodotto. Cliccate configurazione di
Plone, selezionate Add/Remove Products ed installate il prodotto outline_argo. Ora potete aggiungere un oggetto
outline che ha tutto lo schema definito nell’UML.
Questo riguarda cosa potete ottenere come sviluppo rapido, e ci sono molte, molte opzioni in ArchGenXML per
importare classi astratte, frammenti di codice, e così via. Inoltre, il codice così facilmente generato permette
di fare cambiamenti e di avere grande documentazione. L’unico vero inconveniente è una mancanza di round-
tripping
http:// Plone.org/documentation/archetypes/ArchetypesDeveloperGuide/index_html#archgenxml-generating-archetypes-
using-uml

13.3.6 Conservare il vostro contenuto in un Database SQL


In quasi tutto questo libro, il contenuto che avete visto è stato conservato nel database ad oggetti di Zope. Ab-
biamo mostrato come conservare contenuto nel File System, ma una domanda comunemente chiesta è, Come
conservarlo in un database relazionale? Metterlo in un database relazionale è una buona cosa da fare spesso se è
vero il seguente:

• La vostra struttura è rigida, e lo schema spesso non cambia (anche se Archetypes mitighi questo aspetto).
• Avete altre applicazioni che possono o accedono al database relazionale.
• Ci sono tools o altri requisiti che sono sempre adempiuti mediante un database relazionale.
• Avete un grande ammontare di dati ripetitivi che sono aggiornati spesso.

In più in un tradizionale ambiente CGI, probabilmente scriverete delle istruzioni SQL per estrarre il contenuto
da un database relazionale. Potete fare questo in realtà se volete usando i metodi ZSQL.
Questi sono utili in molte situazioni e sono trattati in grande dettaglio nel Zope Book ed in molti altri libri, ma non
si possono usare per conservare direttamente il contenuto. Un metodo ZSQL conserva le istruzioni SQL e crea
352 INDICE

query nel vostro database relazionale basate su queste query. Questo è grande se volete fare semplici query in da-
tabase relazionale, ma non classi Python persistenti o tipi di contenuto, e non è il modo in realtà di agire in Plone.
Troverete un capitolo eccellente nel Zope Book per questo presso http://zope.org/Documentation/Books/ZopeBook/2_6Modifi
SQLStorage usa il fatto che Archetypes fornisce un layer addizionale in alto dei normali oggetti per permettere
speciali meccanismi di persistenza. Zope offre molti adattatori per diversi database relazionale, e SQLStorage si
collega a questi. Ci sono attualmente due adattatori, Postgres e MySQL.
Comunque, se il database supporta lo standard SQL, non v’è allora nessuna ragione per cui uno di questi formati
esistenti di SQLStorage non può essere usato. Se scoprite che il vostro adattatore di database ha bisogno di fare
qualche cosa di diverso, allora non sarà difficile modificare gli istruzioni SQL in SQLStorage così che funzioni
con un altro database.

Realizzare un tipo di contento persistente in un database relazionale

Per rendere i dati persistenti, dovete preparare un database relazionale e dovete creare un collegamento in Zope
a lui. In questo caso, useremo Postgres, principalmente perché abbiamo già disponibile un database Postgres
per altro lavoro ma anche perché Postgres è un buon database per tutti i livelli di utenti. Per connettere Zo-
pe a Postgres, psycopg e ZPsycopg probabilmente sono più difficile da pronunciare ma molto comunemente
utilizzati e meglio supportati. Troverete anche pacchetti Debian e simili pacchetti Windows disponibile presso
http://initd.org/software/psycopg.
Installate il vostro adattatore di database, e realizzate una connessione al database dal vostro sito Zope al vostro
database relazionale. Di nuovo, questo è trattato con grande dettaglio nel ZopeBook presso http://zope.org/Documentation/Boo
Ma la risposta breve è di andare nella ZMI, aggiungere una connessione al database dal menu a discesa, e quindi
digitare la configurazione per puntare al vostro database relazionale. Se state connettendovi al vostro database
relazionale come un certo utente, avete bisogno di essere sicuri che l’utente abbia il diritto di creare, inserire,
aggiornare, e cancellare tabelle. I privileggi di creare e cancellare saranno necessari solamente durante la fase di
debug come aggiungere e rimuovere schema ed oggetti.
Una volta che il vostro sviluppo abbia stabilito in giù o si muove alla produzione, questo non sarà più necessario.
Successivamente, nella ZMI ciccate archetypes_tool e selezionate Connections.. Questo permette di mappa-
re il tipo di contenuto al tipo di adattatore di database. Il modo più facile è di mappare il default alla vostro
connessione al database. Se volesse, potete mappare chiaramente specifici tipi a database diversi. Ora cam-
biarete lo schema per utilizzare la nuova memorizzazione. Per questo avete bisogno di importare la classe di
memorizzazione adatta da SQLStorage (in questo caso, PostgreSQLStorage).
Avete bisogno allora di mettere il parametro di memorizzazione sui campi che volete conservare nel database
relazionale. A questo punto, noterete che potete mettere molti o pochi campi nel database relazionale come
cercate - potete mettere tutti i campi del database o solo alcuni. In entrambi i modi ci sarà contenuto da conservare
nel vostro database Plone, ma al minimo vi sarà un oggetto che ha un Id. Nello schema dell’esempio, avete in
ogni modo, due campi: un numero intero (age) ed una stringa (e-mail), come mostrato nel listato 13-4.
Listato 13-4. Un tipo di contenuto che usa SQLStorage

from Products.Archetypes.public import BaseSchema, Schema


from Products.Archetypes.public import BaseContent, registerType
from Products.Archetypes.public import IntegerField, StringField
from Products.Archetypes.public import IntegerWidget, StringWidget
from Products.Archetypes.SQLStorage import PostgreSQLStorage
from config import PROJECTNAME

schema = BaseSchema + Schema((

IntegerField(’age’,
13.3. SVILUPPARE CON ARCHETYPES 353

validators=("isInt",),
storage = PostgreSQLStorage(),
widget=IntegerWidget(label="Your age"),

),

StringField(’email’,
validators = ("isEmail",),
index = "TextIndex",
storage = PostgresSQLStorage(),
widget = StringWidget(label=’Email’,)
),

))

class PersonSQL(BaseContent):
"""Our person object"""
schema = schema

registerType(PersonSQL, PROJECTNAME)

Finalmente, riavviate Plone e registrate il vostro tipo di contenuto nel vostro sito Plone. Ora siete pronto per
testarlo. Se create un oggetto PersonSQL, tutto dovrebbe procedere come normale e come ci si aspetta per il tipo
di contenuto. Ma chiaramente il vero test è guardare nel vostro database.
Vedrete che nel database avete una nuova tabella chiamata personsql, ed in questa tabella troverete quattro
colonne: uid,*parentuid*, age, ed e-mail. Usando psql potete vedere questo:

db=# \d
List of relations
Schema | Name | Type | Owner
--------+--------------------------+----------+-------
public | personsql | table | www-data
...
db=# \d personsql
Table "public.personsql"
Column | Type | Modifiers
-----------+------+-----------
uid | text | not null
parentuid | text |
age | int |
email | text |
Indexes: personsql_pkey primary key btree (uid)

La colonna age è stata creata come int, e la colonna e-mail è stata creata come testo. Questi sono mapping creati
in SQLStorage; potrete cambiare questi mapping ai più adatti se così desiderò. La colonna uid è lo Id unico
per il vostro oggetto Plone. Il*parentuid* è lo uid dell’oggetto genitore obiettano. Questi sono tutti Id unici per
Archetypes che già abbiamo menzionato. Per esempio:

db=# SELECT * FROM personsql;


uid | parentuid | age | email
---------------------------+-----------+-----+-------------------
PersonSQL.2003-07-23.4935 | | 30 | andy@clearwind.ca
354 INDICE

Questo è – i vostri dati sono persistenti nel vostro database relazionale. Non avete bisogno di scrivere SQL, e
potete avere tutti i vantaggi che un database relazionale porta! Joel Burton ha scritto un eccellente articolo how-to
su SQLStorage presso http:// Plone.sourceforge.net/archetypes/sqlstorage-howto.html. Con il gentile permesso,
alcune parti di questa sezione sono basate sul documento di Joel.
13.3. SVILUPPARE CON ARCHETYPES 355

Figura 13.4: Figura 13-4. Il file caricato


356 INDICE

Figura 13.5: Figura 13-5. Il documento caricato in Word


13.3. SVILUPPARE CON ARCHETYPES 357

Figura 13.6: Figura 13-6. Un esempio complesso di ArchGenXML


358 INDICE
Capitolo 14

Capitolo 14: Amministrazione e


scalabilità di Plone

359
360 CAPITOLO 14. CAPITOLO 14: AMMINISTRAZIONE E SCALABILITÀ DI PLONE
Indice

Questo capitolo tratta i compiti di cui dovete occuparvi una volta che avete costruito il vostro sito e lo state
usando. Cominciamo col trattare l’amministrazione di un sito Plone che è davvero piuttosto semplice. Successi-
vamente, tratteremo quali file back up, incluso quando e come back up. Inoltre tratteremo gli aggiornamenti di
Plone.
Quindi, tratteremo le performances e mostreremo le tecniche per trovare gli hotspots. Una volta che avete trovato
questi spots, tratteremo problemi comuni. Poi vedremo le tecniche principali per rendere il vostro Plone real-
mente veloce e scalabile: caching. Quando viene il rendimento, avrete certamente bisogno di conoscere come
scalare il vostro server in ambienti multi-processori e come affrontare richieste ad alto costo. Per questo avrete
bisogno di Zope Enterprise Objects (ZEO) che viene trattato alla fine di questo capitolo.

14.1 Amministrare un sito Plone


Come risulta, l’amministrazione di un sito Plone è piuttosto semplice; avete bisogno di effettuare solamente
alcuni compiti che sono comuni a tutti i servizi. I compiti sono i seguenti:

• Dovrete fare il backup del database regolarmente.


• Dovrete comprimere il database regolarmente.
• Dovrete fare il backup e ruotare i file di log.

Dovrete effettuare queste azioni regolarmente per mantenere il vostro sito. In imprese, avete tools di default
spesso standard per fare il backup e ruotare i log; questi tools sono del tutto facili da integrare visto che i dati
Plone sono tutti contenuti come file nel File System.

14.1.1 Fare il backup del vostro sito Plone


Doveste eseguire regolarmente backup su un sito Plone; la maggior parte delle persone eseguono i backup ogni
notte. La vostra applicazione necessita di determinare la schedulazione del backup. Se una grande quantità di
dati sono scritti all’interno dei vostri dati, allora forse è necessario fare backup più di frequente. Nel caso di un
piccolo sito con meno contento, meno frequente schedulazioni, come una volta alla settimana, possono essere
più appropriati.
In un sito Plone standard, solamente un file necessita di fare il backup: il database di Zope dove risiede tutto
il contento del sito Plone. Potete trovare questo file accedendo al pannello di controllo della Zope Managemet
Interface (ZMI), selezionare Database Gestione,
Data.fs var Potete usare vostri propri scripts o tools per fare backup o potete usare un tool da Zope.
Come un esempio della prima opzione, il listato 14-1 mostra uno script bash di Linux che usiamo per fare il
backup di un sito Zope.
Listato 14-1. Script bash per fare il backup

361
362 INDICE

#!/bin/bash
# script to copy, gzip, and then copy Zope databases
# to remote server
# make up a filename
fn=‘uuidgen‘.fs
# copy it locally, you’ll want to change the
# path
cp /var/zope.test/var/Data.fs /tmp/$fn
# gzip the file up
gzip /tmp/$fn
# scp over to my backup server and then remove
# the temporary file
# change the destination file
scp /tmp/$fn.gz backup@backups.agmweb.ca:~/Zope
rm /tmp/$fn.gz

Per la seconda di queste scelte, uno script Python chiamato repozo.py è disponibile nello Zope Object Database
(ZODB) per fare il backup. Potete trovare questo script on-line presso http://cvs.zope.org/ZODB3/Tools/repozo.py.
Funziona piuttosto felicemente su Windows e su Linux. Questo script può fare un intera moltitudine di cose come
fare un completo backup, fare un backup incrementale, e ripristinare il database.
Per effettuare il backup del database con questo script, dovete prima creare una directory per conservare il backup;
nei seguenti esempi, questa directory è, /home/backups. Comunque, questa ubicazione è su. Per fare un backup
completo del database, eseguite il seguente:

$ python repozo.py -B -F -v -r /home/backups -f /var/zope.test/var/Data.fs


looking for files b/w last full backup and 2003-11-21-18-33-17...
no files found
doing a full backup
writing full backup: 3601549 bytes to /home/backups/2003-11-21-18-33-17.fs

Per eseguire un backup imcrementale, omettete solamente il flag -F (full) il flag. Lo script confronterà lo ZODB
corrente con l’ultimo salvataggio e eseguirà solamente il backup delle differenze. Se non sono occorse nessun
cambiamento, allora non verrà eseguito nessun backup. Ciò che segue è un esempio di backup effettuato a seguito
di modifiche in Plone:

$ python repozo.py -B -v -r /home/backups -f /var/zope.test/var/Data.fs


looking for files b/w last full backup and 2003-11-21-18-39-09...
files needed to recover state as of 2003-11-21-18-39-09:
/home/backups/2003-11-21-18-33-17.fs
repository state: 3601549 bytes, md5: ab9e46bcdf52641ad6f71db62a9da333
current state : 3624968 bytes, md5: 73c871bbe2528e152342abea9e25ab27
backed up state : 3601549 bytes, md5: ab9e46bcdf52641ad6f71db62a9da333
doing incremental, starting at: 3601549
writing incremental: 23419 bytes to /home/backups/2003-11-21-18-39-11.deltafs

A questo punto, ora avete un backup completo ed uno incrementale. Lo stesso script ora può fare un recupero di
questi dati. Per fare questo, passate l’opzione -R (recovery) e -o che specifica il file di output, così come:

$ python repozo.py -R -v -r /home/backups -o /var/zope.test/var/Data.fs


looking for files b/w last full backup and 2003-11-21-18-50-21...
files needed to recover state as of 2003-11-21-18-50-21:
/home/backups/2003-11-21-18-33-17.fs
14.1. AMMINISTRARE UN SITO PLONE 363

/home/backups/2003-11-21-18-39-11.deltafs
Recovering file to /var/zope.test/var/Data.fs
Recovered 3624968 bytes, md5: 73c871bbe2528e152342abea9e25ab27

Per un lista completa delle opzioni, eseguite repozo.py con il flag –h. Questo visualizzerà un set completo di
istruzioni.
I file di log sono presenti nella directory log della vostra istanza home di default, e vi sono due file di log: un file
di log di accessi ed un file di log di eventi. Settate l’ubicazione di questi log nel file di configurazione che avete
guardato nel capitolo 2. z2.log registrano tutte le richieste entranti, e event.log registra tutti gli errori. Questi file
di log dovrebbero essere backup regolarmente, insieme con qualsiasi file di log del server proxy come quelli che
Apache o Internet Information Server (IIS) producono.
Dovreste fare regolarmente il backup dei file di codice, dei template, e dei prodotti personalizzati che risiedono
fuori dello ZODB. Anche se avete questi in un controllo di sorgente, come Concurrent Versioning System (CVS),
fare il loro backup per creare un valido snapshot della vostra installazione, non fa male.
Se avete contenuti, altri database, o altri dati che non risiedono nello ZODB, questo dovrebbe far parte del piano
di backup, mentre dipendendo su come spesso cambiate. Questo può includere dati in database relazionali e
contenuti nel File System. Tutti questi sono creati dallo sviluppatore del sito e non esistono in un standard sito
Plone ”fuori dalla scatola“. Se state promuovendo Zope o Plone, può essere prudente fare un backup di tutti
gli file coinvolti, incluso Zope e Plone così che se l’aggiornamento va a vuoto per qualche ragione, una piena
restaurazione sia possibile.

14.1.2 Comprimere lo ZODB


Il file ZODB registra ogni modifiche di ogni oggetto nel sistema. Ogni volta che un oggetto è modificato, una
copia nuova viene appesa alla fine del file ZODB. Questo file è il file Data.fs, discusso nella sezione precedente.
Se il database ha i grandi pezzi di contenuto o ha un gran numero di modifiche, allora questo può causare una
reale crescita del file ZODB.
Un grande file ZODB non è un problema – lavora proprio bene, ed i tempi di avvio sono simili (a meno che
l’index non sia stato rimosso). I tempi di compressione diventeranno più lunghi se il database è grande, ed ha
senso di tanto in tanto andare a rimuovere quelle vecchie copie di oggetti che non sono più usate per rendere
più piccolo il database. È fondamentale per tutti ricordarsi che comprimendo state ripulendo il vostro database
esistente ed che state eliminando quelle vecchie copie.

Il vecchio limite di 2GB del Database

Un problema esiste con le versioni più vecchie di Python (prima della Python 2.1 su Unix e della Python 2.2 su
Windows), che non era capace di supportare grandi file. Quando il file ZODB raggiunge 2 gigabyte (GB), il sito
Plone muore e non può essere riavviato. Per esaminare se sta eseguendo una versione Python che ha il supporto
per i grandi file, aprite un file in Python e vedete se la sua dimensione è riportata come un numero intero od un
numero lungo, così come:

>>> import os
>>> from stat import ST_SIZE
>>> type(os.stat(’/tmp/test.txt’)[ST_SIZE])
<type ’long’>

Questo Python ha il supporto per i grandi file attivato e potete supportare file più grande di 2GB. Se un numero
intero viene riportato, poi avete bisogno di aggiornare la vostra versione di Python o di ricompilarlo con il
supporto per i grandi file (di nuovo, abilittata di default nelle nuove versione). Se tentate di modificare Plone con
una versione di Zope che non ha il supporto per i grandi file, avrete un errore, così come:
364 INDICE

andy@thorin:/tmp/Zope-2.7.0-b3$ ./configure
Configuring Zope installation
...

This Python interpreter does not have have ’large file support’ enabled.

Se questo è il caso, poi avete bisogno di andare e riparare la vostra installazione di Python. Potete trovare mag-
giori dettagli su questo presso http://www.Python.org/doc/current/lib/posix-large-file.html. Se siete felice con
giusto il limite di 2GB, allora potete utilizzare, nel vostro script di configurazione, l’opzione --ignore-largefile.
Se siete limitati ad un database di 2GB, avete allora bisogno di comprimerlo più regolarmente.

La pulitura del database viene chiamata compressione (packing)

La fase di compressione può essere intensiva, e quando il processo è in esecuzione, in un thread separato, così
anche se si ripercuote sulla velocità del sito, sarate ancora capaci di rispondere alle richieste. Per comprimere il
sito e mantenere alto il rendimento di Plone, vedete la sezione ”Usare ZEO“ successivamente in questo capitolo.
Per eseguire una compressione, accedete al pannello di controllo di ZMI, selezionate Database Management, e
cliccate main
Digitate il numero di giorni che volete mantenere gli oggetti, e cliccate Pack. Per esempio, settando il numero di
giorni a zero (di default) rimuoverete tutte le revisioni degli oggetti. Di nuovo, non cancellate l’oggetto stesso,
solo quelle vecchie copie. Un setting più comune è qualche cosa come sette, che rimuove le revisioni più vecchie
di una settimana. Facendo un setting appropriato con il vostro orario di backup, potete assicurarvi che terrete una
copia di ogni oggetto. Il pack richiederà un po’ di tempo e di potenza in funzione della dimensione del vostro
ZODB. Plone lavorerà ancora, benché più lento, così potete volere usare ZEO per fare ciò.

14.1.3 Aggiornare Plone


Plone è continuamente aggiornato e migliorato, così nuove versioni di Plone vengono rilasciate piuttosto rego-
larmente. Prima di fare l’aggiornamento ad una nuova versione di Plone, tuttavia, controllate che ne abbiate
davvero bisogno. Spesso le distribuzioni hanno minori cambiamenti o cambiamenti che possono non essere at-
tinenti. Ogni distribuzione ha un lista di modifiche, accessibile dallo pagina del download. Conviene sempre
vedere la lista per essere sicuri che l’aggiornamento ne valga la pena.
Dopo avere effettuato il vostro backup, scaricate l’aggiornamento. Probabilmente il modo più facile per effettuare
un aggiornamento consiste nel ripetere gli stessi passi compiuti durante l’installazione. Per esempio, se installate
usando l’installer di Windows, scarica l’installer nuovo ed eseguite una nuova installazione. Se installatee dai
sorgenti o da un pacchetto Debian, ripetete questi passi. I passi di aggiornamento sono i seguenti:

1. Scaricate l’aggiornamento attinente.


2. Fermate Plone.
3. Fate il backup (come descritto precedentemente).
4. Installate l’aggiornamento.
5. Avviate Plone.

A questo punto raccomandiamo di fatto di avviare Plone in modalità debug. Su Windows, potete fare questo
selezionando Start - Plone - Plone Debug. Su Linux potete farlo usando lo script runzope all’interno della
directory bin della vostra istanza home, come così:

bin/runzope -X "debug-mode=on"
14.1. AMMINISTRARE UN SITO PLONE 365

Figura 14.1: Figura 14-1. Comprimere un database


366 INDICE

Eseguendo questa modalità di debug, vedrete direttamente alcuni errori che sono accaduti durante l’aggiorna-
mento alla versione nuova. Se siete felice con questo, ora potete procedere con il prossimo passo, la migrazione.
Per ciascun sito Plone che avete, accedete alla ZMI ed accedete al tool portal_migration nel vostro sito Plone.
Avrete un punto esclamativo rosso brillante in prossimità, per indicare che il sito non è <manca qualcosa – Ugo>
La migrazione cercherà di fare queste modifiche per voi. Finché eseguite questa migrazione è possibile che il
vostro sito Plone possa essere rotto. Questo può richiedere del tempo, in funzione di ciò che sia necessario fare
nel processo di migrazione. Per effettuare una migrazione, seguite questi passi:

1. Dal portal_migration, cliccate la tab Migrate.


2. Cliccate il bottone upgrade. Questo può richiedere tempo, specialmente su grandi siti o
se sia necessario un grande aggiornamento.
3. Il risultato della migrazione, un messaggio piuttosto lungo, verrà visualizzato sullo scher-
mo. Se il messaggio finale è ”End of upgrade path, migration has finished“, allora la
migrazione ha avuto successo. Qualsiasi messaggio d’errore sarà evidenziati in rosso.

Ripeta questo processo per ogni sito Plone all’interno della vostra istanza di Zope. Se quindi è felice con la
migrazione del sito, arresti Plone in esecuzione in modalità debug. Riavvii Plone nella vostra solita maniera, e lo
continui ad usare come normale.

14.2 Migliorare il rendimento di Plone


Cosi avete scritto un meraviglioso sito Web, millioni di visitatori visitano il sito ed esso non possiede del tutto
un rendimento in termini di velocità come voi vorreste. Bene, Plone è progettato fuori del box per essere ric-
co di caratteristiche, non veloce, in quando la velocità è fortemente dipendente dall’applicazione in questione.
Ma molte tecniche possono rendere Plone veramente veloce, e potete facilmente scalare Plone. Nelle sezioni
seguenti, tratteremo, di come individuare le parti lente del vostro sito e quindi mostrarvi i metodi per migliorarlo.

14.2.1 Eseguire un benchmarcking di un Sito Plone


Prima di provare ad ottimizzare un sito, il compito fondamentale è trovare un valore numerico per il rendimento
del sito. Gli utenti restituiscono spesso dei feedback come ”è troppo lento“ o ”prende troppo tempo per caricare.“
Questi commenti sono pressocchè inutili per un sviluppatore; avete bisogno di essere capace di quantificare
la velocità così che potete conoscere come sia veloce ora e di quale velocità avete bisogno di raggiungere.
Solamente dopo cominciate a fare l’ottimizzazione.
Per trovare un test di efficienza, potete usare un tool chiamato ab, o Apache Bench. Questo è un tool che viene
rilasciato con il server Apache. Se avete Apache 1.3 o successivo installato su Linux, ab è incluso. Su Windows
è incluso con la distribuzione Apache 2. Eseguire ab è semplice – giusto passare lo Uniform Resource Locator
(URL) che desiderate testare, cosi come:

ab http://localhost/

Il tool ab produrrà in output delle informazioni prima sul sito esaminato, così come:

Benchmarking localhost (be patient).....done


Server Software: Zope/(unreleased
Server Hostname: localhost
Server Port: 80

Document Path: /
Document Length: 20594 bytes
14.2. MIGLIORARE IL RENDIMENTO DI PLONE 367

Quindi produrrà in output delle statistiche globali, come così:

Concurrency Level: 1
Time taken for tests: 0.771151 seconds
Complete requests: 1
Failed requests: 0
Write errors: 0
Total transferred: 20933 bytes
HTML transferred: 20594 bytes
Requests per second: 1.30 [#/sec] (mean)
Time per request: 771.151 [ms] (mean)
Time per request: 771.151 [ms] (mean, across all concurrent requests)
Transfer rate: 25.94 [Kbytes/sec] received

Questo vi informa di quanto tempo prende la richiesta, il numero di errori, ed il tempo preso per trovare una
richiesta che probabilmente è il chiave statistico. Il valore più utile di riferimento e di solito Requests for second.
Richiesta al secondo, che in questo esempio è 1.30 [#/ secondo]. Il tool ab offre alcune ulteriori statistiche che
danno informazioni su quanto tempo prende per connettersi, trattare, e trovare un risultato per ogni richiesta. Per
esempio:

Connection Times (ms)


min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 770 770 0.0 770 770
Waiting: 766 766 0.0 766 766
Total: 770 770 0.0 770 770

Questo ultimo pezzo di informazioni è utile ed include il tempo preso per trovare un collegamento. Siccome il
mio server è sullo stesso computer come il client, questo è piuttosto corto. Questa prova dimostra che ci sono
voluti 1.30 secondi per completare una richiesta. In realtà, questo chiaramente non ha testato affatto molto il
server. Quando esaminate, vorrete probabilmente interessare il server con diverse richieste concomitanti per
simulare in modo reale un poco di più. Potete fare questo specificando il numero di richieste ed la concomittanza
usando le opzioni -c (threads concomittanti) e -n (numero di richieste). Per esempio:

ab -n 20 -c 4 http://localhost/

Questo spedisce un totale di 20 richieste su 4 threads concomittanti. Il risultato finele è di 1.78 secondi, una ri-
chiesta lievemente diversa. Per ulteriori informazioni su tutte le opzioni disponibile, per favore vedate il manuale
di Apache Bench presso http://httpd.apache.org/docs/programs/ab.html.
Un vantaggio di usare ab è che non sta assemblando davvero le pagine sul client; loro sono scaricati solo e poi
gettate via. Se avete una pagina che ha molte scripts o caratteristiche grandi immagini, il tempo che richiede
al un client per assemblare quella pagina in qualche cosa l’utente può capire non sarà incluso. Un esempio
classico di questo è che nel vecchio browser Netscape, un gran numero di tabelle potevano rallentare o cashare
Netscape. Questo non sarebbe evidente evidenziato usando ab che vi fornicse un numero molto indipendente
con cui lavorare.

14.2.2 Bugie, maledette bugie, e numeri di benchmark


A questo punto, possiamo preoccuparci di questi numeri. Sembrano indicare un sito molto lento. In questo
esempio, la nostra macchina è un laptop Toshiba con un microprocessore Celeron 1.8 gigahertz (GHz), 256
megabyte (MB) di Random Access Memory (RAM), Red Hat Linux 9.0, ed una versione beta di Plone 2. Inoltre,
368 INDICE

Plone sta funzionando in modalità debug contemporaneamente con KDE, OpenOffice.org, Istant Message, e
diversi altri tools di sviluppo, incluso l’attuale toold di benchmarking. Questo vuol dire che Plone non sia in
alcun modo ottimizzato o sia eseguito in un ambiente ideale. Un simile test su un server più veloce produce
come risultato circa 20 richieste al secondo.
Il punto fondamentale è che creare un numero obiettivo per il rendimento del sito vi permette di misurare il
successo delle vostre ottimizzazioni. Gli sviluppatori possono effettuare modifiche e quindi possono esaminare
di nuovo comparando i numeri ”prima“ e ”dopo“. Se è possibile, dovreste eseguire prove di rendimento su una
macchina simile al server di produzione per trovare numeri con senno. Per questo capitolo non è importante che
un sito possa produrre X richiede al secondo; invece, è importante che un cambiamento sia capace di produrre
un aumento significativo del rendimento.
Inoltre, ricordate che i numeri attorno alla velocità di alcune parti del vostro sito sia abbastanza insignificante
in isolamento. Dovete prendere in considerazione come spesso la pagina sia visitata, le aspettative degli utenti
a quel punto, e i requisiti realistici. Micromisurare solo uno parte di un sito può essere utile per localizzare
in profondità un certo problema, ma non può rendere molto più veloce il vostro sito. Come molte cose, avete
bisogno di un approccio assennato alle ottimmizzazioni.

14.2.3 Modalità di produzione contro modalità di debug.


Uno dei maggiori assassini della velocità di Plone è eseguire il vostro sito in modalità debug. Quando viene
eseguito in modalità debug, ogni template, script, ed oggetto nel tool*portal_skin* viene confrontato con il File
System per vedere se sia recente. Questo controllo succede con <manca qualcosa – Ugo >
Per scoprire se il vostro sito stia funzionando in modalità debug, nella ZMI accedete all’oggetto portal_migration
del vostro sito Plone. In fondo alla pagina vi sarà un lista di informazioni, incluso lo status Debug Mode. Per
cambiare questo, modificate il file di configurazione, come descritto nel capitolo 2.

14.2.4 Altre ragioni per un rendimento lento


Un server può funzionare lentamente per ragioni esterne a Plone. Se sta eseguendo una fase di ottimizzazione,
dovreste dare sempre prima un sguardo a queste considerazioni, in quando forniscono rapidi miglioramenti di
velocità con poco costo.

Microprocessore usato

Se state eseguendo un grande numero di applicazioni, o solo qualcuna intensiva, allora queste limiteranno l’am-
montare di tempo del processore disponibile per Plone. L’assemblare pagine in Plone può richiedere molta
potenza della Central Processing Unit (CPU). Quando una applicazione è legata al’ammontare della potenza di
processing disponibile, essa viene denominata CPU bound.
Per scoprire cosa esegue il server, se gira sotto Linux, usate il comando top. In Windows, il Task Manager
(accessibile premendo Ctrl+Alt+Del) vi fornirà simili statistiche. La velocità raccomandata della vostra CPU
dipende sulla dimensione e dal carico di traffico del vostro server Plone, ma un microprocessore a 2GHz è un
buon punto di partenza.

Ammontare di memoria

A Zope piace usare molta memoria per gli oggetti caricati dal file ZODB. Di tutte le caratteristiche fondamentali,
fornire ad un server Zope ulteriore memoria è probabilmente la migliore cosa che si possa fare.
Per scoprire cosa viene eseguito sotto un server Linux, usate il comando top. In Windows, il Task Manager
(accessibile premendo Ctrl+Alt+Del) vi darà simili statistiche. L’ammontare raccomandato di memoria dipende
14.2. MIGLIORARE IL RENDIMENTO DI PLONE 369

sulla dimensione e dal carico del traffico del vostro server Plone, ma un quantità di 512MB è un buon punto di
inizio. Se potete permettersi più memoria, ciò è raccomandato.
Potete fare alcune modifiche ai parametri di memoria di Plone aumentando il numero di target di oggetti in cache.
Di default, Plone carica 400 oggetti in cache. Per un sito, si può aumentare questo a 5,000, come mostrato in
figura 14-2. Sebbene questo aumento di uso della memoria, questo inoltre <manca qualcosa – Ugo>

Figura 14-2. Cambiando i parametri di cache nel pannello di controllo


Inoltre, meno threads usati da Zope, meno potenziale uso di memoria occorrerà. Anche se Zope è multithreaded,
la maggior parte del tempo verrà utilizzata da un solo thread Zope. Riducendo il numero di threads a tre fornite un
server con maggior memoria-efficiente. Invece di tentare di eseguire un gran numero di threads, è raccomandato
eseguire client ZEO per servire più richieste. La sezione ”Zope Oggetti Enterprise“ tratta ciò con maggior
dettaglio.

Collegamento di rete

Il collegamento di rete può essere critico per il rendimento di qualsiasi applicativo. Quando state ottimizzando
un sito Plone, prendate in considerazione l’ammontare di tempo richiesto per la connessione. Se ci vogliono due
secondi per connettersi in realtà, ottimizzare il codice è piuttosto inutile.
Il tool ab può aiutarvi di nuovo, qui. Quando abbiamo eseguito un test di efficienza di Plone.org da British
Columbia (il server è localizzato in Texas), si può vedere nel seguente output che l’attesa media per i collegamenti
sulla rete sono di 125 millisecondi:

Connection Times (ms)


min mean[+/-sd] median max
Connect: 90 133 40.2 125 211
Processing: 511 1103 400.2 1113 1846
Waiting: 202 310 110.3 293 565
Total: 601 1236 411.2 1211 2043

Il server può avere anche limiti sul numero dei collegamenti o sul viaggiare attraverso firewalls interni. Quando
un processo è legato dal tempo preso per fare processi di Input/Output (I/O) come questi, viene chiamato processo
di confine I/O (I/O bound).
370 INDICE

La vostra Applicazione

Può, certamente, essere che la vostra applicazione stia davvero provocando un rallentamento. Gli esempi da società d
Codice copiato da un sito Web che ha una chiamata sleep profonda nel sistema causata dallo script
può causare una pausa di qualche secondo. Una revisione del codice che individui questo e rimuova
la linea che reca danno.
• Molteplici lookups al database relazionale, più di una dozzina su di una pagina. Una progettazione
più intelligente combina i lookups e permette il caching.
• Uno script che ha prelevato informazioni dal file ZODB richiedendo ogni oggetto dal database. L’uso
del catalogo (trattato nel capitolo 10) rende molto più veloce le perfomance.
• Una query che richiede tutti i record in un database, ma che poi ne mostra solamente 100 alla volta
su una pagina, scartando le rimanenti 99,900. Questo viene risolto scrivendo le istruzioni SQL in
maniera più efficiente.

Prima di trarre conclusioni rispetto a ciò che sta provocando il problema, vale quindi, trovare dove sia il collo di
bottiglia.

14.2.5 Profiler di Plone


Visto che si può quantificare il tempo richiesto per produrre delle pagine, potete ora tentare di ottimizzare.
Comunque, il primo problema rimane trovare ove ottimizzare.
Per favore notate che se abilita tutti i tre questi tools che tracciano i profili, troverete che il vostro sito Plone inizia
realmente a rallentare (di una grandezza significativa). Ognuno di questi profilers esigono un tributo sul rendi-
mento per il numero di collegamenti che debbono installare. Dovreste disinstallarli sempre od arrestarli questi
profilers dopo che li avete usati per assicurarvi che il vostro sito stia funzionando al massimo dell’efficienza.
Inoltre, se abilite tutti e tre questi profilers, iniziate ad elaborare il profilo dai profilers (e questo avviene quando
si inizia a trovare confosione). Raccomandiamo di iniziare dal Call Prifiler. Quindi eseguite a turno ciascuno
degli altri profilers, arrestando il profiler precedente, finché avete abbastanza informazioni.

Call profiler

Questo prodotto Zope prende una richiesta, come trovare una front page e fornisce un report degli oggetti che so-
no stati usati e di quanto tempo viene richiesto da ognuno. Potete trovare Call Prifiler presso http://zope.org/Members/richard/C
Nonostante i commenti sulla pagina di download, il prodotto non è integrato in Zope 2.6. Installate il prodotto
nel modo standard, e poi riavviate il vostro Zope.
Per abilitare Call Profiler, andate al pannello di controllo ZMI e scegliete Call Profiler. Il prodotto funziona
installando aggangi ad un oggetto così che quando si accede all’oggetto, l’ammontare di tempo speso per resti-
tuirlo possa essere misurato. Ricordate che Call Profiler verrà attivato solamente sugli oggetti che scegliete di
esaminare, come mostrato in figura 14-3. Per un’configurazione standard di Plone, avrete bisogno di esaminare
Filesystem Script (Python) e Filesystem modello di pagina. Call Profiler non ricorda questi settaggi fra riavvii di
Zope il che significa che un semplice riavvio disattiverà gli agganci e lascerà pronto per il deploy.
Figura 14-3. Call Profiler con gli agganci al File System selezionati
Una volta che gli oggetti da esaminare sono stati selezionati, accedete all’URL che volete esaminare. Il modo più
facile di accedere all’URL da esaminare è eseguire il tool ab menzionato precedentemente; comunque funzionerà
più che bene usando un browser Web. In questo caso, se sta eseguendo il profilo della pagina iniziale su localhost,
allora eseguite il seguente:

ab -n 20 -c 4 http://localhost/
14.2. MIGLIORARE IL RENDIMENTO DI PLONE 371

Questo provocherà 20 richieste da fare a Plone. Una volta completate, potete visionare il tempo richiesto. Ri-
tornando all’interfaccia di Call Profiler, vedrete tre tab in alto al tool Call Profiler: Results, Results by URL ed
Aggregates. Visto che sono state eseguite richieste multiple, selezionate il tab Aggregates che è più facile da
capire. Nella lista delle pagine chiamate vedrete l’URL esaminato. Cliccate quel link per vedere i risultati di quel
URL. Ora dovreste vedere qualche cosa come in figura 14-4.
Figura 14-4. I risultati del profiler
In questo esempio, vedrete gli elementi che Call Profiler è capace di rilevare. Sfortunatamente, i risultati possono
essere un pò complicati da decifrare. Per primo osservate, i risultati si accumulano più del 100 per cento. In
questo caso, document_view richiede il 71.1 per cento del tempo di processo. Comunque, questo è forviante
perché valuta sotto questa figura relativa a document_view, non all’intera pagina. In questo esempio, per l’intera
pagina ogni cosa prima di browserDefault richiede il 19.9 per cento della richiesta. Poi passa a document_view,
e vedete le percentuali per questa parte. Quindi in questo caso, l’andare da toLocalizedTime a getPreviousMonth
richiede il 23.3 percento del tempo richiesto per rendere document_view.

Eseguire il profiler del modello di pagina

Page Templete Profiler lavora solamente con il sistema Zope Page Templetes. In un modo simile a Call Pro-
filer, restituisce, quanto tempo è stato impiegato per rappresentare ciascuna chiamata in un modello di pagi-
na. Cosi nell’esempio precedente vedete che la maggior parte del tempo viene speso in un modello di pagina
(document_view), potete trovarlo istruttivo vedere come il tempo è speso in quel modello.
Potete trovare Page Template Profiler presso http://zope.org/Members/guido_w/PTProfiler. Installate il prodotto,
e poi riavviate Zope. Per disistallare il Page Template Profiler, dovrete rimuoverlo dalla vostra directory Products
quando avete finito di eseguire il profiler.
Una volta installato, andate alla radice di Zope nella ZMI e selezionate PT Profiler Viewer da Add della casella
a discesa. Completate il modulo di creazione, dando un unico valore ad Id (digitate PTProfiler, per esempio), e
allora cliccate Add. Ora ripetete la chiamata alla pagina che volete misurare eseguendo il tool ab od accedendo
alla pagina in un browser. Accedete solo il modello di pagina Elaboratore oggetto aggiunto, e vedrete un risultato
per la richiesta solo corsa. Lo Cliccate per trovare dettagli più, come mostrato in figura 14-5.
Figura 14-5. I risultati di Page Templete Profiler
In questo caso, potete vedere che sul mio sito che calendarBox stia utilizzando 0.7321 secondi di chiamata per
372 INDICE
14.2. MIGLIORARE IL RENDIMENTO DI PLONE 373

ogni volta che viene chiamata. Visto che l’intera pagina sta utilizzando 1.9 secondi, si può presumere che sia
questo un campo che potremmo ottimizzare.

Python Profiler

Il Python Profiler offre molte informazioni a basso livello sui tempi e viene normalmente usato per effettuare
debugging più complesso sul codice fondamentale. Fornisce un prospetto particolareggiato dell’ammontare di
tempo speso in vari campi di codice Python. Questo non è normalmente qualche cosa che viene utilizzato per
effettuare il profiler di un sito; per completezza, comunque, lo descriveremo in questa sezione.
Per attivare Profiler Python, avete bisogno di aggiungere una variabile al file di configurazione. Nel file zope.conf
nella vostra directory ect, abilitate il comando publisher-profile-file. Per fare questo, definite un file sul quale
scrivere. Su Windows questo potrebbe essere c:zope.output; su Linux è /tmp/zope.output. Aggiungete la seguente
linea su Linux:

publisher-profile-file /tmp/zope.output

Poi riavviate Plone, ma verrà eseguito molto lentamente. Se state eseguendo un gran numero di richieste e volete
esaminare i risultati, allora il file specificato nella variabile di ambiente conterrà l’output dei dati. Come negli
esempi precedenti, chiamate la pagina che viene profilata usando il tool ab od un browser Web. Poi accedete al
pannello di controllo attraverso la ZMI, selezionate Info Debug, e quindi selezionate la tab Profiling; otterrete
l’output del Python Profiler, come mostrato in figura 14-6.

Figura 14-6. Risultati del Python Profiler


Come potete vedere in figura 14-6 l’output mostra i dettagli cruenti di ciò che richiede più tempo. Abbiamo
dovuto usarlo raramente.

14.2.6 Semplici trucchi di ottimizzazione


Dopo avere completamente osservato molto Plone, la squadra di sviluppo di Plone è arrivata ad individuare i
seguenti trucchi di ottimizzazione.
374 INDICE

Limite Nome Lookup

Esagerare con il nome lookups è un errore comune; la soluzione è definire localmente una variabile. Nell’esempio
seguente, Plone deve effettuare lookup per portal_url su ogni ripetizione del ciclo iterativo:

<tal:block
tal:repeat="result here/portal_catalog">
<a href=""
tal:attributes="href here/portal_url/getPortalUrl">Home</a>
...
</tal:block>

But it’d be faster to use a *tal:define*, like so:

<tal:block
tal:repeat="result here/portal_catalog"
tal:define="url here/portal_url/getPortalUrl>
<a href=""
tal:attributes="href url">Home</a>
...
</tal:block>

Come già determinato, Plone definisce un gran numero di definizioni globali. Usando queste definizioni, un
sviluppatore può ridurre il numero di traversals. Potete trovare un lista completa di tutte queste definizioni
nell’Appendice A.

Controlli di sicurezza e traversal

Ogni qualvolta che si accede ad un oggetto, a degli attributi di un oggetto, od a dei metodi di un oggetto, viene
effettuato un controllo di sicurezza. Anche se ogni controllo di sicurezza non è esoso, un gran numero di controlli
di sicurezza possono realmente accumularsi.
Questo è specialmente vero quando si traversa un oggetto, per esempio, a here/folderA/folderB/object. In questo
caso, Zope effettuerà controlli di sicurezza su ciascuna di queste cartelle e poi sull’oggetto. Se le informazioni
possono essere accessibili senza fare ogni volta questo traversal, vi sarà un guadagno di rendimento. Un altro
modo di evitare di fare controlli di sicurezza è scrivere codice in Products nel File System. Il codice in Products
viene considerato codice fidato, è soggetto a meno controlli, ed è da qui più veloce.

Lo ZCatalog

Lo ZCatalog è un efficiente albero binario di dati sugli oggetti. Dovreste usarlo (in molte situazioni) quando
ricevete un lista di oggetti, come risultati di una ricerca, offrendo sommari, trovando oggetti e così via. Quando
il catalogo restituisce un set di risultati che accedono ad una serie di oggetti leggeri (chiamati brains), accedendo
a questi brains, non si intende fare traversal all’oggetto o compiere alcun controllo di sicurezza.

Anche molte caratteristiche

Questo può sembrare ovvio, ma Plone viene eseguito con molte caratteristiche di cui potete non avere neces-
sariamente bisogno. Il calendario e portlet di navigazione, richiedono ancora, per esempio, un gran numero di
risorse e sono di uso generalmente limitato. Spegnere queste caratteristiche, se non ne avete bisogno, aumenterà
il rendimento.
14.2. MIGLIORARE IL RENDIMENTO DI PLONE 375

L’ottimizzazione è un valore?

Prima che avviate qualsiasi ottimizzazione, dovreste effettuare una semplice analisi costi-benefici per vedere se
l’ottimizzazione sia valore da compiere.
Per esempio, dite che avete una pagina che richiede 0.5 secondi per essere generata. Di questa pagina, lo script
prende il 10 percento del tempo per generare. Se siete capaci di raddoppiare la velocità di questo script, gua-
dagnerete solamente 0.025 secondi per l’esecuzione di questa pagina. In questo caso, il beneficio, realizzato
compiendo l’ottimizzazione, è piccolo perché ci sono costi di base come il costo di un sviluppatore per effettuare
l’analisi, il costo di testing per controllare il funzionamento, e possibilmente la modifica alla documentazione.
Compiere anche questo lavoro crea rischio sostanziale. Cambiando codice si può rompere o introdurre bugs
all’interno dell’applicazione. Utilizzando agili metodologie di programmazione, tuttavia questi potrebbero essere
minimizzati. Ulteriormente, un programmatore può non essere capace di incrementare la velocità o potrebbe
realizzarlo più lento.
Avete alternative ad ottimizzare il codice; per esempio, potete installare più memoria o hardware se l’applicazione
è costretta entro una di queste limitazioni. Anche se molti programmatori pensano che fornire hardware ad una
soluzione sia un opzione pigra, può essere una soluzione estremamente economica. Introdurre nuovohardware è
rischio basso, potrebbe portare un gran guadagno di velocità, e spesso costò meno di un programmatore.
Infine, potete scalare in realtà il vostro server mediante caching o aggiungere ulteriori computer e separare il
carico. Queste tecniche saranno oggetto del resto del capitolo.

14.2.7 Caching dei contenuti


Così ora che avete trovato le parti lente della vostra applicazione, vi rivolgerete al principale tool per aumentare
il rendimento: caching. Caching
Quando si parla di caching, stiamo discuttendo approssimativamente di due cose che possono essere cached:
il contenuto e lo skin. Il contenuto sono i dati digitati dall’utente in tipi Contents. Lo skin fa riferimento a
qualsiasi cosa presente in*portal_skin* e può essere template, scripts, immagini, o file. Questi due tipi sono
cached differentemente.
Ci piace pensare al caching in termini di ammontare di controlli che avremo sul meccanismo di caching. In altre
parole, più vicino al client sarà effettuato il caching, più veloce sarà la risposta ma anche meno controlli avremo
su quella cache. Questo infatti include la possibilità che può non esservi affatto cache. La figura 14-7 illustra
caching fra un client ed un server.
Figura 14-7. Cache fra un client ed un server
La cache del browser dell’utente è il posto più veloce per effettuare cache, ma non avete idea se l’utente abbia
davvero abilitato nel prprio browser la cache. Seccessivamente viene la cache intermedia del server proxy;
ricordate questo potrebbe essere il vostro server proxy (quale sul quale dovete avere controllo) o un proxy di un
Internet service provider (ISP). Vi sono finalmente, le opzioni di caching del server.
Nelle seguenti sezioni, discuteremo dei seguenti meccanismi di caching:

• Caching degli elementi di skin usando Accelerated HTTP Cache Manager


• Caching del codice usando RAM Cache Manager
• Caching dei contenuti aggiunti dagli utenti attraverso Caching Policy Manager

Discuteremo quindi di come usare Apache e Squid, due server esterni comunemente usati che offrono un host
intero di opzioni di configurazione ad alto rendimento.
376 INDICE
14.2. MIGLIORARE IL RENDIMENTO DI PLONE 377

14.2.8 Caching Skin


Hypertext Transfer Protocoll (HTTP) permette di settare le intestazioni HTTP per il caching. Quando una risposta
ritorna con queste intestazioni, è responsabilità dei proxies fra il client ed il server mettere in cache l’oggetto
secondo queste intestazioni. In figura 14-7, questo potrebbe essere qualsiasi cache dal server cache in giù.
Questo proxy può essere un server Web che controllate sul server, come Apache o un proxy che viene controllato
dal ISP. Come discuteremo, questo realizza un tool potente quando unito con Apache o con Squid.
Questi caching possono includere anche il browser se è settato per usare caching (di default per Internet Explorer).
Comunque, se un browser esegue un aggiornamento su una pagina, il browser spedisce l’intestazione Pragma:
no cache che forza i proxy a ricaricare anche la loro copia.
Il caching viene applicato in questa modalità all’intera risposta, così che possa essere rischioso se provate ad
applicarlo ad una pagina intera. Questo viene usato più comunemente con immagini, fogli di stile, JavaScript, o
pagine che non subiscono cambiamenti in grande quantità. Immagini usate ripetutamente nelle vostre pagine per
fare i begli elementi, come angoli rotondi o immagini di background sono ideali per questo.
Di default, Plone crea un Accelerated HTTP Cache Manager, chiamato HTTPCache, nella radice del vostro sito
Plone. Per accedere a questo oggetto attraverso la ZMI utilizzerete le opzioni di gestione per la cache. Ciò che
segue sono tutte accettabili di default, e non avete bisogno di cambiarle inizialmente:

• Title
• Interval
• Cache anonimous connections only
• Notify URLs (via PURGE)

Per vedere come Accelerated HTTP Cache Manager lavori, il seguente è un esempio basato su un oggetto di
prova, un’immagine chiamata test.gif. Per vedere che le intestazioni sono ritornate, avete bisogno di esaminare
le intestazioni che sono ritornate. Per fare ciò potete usare un semplice script Python chiamato header.py. Potete
trovare questo script nell’Appendice B. Su Linux il comando wget esegue inoltre la stessa cosa se passate - S,
sebbene ancora scaricate il file. Per esempio:

wget -S http://www.agmweb.ca

Primo, ciò che segue sono le intestazioni ritornate prima per test.gif

[andy@basil scripts]$ ./header.py http://localhost:8080/test.gif GET


Accept-Ranges: bytes
Connection: close
Content-Length: 2541
Content-Type: image/gif
Date: Wed, 03 Sep 2003 23:55:38 GMT
Etag:
Last-Modified: Wed, 03 Sep 2003 23:54:27 GMT
Server: Zope/(unreleased version, python 2.2.2, linux2) ZServer/1.1

Dopo avere aggiunto l’immagine alla cache, riverificherà le intestazioni HTTP usando di nuovo lo script. Trove-
rete che vi sono due intestazioni nuove. Per esempio:

[andy@basil scripts]$ ./header.py http://localhost:8080/test.gif GET


...
Cache-Control: max-age=3600
Expires: Thu, 04 Sep 2003 00:56:03 GMT on 2.2.2, linux2) Zserver/1.1
378 INDICE

NOTA: Sfortunatamente, Zope 2 non e conforme Request for Comments (RFC) riguardante le richieste HEAD.
Invece di spedire il set completo di intestazioni quando una richiesta HEAD viene spedita, i valori dal cache
manager sono persi. Quando intestazioni, dovreste sempre spedire la richiesta GET.
Per ulteriori informazioni sulle intestazioni HTTP e su come fanno riferimento al caching, vedate RFC 2616
presso http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html La Accelerated HTTP Cache Manager caches
una risposta intera, che funziona bene per items statici. Comunque, la pagina normale di Plone consiste di
elementi personalizzati, come il calendario, la barra di navigazione personale, e così via. In questa situazione,
avete bisogno di essere capace di abilitare la cache solo su una parte della pagina, e questo è dove RAM Cache
Manager diviene utile.
La RAM Cache Manager cache l’output di un oggetto in RAM così che alla prossima richiesta di questo script,
sarà prelevato dalla cache. Ripetute richieste di questo oggetto produrranno l’output prelevato dalla cache finché
la cache non espiri. Il punto di questo manager è che sta in realtà evitando complicati ricalcoli od ogni volta
grande calcoli; invece, sta conservando il risultato e lo sta riutilizzando. Questo Cache Manager non cache
immagini o file. Non bloccherà gli utenti che tentano di configurare la cache per fare ciò, ma non ha effetto su
questi oggetti.
Di default, Plone crea un RAM Manager chiamato RAMCache nella radice del vostro sito Plone. Per accedere a
questo oggetto attraverso la ZMI aprite le opzioni di gestione per la cache. Ciò che segue è tutto accettabile di
default, e non avete bisogno di cambiarlo inizialmente:

• Title: Questo è il titolo del manager di cache ed è opzionale.


• REQUEST variables: Queste sono le variabili che formano la condizione per la cache. Questa
è un opzione potente che permette alla cache di essere basata sulle variabili dell’utente. Per
esempio, se un item per essere cached richiede che dovrebbe essere differentemente cached per
ogni utente, od in lingue diverse, potete digitare le variabili di REQUEST che gradireste cache
qui.
• Threshold entries: Questo è il numero massimo di entrate che possono essere conservate nella
cache. Se la cache sta richiedendo troppa RAM, abbassate questo valore.
• Maximum age of a cache entry: Questo è l’ammontare di tempo (in secondi) che questo oggetto
rimarrà in cache.
• Cleanup interval: Questo è come spesso la cache viene pulita.

Poiché le richieste per l’oggetto di fatto giungono a Zope, questo non fa nulla per ridurre il traffico di rete; appena
causa a Zope per rendere il risultato più rapido. Selezionando la tab Statistics nella ZMI riporterà precisamente
le statistiche su quanti hits sono stati restituiti dalla cache e quanti sono stati passato sopra l’oggetto. Se anche
troppi hits sono passati sull’oggetto, potete considerare di modificare la configurazione della cache avendo meno
variabili REQUEST o aumentando il tempo usato nella cache.

14.2.9 Assegnare cache


Per aggiungere un oggetto che sia nel File System alla cache, semplicemente specifichi il nome della cache nel file
.metadata per quel oggetto. (nel capitolo 7 abbiamo trattato come utilizzare il file .metadata.) Plone fa questo già
su un gran numero di immagini, su CSS e su JavaScript. Per esempio, plone_skin/plone_images/pdf_icon.gif.metadata
legge come segue:

[default]
title=Pdf icon
cache=HTTPCache

Questo significa che l’immagine sarà cached usando HTTPCache. La maggior parte degli oggetti presenti nel
File System sarebbero più appropriati da aggiungere al HTTPCache, piuttosto che al RAMCache.
14.2. MIGLIORARE IL RENDIMENTO DI PLONE 379

14.2.10 Caching il tipo Content


Il caching dei tipi di contenuti è un pò più ingannevole e richiede l’uso di Caching Policy Manager. Plone installa
di default questo tool, e potete trovarlo nella radice dell’istanza Plone con lo ID caching_policy_manager.
Prima che possiate cache qualsiasi contenuto, dovete modificare i setting di cache per i template all’interno di
Plone. Di default Plone emette intestazioni per il contenuto che spengono qualsiasi cache per esso. Se non
eseguite ciò che segue, il resto di questa sezione non funzionerà. Se cliccate portal_skin e quindi cliccate plo-
ne_template, troverete il modello di pagina global_cache_settings. Questo viene utilizzato su ciascuna pagina
che usa il template principale di Plone. Il template corrente è come segue:

<metal:cacheheaders define-macro="cacheheaders">
<metal:block tal:define="dummy python:request.RESPONSE.setHeader ~CCC
’Content-Type’, ’text/html;;charset=%s’ % charset)" />
<metal:block tal:define="dummy python:request.RESPONSE.setHeader ~CCC
(’Content-Language’, lang)" />
<metal:block tal:define="dummy python:request.RESPONSE.setHeader ~CCC
(’Expires’, ’Sat, 1 Jan 2000 00:00:00 GMT’)" />
<metal:block tal:define="dummy python:request.RESPONSE.setHeader ~CCC
(’Pragma’, ’no-cache’)" />
</metal:cacheheaders>

Questo vuol dire che nulla è cached perché le intestazioni HTTP Pragma: no-cache e Expires sono stato settati.
Per disabilitare questo ed essere sicuri di selettivamente cache, personalizzare questo template e rimuovere le
direttive Pragma e Expires. Il vostro modello ora dovreste essere come segue:

<metal:cacheheaders define-macro="cacheheaders">
<metal:block tal:define="dummy python:request.RESPONSE.setHeader ~CCC
’Content-Type’, ’text/html;;charset=%s’ % charset)" />
<metal:block tal:define="dummy python:request.RESPONSE.setHeader ~CCC
(’Content-Language’, lang)" />
</metal:cacheheaders>

Una volta che avete fatto questo, potete continuare a cache selettivamente utilizzando il caching_policy_manager.
Accedere al tool attraverso la ZMI, e vedrete le seguenti opzioni:

• Policy Id: Questo è un Id unico per una polizza, usata solamente internamente.
• Predicate: Questa è un’espressione TALES per accoppiare il contenuto. La variabile contenuto
contiene l’oggetto che viene reso.
• Mod. Time: Questa è un’espressione TALES che valuta e ritorna un valore dall’oggetto da
usare per calcolare il tempo di modifica. La variabile contenuto contiene l’oggetto che è reso.
• Max age(secs): Questo è quanto tempo mettere la testata di cache per.
• Vary: Questo cambia l’intestazione da spedire (imparerete in un secondo tempo qualcosa al
riguardo nella sezione ”Usare Squid “).
• No-cache: Questo invia l’intestazione HTTP no-cache.
• No-store: Questo invia l’intestazione HTTP no-store.
• Must-revalidate: Questo invia l’intestazione HTTP must-revalidate.

Il seguente è un’esempio di polizza che può cache tutte le immagini sul sito:

• Policy ID: Images


380 INDICE

• Predicate: python:content.portal_type==’Image’
• Max age (secs): 3600

Lasciate tutti gli altri campi vuoti, e selezionate Add per aggiungere questa polizza. La caching_policy_manager
ora mostra qualche cosa come in figura 14-8.

Figura 14-8. Il caching_policy_manager con la polizza Image aggiunta


Per testarla correttamente, avete bisogno di aggiungere un’immagine nel vostro sito attraverso l’interfaccia Plone.
Le immagini saranno spedite con le intestazioni adatte se chiamate la vista:
test.gif

~/header.py http://localhost/test.gif/view GET


Cache-Control: max-age=3600
Connection: close
Content-Language:
Content-Length: 19810
Content-Type: text/html;charset=utf-8
Date: Fri, 05 Sep 2003 18:42:44 GMT
Etag:
Expires: Fri, 05 Sep 2003 19:42:44 GMT
Last-Modified: Fri, 05 Sep 2003 18:33:41 GMT
Pragma: no-cache
Server: Zope/(unreleased version, python 2.2.2, linux2) ZServer/1.1

Come vi aspettavate, le intestazioni Last-Modified e Expires ora sono state inviate. Modificando i predicati ed ag-
giungendo polizze multiple, potete sviluppare, un sistema di caching piuttosto sofisticato. Per regole complicate,
potete, chiaramente, passare maneggiando attraverso un oggetto Script (Python) se così desiderate. Per esempio,
se il predicato è il seguente:

python: here.myCachingRules(content)

poi aggiungete uno script (Python) chiamò myCachingRules per calcolare queste regole. Per esempio:
14.2. MIGLIORARE IL RENDIMENTO DI PLONE 381

##parameters=content
# cache all files, images and anything
# thats published
if content.portal_type in [’File’, ’Image’]:
return 1
if content.review_state in [’published’,]:
return 1

In questo script sono in caching tutti i file e le immagini, e qualunque cosa che sia nello stato pubblicato, mettendo
le intestazione HTTP attraverso il Caching Policy Manager.

14.2.11 Esempio: Caching su ZopeZen.org


Quando abbiamo sviluppato il sito http://www.zopezen.org, c’era un problema notevole. La pagina principale di
ZopeZen che elenca i posts ed il numero di repliche è costosa da generare. In Plone, non v’è nessun via facile
per calcolare efficientemente dal catalogo il numero di repliche di discussione ad un item.
Questa è una situazione ideale per il RAM Cache Manager. Finchè il traffico che aggiunge items di notizie o posts
sia piuttosto piccolo, forse uno o due al giorno, sembra ragionevole che durante un periodo di 30 minuti, la pagina
frontale non cambierà di molto. La funzione che trova le notizie e le repliche è chiamata getNewsAndReplies, e
effettua il compito di trovare tutti i dati che necessitato per il modello index_html.
Il modello index_html ha elementi che sono specifici per l’utente; per esempio, il box di login sul lato sinistro
mostra agli utenti quali opzioni hanno. Questo vuol dire che usando il Accelerated HTTP Cache Manager o
caching l’intero template usando il RAM Cache Manager non funzionerebbe. Questo causerebbe per gli utenti
di vedere altri opzioni degli utenti.
Invece, lo skin ZopeZen cache l’oggetto Script (Python) getNewsAndReplies aggiungendolo al RAM Cache
Manager. Facendo così ci si assicura che la maggior parte del lavoro costoso per rendizzare la pagina è in cache.
Siccome gli items di notizie saranno gli stessi per qualsiasi utente, non c’è punto in caching basato su qualsiasi
variabile di REQUEST, così AUTHENTICATED_USER sono state rimosso dalla lista delle variabili REQUEST
per la cache. Profilando la pagina frontale rivela che senza la cache potete produrre al secondo 1.06 richieste.
Con il caching, il sito può produrre al secondo 4.96 richieste che rappresentano una differenza significativa per
un modifica minore.

14.2.12 Usare server di caching


Siccome ora potete inviare intestazioni di cache secondo regole sofisticate, ora potete usare un altro server per
cache le richieste per Plone. Come veloce come Zope è, non sarà mai più veloce di Apache, Squid, o IIS nel
servire contenuto. Questi server possono servire contenuti statici e cached rapidamente e semplicemente. In parte
perché questi server sono scritti in C, ma anche perché lavorano meno per ciascuna richiesta. Non c’è nessun
controllo di sicurezza, lookups del database, o negoziazioni di linguaggio da eseguire. Inoltre, come avete letto
nel capitolo 10, avete anche già installato un server proxy.

Usare Apache

Apache è il server Web standard open source. Le seguenti sezioni documentano tecniche usando il server Apa-
che 2.0 su Linux. Con solamente leggere modifiche di sintassi, la maggior parte di queste appunti funzionano
con la 1.3. Per ulteriori informazioni sul server Apache e su diverse piattaforme, per favore vedete l’eccelente
documentazione Apache presso http://www.apache.org.
L’abilità di decomprimere o gzip le vostre pagine è utili per salvare larghezza di banda. Prima che una pagina sia
inviata dal server, verrà spedito il filo, ove il client decomprimerà la pagina. Questo rende le pagine più rapide
382 INDICE

da scaricare ed incorre in meno cambiamenti di larghezza di banda per il proprietario del sito visto che i file sono
più piccoli. Prima, abilitate il modulo mod_deflate. Questo dipenderà dalla vostra particolare installazione. Per
esempio, su Linux fate come segue:

LoadModule cache_module modules/mod_deflate

Secondo, aggiungete solamente ciò che segue alla vostra configurazione del server per sgonfiare ogni Hypertext
Markup Language (HTML), Extensible Markup Language (XML), e semplice testo:

AddOutputFilterByType DEFLATE text/html text/xml text/plain

Alcuni client si occupano in modo leggermente differentemente dello sgonfiamento, così leggete la documenta-
zione mod_deflate per ulteriori dettagliati esempi (http://httpd.apache.org/docs-2.0/mod/mod_deflate.html).
Nelle sezioni precedenti avete visto come potete inviare intestazioni di espirazione manipolando tools in Plone.
Apache può anche inviare facilmente queste intestazioni usando la direttiva ExpiresActive; questa è un’alternativa
ad usare i vari tools Plone. Per settare la scadenza delle intestazioni a 24 ore da ora per tutte le immagini, per
esempio, potete aggiungere ciò che segue alla vostra configurazione del sito Apache:

ExpiresActive On
ExpiresByType image/gif "access plus 1 day"
ExpiresByType image/png "access plus 1 day"
ExpiresByType image/jpeg "access plus 1 day"

Potete trovare ulteriori informazioni su mod_expires presso http://httpd.apache.org/docs-2.1/mod/mod_expires.html.


Apache viene rilasciato con molti sistemi che possono effettuare caching per voi. Il modulo Apache standard
mod_cache ha due modalità di fare caching: memoria e disco. Questa cache tutte le pagine richieste dato un set
di parametri per l’ammontare di tempo determinato. Per settare un disk cache nella cartella /tmp/apache_cache,
aggiungete ciò che segue alla configurazione del sito:

CacheRoot /tmp/apache_cache
CacheEnable disk /
CacheSize 256
CacheDirLevels 5
CacheDirLength 3

Sfortunatamente, provare che Apache stia attualmente caching il contenuto può essere un pò difficile; forse il
modo più semplice per verificarlo è osservare il file di log z2.log in Plone e vedere se viene colpito. Potete
trovare ulteriori informazioni su mod_cache presso http://httpd.apache.org/docs-2.0/mod/mod_cache.html.

Usare Squid

Squid è un proxy server open source che viene usato comunemente con Zope. Abilita per accelerare Zope
mediante caching di contenuto che viene prodotto all’interno di Squid così che richieste multiple sono fornite da
Squid, non daZope. Di nuovo, in quando Squid non rende contenuto dinamico ed è scritto in C, potete rispondere
molto più rapidamente. Nel capitolo 10 abbiamo trattato dell’installazione di Squid e del suo uso come proxy.
Se userete Squid per accelerare Plone, allora per favore vedete quel capitolo per informazioni su come preparare
un proxy Squid.
Come avete visto precedentemente in questo capitolo, potete mettere pressocché qualsiasi informazione che
volete nelle intestazioni HTTP usando Caching Policy Manager ed il Accelerated HTTP Cache Manager. Ora
Squid agirà in maniera simile ad una cache browser. Quando viene richiesta una pagina, se queste intestazioni
14.2. MIGLIORARE IL RENDIMENTO DI PLONE 383

sono presenti in cache, Squid cache la pagina. Ripetute hits provocheranno Squid per ritornare la pagina, non
Plone.
È relativamente semplice vedere se una pagina è stata cached. Squid aggiungerà un’intestazione X-Cache alla
risposta. Usando lo script header.py, potete vedere se la pagina è stata con successo cached. Un HIT vuol dire
che una copia di cached è stata trovata in Squid e ritornata; se nessuna copia è stata trovata nella cache e Plone
viene consultato, un MISS viene riportata. Per esempio:

X-Cache: HIT from www.agmweb.ca

Squid mostra numeri impressionanti in testing nell’ambiente di sviluppo, accelerando la view di una pagina
Plone che è cached da circa 2 richieste al secondo a più di 25 richieste. Su server veloci, gli utenti hanno
riportato velocità di più di 200 richieste al secondo con agio relativo.

Pulire la cache Squid

Quando un utente modifica un oggetto, esso è cambiato in Plone; comunque, poiché questo oggetto è cached
in un precedente stato, la cache contiene una versione vecchia. Gli utenti che accedono al sito troveranno la
vecchia versione piuttosto che la nuova versione. Con cache sotto il vostro controllo (come Squid), potete
spedire comandi di PURGE al server di caching per dirgli di rimuovere gli oggetti dalla cache.
Per il Accelerated HTTP Cache Manager, aggiungete lo URL delle cache al Notify URLs (via PURGE). Un
esempio è il seguente:

http://192.168.1.1:80/example.org

In questo esempio, l’IP è l’indirizzo della cache, ed il dominio è il sito da essere ripulito. Per Squid per eseguire
la direttiva PURGE, dovete essere sicuri che Squid sia configurato. Se Squid fosse su localhost, questo sarebbe
come segue:

acl PURGE method purge


http_access allow localhost
http_access allow purge localhost
http_access deny purge
http_access deny all

Il Caching Policy Manager non ha attualmente meccanismo di PURGE, sebbene il Collective ha un nuovo tool
chiamato CMFSquidTool che fa questo lavoro per voi. Guarda per le modifiche sul contenuto e quando questo
succede invia un purge alla cache Squid per voi. Non abbiamo provato ancora questo nuovo tool, ma vale la pena
di dare un’occhiata se sta usando Squid.

Evitare di dovere pulire la cache Squid

Il miglior modo di evitare di ripulire la cache è di essere più selettivi sul caching. Il Caching Policy Manager ed
il RAM Cache Manager, offrono metodi per essere selettivo intorno a cosa ritornare da una cache.
Il Caching Policy Manager e Squid, supportano il tag Vary. Se un tag Vary viene specificato, Squid estrarrà
le intestazioni specificate nel tag Vary dalla richiesta. Queste intestazioni controllano di nuovo la cache – se
corrispondono, la pagina è restituita dalla cache. Se non corrisponde, allora la richiesta viene passata attraverso
la catena di Plone.
Per esempio, nel Caching Policy Manager il tag Vary ha il valore di Accept-Language. Quando una richiesta
entra in Squid, la pagina sarà cached secondo Accept-Language settata nell’intestazione di richiesta. Quando un
384 INDICE

utente richiede una pagina con un setting diverso, una pagina nuova verrà ritornata. Questo vuol dire che puoi
cache le pagine basate su linguaggio.
Il valore meno aggressivo per Vary è * , che cache qualsiasi richiesta che è la stessa come qualsiasi altra richiesta.
Richieste diverse sono passate diritte a Plone. Sebbene questo sia il sistema di caching meno aggressivo, è sicuro
che l’utente veda il contenuto solamente più recente.
Il metodo REQUEST di RAM Cache Manager è lo stesso concetto di Vary eccetto che il tool accetta un lista di
variabili request di Zope. Il risultato di un lookup della cache è basato poi su queste variabili. Il valore di default
è AUTHENTICATED_USER che vuol dire che ciascun utente autenticato vedrà la propria versioni della cache.
Gli utenti di non registrati (anonimo) vedranno tutti lo stesso contenuto.

14.3 Usare Zope Enterprise Objects (ZEO)


Il finale fondamentale per scalare ed amministrare Plone sta nell’usare Zope Enterprise Objects (ZEO). Questo è
un tool fondamentale in molte area di Plone per lo sviluppo e la produzione. Molte persone pensano che dovrebbe
essere l’installato di default in Plone, e può essere così un giorno. Per il momento, comunque ZEO viene
rilasciato con Plone su Linux ma non viene installato. Funziona anche in Windows ma non è completamente
supportato con servizi o con una facile installazione.
In una configurazione standard di Plone, c’è un’istanza di Plone che parla con un’istanza del file ZODB. Fino
a che un’istanza di Plone sta accedendo al file ZODB, esso è bloccato e nessun altro processo può accedervi.
Questo limita la dimensione del sito e crea un solo punto di fallimento. Nel mondo dei database relazionali,
questo sarebbe equivalente ad un solo processo capace di accedere al vostro database.
ZEO rompe questo collegamento e separa l’accesso del file ZODB (chiamato il server ZEO)

Figura 14-9. Un’installazione di ZEO standard


Poiché processi multipli sono capaci di connettersi ad un ZODB, ora è capace di avere molte copie Plone. In
essenza ora potete avere due o tre istanze di Plone che condividono tutti lo stesso contenuto. Non solo facendo
questo potete spalmare sul carico del vostro sito
14.3. USARE ZOPE ENTERPRISE OBJECTS (ZEO) 385

Finalmente, un punto minore è che il tempo di riavvio per un client di ZEO è molto rapido. Il costo di dovere
caricare il database è stato rimosso, che vuol dire che potete riavviare i siti Plone rapidamente.

14.3.1 Installare ZEO


ZEO è incluso con Zope 2.7, la versione di Zope supportata da questo libro. Nelle versioni precedenti di Zope,
è stato distribuito separatamente. Al momento non vi è nessun modo facile di installare ZEO su Windows – lo
script mkzeoinstance non lavora bene; ZEO stesso lavora più che bene, ma dovrete leggere il sorgente di ZEO
per vedere come fare ciò. In aggiunta, zopectl non funziona su Windows, ricordate che gli esempi seguenti non
funziona.

Linux

Per creare un server ZEO, usate lo script mkzeoinstance localizzata nella directory /opt/Zope-2.7/bin. Questo
presume che Zope sia già installato, come descritto nel capitolo 2. Lo script richiede i seguenti parametri:

• Directory: Questa è la directory in cui creare l’instanza di server ZEO.


• Host: Questo è lo host e la porta per il server in ascolto, nel formato host:port. La porta sarà
la porta ove i client ZEO si connettono e dovrebbe essere protetta da un firewall, in quando
ZEO non offre sicurezza contro gli accesso non autorizzato. Questi sono opzionali. La porta
di default è 9999.
• User e password: Questa è l’utente di default e password per il server nel formato user:password
ed è opzionale.

Per esempio, ciò che segue installerà ZEO a /var/zeo sulla porta di default:

cd /opt/Zope-2.7/bin
./mkzeoinstance /var/zeo

Questo ha creato un nuovo database con tutta la configurazione appropriata. Questo database è una nuova localiz-
zazione, ma questo sta bene. Se volete trasferirsi un’installazione di Zope esistente a ZEO, allora avrete bisogno
di fermare la marcia di Zope e poi trasportare il database dalla vostra vecchia installazione nella nuova directory
di ZEO. Nel nostro caso che ricordiamo vogliamo trasportare il file Data.fs da /var/zope/var a /var/zeo/var.
Successivamente avete bisogno di modificare la configurazione della vostra istanza di Zope. Per fare questo,
aprite il file zope.conf in ect e digitate le seguenti informazioni:

# ZEO client storage:


#
<zodb_db main>
mount-point /
<zeoclient>
server localhost:9999
storage 1
name zeostorage
var $INSTANCE/var
</zeoclient>
</zodb_db>

Nel codice precedente state mettendo la porta ed il server dove il Server ZEO può essere trovato. Avete bisogno
inoltre di fare commenti fuori dalla mappa esistente al database locale. Questo è dovrebbe sembrare come segue:
386 INDICE

#<zodb_db main>
# # Main FileStorage database
# <filestorage>
# path $INSTANCE/var/Data.fs
# </filestorage>
# mount-point /
#</zodb_db>

Per testare come questo funziona, prima avviate il server ZEO. Questo può richiedere più permessi che utente
che ha installato come:

$ cd /var/zeo/bin
$ ./zeoctl start
daemon process started, pid=29316

Il daemon ZEO ha iniziato con successo. Ora spari su un client Zope, e tenti di connettersi a lui, così come:

$ cd /var/zope/bin
$ ./zopectl start
daemon process started, pid=29338

Questo vuol dire che le cose sono andate bene, ed ora potete accedere come al solito al vostro Plone.

14.3.2 Usare client ZEO


In questa configurazione, si accede al file ZODB attraverso il server ZEO, ed ciascuna istanza di Zope è un client
ZEO. Diversi client ZEO possono essere connessi al server. Non c’è bisogno per il client e per il server di essere
sullo stesso computer, finché il client può effettuare un collegamento al server. Se i clienti sono sullo stesso
computer, ogni client ha bisogno di linkarsi su una diversa porta HTTP e FTP per evitare conflitti fra di loro.
Quando il vostro client inizia, si connetterà allo storage specificato nella vostra configurazione invece dello
storage standard locale. Un requisito comune è permettere ad un secondo computer di eseguire compiti intensivi,
come aggiornare il catalogo, comprimere il database, o compiere complessi lookups, senza causare degradamento
nel rendimento dell’altro client. Questo è davvero facile da fare usando la funzione zopectl:

$ cd /var/zope/bin
$ ./zopectl debug
Starting debugger (the name "app" is bound to the top-level Zope object)

Per comprimere il database, potete fare così:

>>> app.Control_Panel.Database.manage_pack(days=0)

Poiché state lavorando su un client ZEO, devete informare il server che una modifica è stato eseguita e che la
cache deve essere aggiornata. Per completare l’operazione, fate questo:

>>> get_transaction().commit()
>>> app._p_jar.close()

Questa è davvero una cosa utile da effettuare se state eseguendo un sito ad alto rendimento ed avete bisogno di
comprimere il database. Il sito funzionerà un pò più lentamente quando l’operazione è commessa, ma la maggior
parte del lavoro duro avverrà sul client che sta effettuando il packing. Questa può essere una macchina totalmente
separata dal vostro sito e potrebbe essere un modo eccellente di distribuire il carico.
Per eseguire il debug, è estremamente utile arrivare a questo prompt, come ora potete esaminare gli oggetti interni
all’oggetto app. Troverete che corrispondono agli oggetti che vedete nella ZMI. Per esempio:
14.3. USARE ZOPE ENTERPRISE OBJECTS (ZEO) 387

>>> app.objectIds()
[’acl_users’, ’Control_Panel’, ’temp_folder’,...

Quale è l’API per quel oggetto app? Potete usare la funzione incorporata (built-in) dir in Python per esaminare
l’oggetto ed anche usare il metodo __doc__ per vedere le stringhe di commento contenute in là, così come:

$dir(app)
>>> dir(app)
[’COPY’, ’COPY__roles__’, ’Control_Panel’, ’DELETE’,...
>>> app.valid_roles.__doc__
’Return list of valid roles’

Un buon esempio di un’applicazione basata su ZEO è CMFNewsFeed (http://sf.net/projects/collective). Questo


si connette a Plone usando un client ZEO. Quel client separato va poi e raccoglie tutte le notizie inserite che
può trovare ed può inserire i dati nel sito. Questo assicura che, facendo tutta la ricerca e la catalogazione in un
processo separato, il rendimento del sito principale non sia degradato.
ZEO è un tool indispensabile per gli sviluppatori. Permette di interagire quando si programma con il vostro
server mentre è in eseguzione. Se siete ancora confusi, a questo punto, su Plone e sul database ad oggetti, allora
per i programmatori esperti ZEO è un normalmente una rivelazione.

14.3.3 Bilanciamento del carico e failover


Anche se ZEO offra la possibilità di eseguire Plone su molti server, non offre alcuna funzionalità di bilanciamento
del carico per l’utente. Il bilanciamento del carico è la possibilità di inviare richieste entranti a diversi server e
distribuire fuori il carico per produrre le pagine. Sofisticati tools controllano per vedere se il server sta inviadogli
prima una richiesta.
Avete opzioni hardware e software per bilanciamento del carico. Per esempio, Squid può effettuare failo-
ver dinamico. Pounds è un esempio di programma per il bilanciamento del carico; potete trovarlo presso
http://www.apsis.ch/pound/index.html.
L’ Internet Cache Protocoll (ICP) è un protocollo che Squid può utilizzare per controllare che un sito Plone stia
funzionando prima di inviargli una richiesta. In siti estremamente dinamici, questa può essere una necessità.
Potete trovare ulteriori informazioni su ICP e Zope presso http://www.zope.org/Members/htrd/icp/intro.
388 INDICE
Elenco delle figure

Capitolo 15.

389
390 ELENCO DELLE FIGURE
Capitolo 15

Docutils System Messages

Duplicate target name, cannot be used as a unique reference: ”capitolo 9“.


Duplicate target name, cannot be used as a unique reference: ”capitolo 9“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 3“.
Duplicate target name, cannot be used as a unique reference: ”appendice a“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 9“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 9“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 9“.
Duplicate target name, cannot be used as a unique reference: ”appendice a“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 9“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 9“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 9“.
Duplicate target name, cannot be used as a unique reference: ”appendice a“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 9“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 9“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 3“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 9“.
Duplicate target name, cannot be used as a unique reference: ”appendice a“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 9“.
Duplicate target name, cannot be used as a unique reference: ”appendice a“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 5“.
Duplicate target name, cannot be used as a unique reference: ”appendice b“.
Duplicate target name, cannot be used as a unique reference: ”appendice b“.
Duplicate target name, cannot be used as a unique reference: ”appendice b“.
Duplicate target name, cannot be used as a unique reference: ”appendice b“.
Duplicate target name, cannot be used as a unique reference: ”appendice b“.
Duplicate target name, cannot be used as a unique reference: ”appendice b“.

391
392 CAPITOLO 15. DOCUTILS SYSTEM MESSAGES

Duplicate target name, cannot be used as a unique reference: ”appendice b“.


Duplicate target name, cannot be used as a unique reference: ”capitolo 9“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 9“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 3“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 3“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 5“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 9“.
Duplicate target name, cannot be used as a unique reference: ”appendice b“.
Duplicate target name, cannot be used as a unique reference: ”appendice a“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 3“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 3“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 3“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 3“.
Unknown target name: ”integrare plone con il file system“.
Unknown target name: ”installare prodotti in plone“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 3“.
Duplicate target name, cannot be used as a unique reference: ”capitolo 9“.

View document source. Generated on: 14/03/2005 09:27 UTC. Generated by Docutils from reStructuredText source.

Potrebbero piacerti anche