Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Versione italiana
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
5
6 CAPITOLO 1. CAPITOLO 1: INTRODUZIONE A PLONE
Indice
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
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.
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.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.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.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.
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
“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
$ 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
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:
$ python hello.py
Hello, world!
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
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:
Plone funziona perfettamente anche nei seguenti browser ma potrebbe differire dall’originale:
• Netscape 4.*x*
• Microsoft Internet Explorer 5.0
19
20 INDICE
• 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).
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
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‘_.
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.
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.
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.)
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.
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
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.
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
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:
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.
$ 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:
/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
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.
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.
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).
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:
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.
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
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.
<http-server>
# valid keys are "address" and "force-connection-close"
address 8080
# force-connection-close on
</http-server>
<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
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.
<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
37
38 CAPITOLO 3. CAPITOLO 3: AGGIUNGERE E MODIFICARE I CONTENUTI
Indice
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.
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 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
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.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).
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
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.
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.
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.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
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
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.
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.
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.
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
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).
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.
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.
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
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.
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.
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
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.
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.
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).
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
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:
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.
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.
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
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).
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
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.
81
82 INDICE
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:
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.
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.
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.
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:
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).
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).
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.
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).
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).
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.
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.
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).
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).
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:
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.
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.
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)
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.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.
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
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.
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.
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
• View
• portal_tabs
• selected
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.
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).
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
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.
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.
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
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:
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
113
114CAPITOLO 5. CAPITOLO 5: INTRODUZIONE ALLA MODELLAZIONE IN PLONE (PLONE TEMPLATE)
Indice
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
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.
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.
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.
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
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
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:
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:
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:
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:
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.
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.
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.
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:
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:
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:
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.
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.
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
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).
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.
Title: il titolo per il modello, è opzionale. Se si modifica, nel precedente esempio, si nota come nella scheda
Test l’HTML risultante sia diverso.
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:
Quindi accediamo alla scheda Test per verificare se funziona. Si dovrebbe ottenere quanto segue:
126 INDICE
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:
Questo crea l’HTML appropriato per includere l’immagine e la mostrerà nella pagina.
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.
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>
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:
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>
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.
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
• un dizionario vuoto
• il valore None di python
• il valore nothing di TALES
• il valore default
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:
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:
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.
L’istruzione tal:define permette di creare variabili che potranno essere utilizzate all’interno del modello. Per
esempio:
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:
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:
È 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‘_.
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:
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:
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
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>
• 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
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
<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>
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
L’istruzione tag:replace è simile all’istruzione tal:content, con una differenza: rimuove il tag.
Per esempio:
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.
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.
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:
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
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.
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
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>
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>
<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>
<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
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>
...
<div metal:fill-slot="main">
...
</div>
Se ritorniamo di nuovo al main_template, vedremo che contiene una definizione define-slot per lo slot main:
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:
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.
<i>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:
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:
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>
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
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
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.
<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.
<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
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
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:
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.4: Figura 6-4. Un deliberato errore di indentazione nell’oggetto Script (Python)
6.2. SCRIVERE CODICE PYTHON PER PLONE 157
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:
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:
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 = []
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).
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:
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
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
<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à:
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.
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
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:
#!/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:
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.
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
<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
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.
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
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
<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:
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’)
%s
URL: %s """
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:
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:
<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:
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’)
%s
URL: %s """
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:
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
177
178 CAPITOLO 7. CAPITOLO 7: PERSONALIZZARE L’ASPETTO DI PLONE
Indice
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.
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).
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.
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).
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.
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à.
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.
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).
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
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:
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
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.
<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">
<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;
}
#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
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.
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.
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.
$ 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.
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.
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.
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.
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
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.
[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.
[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:
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
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:
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
action.success..button1 = traverse_to:string:script1
In questo esempio non abbiamo alcun contesto esplicito, quindi è valido per qualsiasi tipo di contesto.
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.
<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
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.
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.
#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.
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
217
218 CAPITOLO 8. CAPITOLO 8: GESTIRE IL CONTROLLO DI FLUSSO (WORKFLOW)
Indice
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.
• 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.
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:
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.
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
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
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
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
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.
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
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
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.
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.
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.
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
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
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.
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
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.
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à:
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
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.
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.
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:
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
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:
python:state_change.kwargs.get(’comment’, ’’)
container/Title
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
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.
##parameters=state_change
# get the object and its ID
obj = state_change.object
id = obj.getId()
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
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
##parameters=state_change
# the objects we need
object = state_change.object
mship = context.portal_membership
mhost = context.MailHost
administratorEmailAddress = context.email_from_address
%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:
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)
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
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
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.
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:
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
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
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 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 ).
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.
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.
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
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.
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
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.
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
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.
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.
Figura 9.7: Figura 9-7. Impostare il ruolo di revisore per il gruppo Supervisor
258 INDICE
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.
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.
Figura 9.8: Figura 9-8. Iscrizione di un utente con la validazione della email abilitata
260 INDICE
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:
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.
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.
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
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.
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
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
È 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.
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.
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.
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.
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.
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).
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
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:
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.).
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:
def importUsers(self):
reader = csv.reader(open(fileName, "r"))
pr = self.portal_registration
pg = self.portal_groups
out = []
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.
ignoreLine = 0
continue
# 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)
# 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!
• 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)
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
##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
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:
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!
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:
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:
VerboseSecurity
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.
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
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ì).
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
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:
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.
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.
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:
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:
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.
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
285
286 CAPITOLO 10. CAPITOLO 10: INTEGRAZIONE CON ALTRI SISTEMI
Indice
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
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
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.
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.
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.
$ 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
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.
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‘_.
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.
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.
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:
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]
• 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.
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:
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
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
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:
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.
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"
zopeAddress = "http://192.168.2.1:8080"
zopePath = "/"
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
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.
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.
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.
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.
Fare questo con IIS è facile perché IIS, automaticamente, controlla prima per vedere se il file esiste pri-
ma di sollevare un errore
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:
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.
<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.
<webdav-source-server>
address 1980
</webdav-source-server>
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
Figura 10.11: Figura 10-11. Accedere al nostro contenuto Plone usando WebDrive
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
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:
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:
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
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
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.
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
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.
319
320 INDICE
Capitolo 12
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
325
326 CAPITOLO 13. CAPITOLO 13: SVILUPPARE CON ARCHETYPES
Indice
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.
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
Nota
Solitamente, l’installazione eseguita in questo modo richiede su Unix i diritti di root per
installare nella cartella Python.
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
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.
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
),
# 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:
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:
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:
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.
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:
Tutti i widgets sono instanziati allo stesso modo – creando un widget e passando in parametri fondamentali come
necessita. Per esempio:
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)
)
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.
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’),
)
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
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:
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:
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:
class DateRangeValidator:
__implements__ = (ivalidator,)
Dopo riavviate Zope, ora potete registrare una nuova validazione, come:
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",)
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:
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"
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
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.
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:
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 >
def install(self):
out = StringIO()
13.3. SVILUPPARE CON ARCHETYPES 345
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.
##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.
<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>
</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:
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:
StringField(’email’,
validators = (’isEmail’,),
widget = EmailWidget(
label=’Email’,
)
)
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:
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.
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.
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:
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.
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.
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
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
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
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
• 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.
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
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:
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
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.
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.
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:
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:
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:
/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.
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 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ò.
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
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:
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.
ab http://localhost/
Il tool ab produrrà in output delle informazioni prima sul sito esaminato, così come:
Document Path: /
Document Length: 20594 bytes
14.2. MIGLIORARE IL RENDIMENTO DI PLONE 367
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:
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.
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.
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>
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:
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.
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.
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.
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>
<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.
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.
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.
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
• 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
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:
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:
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.
[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
<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:
• 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.
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.
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:
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:
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"
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:
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.
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:
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.
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.
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.
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:
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:
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.
$ cd /var/zope/bin
$ ./zopectl debug
Starting debugger (the name "app" is bound to the top-level Zope object)
>>> 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’
Capitolo 15.
389
390 ELENCO DELLE FIGURE
Capitolo 15
391
392 CAPITOLO 15. DOCUTILS SYSTEM MESSAGES
View document source. Generated on: 14/03/2005 09:27 UTC. Generated by Docutils from reStructuredText source.