Documentazione di PloneRelease 4
La comunitagrave Italiana di Plone
July 31 2015
Contents
1 Plone 4 Manuale utente 111 Introduzione 112 Aggiungere contenuti 2013 Gestione dei contenuti 4914 Usare TinyMCE come visual editor 7915 Usare Kupu come visual editor 9216 Collaborazione e flusso di lavoro 10317 Utilizzo delle collezioni 11518 Gestione delle Portlet 128
2 Altri manuali 13521 Creare un tema con Diazo 13522 ZODB - un database nativo ad oggetti per Python 15123 La guida completa alla Zope Component Architecture 162
3 Credits e ringraziamenti 241
i
ii
CHAPTER 1
Plone 4 Manuale utente
Il manuale per utenti redattori e amministratori
11 Introduzione
Una panoramica dei concetti di Plone
111 Panoramica
Una spiegazione di Plone come content management system
Cosrsquoegrave Plone
Plone egrave un sistema di gestione dei contenuti (CMS) che permette di costruire un sito web Con Plone anche chi hapoca esperienza puograve contribuire alla creazione dei contenuti di un sito senza lrsquoaiuto di un mago del computer InoltrePlone ldquogira sul Webrdquo quindi non crsquoegrave bisogno di installare alcun software speciale sul proprio computer La parolacontenuto vuole essere generale in quanto egrave possibile pubblicare molti tipi di informazioni tra cui
Un sito web Plone contiene diversi tipi di contenuto compresi testi foto e immagini Questi possono esistere in molteforme documenti notizie eventi video file audio e tutti i tipi di file e dati che possono essere caricati o creati su unsito web I contenuti possono anche essere caricati dal proprio computer In un sito Plone puoi creare delle cartelleper raccogliere i contenuti e per definire una struttura di navigazione
Ti piacciono le farfalle
Ad esempio per pubblicare un contenuto sulle farfalle potresti creare una cartella denominata ldquoFarfallerdquo e poi ag-giungere del testo a una pagina Web nella cartella
Poi potresti caricare alcune foto di farfalle nella cartella
In una cartella puoi aggiungere vari tipi di contenuto comprese delle sotto-cartelle Dopo aver inserito alcune notizie evideo nella cartella Farfalle il contenuto potrebbe essere organizzato in questo modo con due sottocartelle allrsquointernodella cartella Farfalle
1
Documentazione di Plone Release 4
2 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Cosa succede dietro le quinte
Ci si potrebbe chiedere come funziona tutto questo Un tipico sito web Plone esiste come installazione del softwarePlone su un server web Il web server puograve essere ovunque spesso si trova su un server di societagrave specializzateallrsquointerno di un ldquorackrdquo di computer dedicati al compito
Il diagramma mostra i cavi che collegano i singoli server a Internet attraverso connessioni di rete veloci Il sito Ploneegrave prodotto da del software e da un database installati su uno dei server Quando digiti o clicchi sul tuo computer i dativengono inviati su e giugrave per i cavi di rete e dei canali di comunicazione di Internet per interagire con il software Ploneinstallato sul server
Ora semplifichiamo un pograve il diagramma che mostra come interagire con Plone
Puoi utilizzare il tuo browser web - Firefox Safari Internet Explorer ecc - per visualizzare e modificare il tuo sitoweb Plone e le modifiche vengono memorizzate dal software Plone nel suo sistema di archiviazione
Per esempio immagina che il tuo sito web Plone sulle farfalle si trovi su mysitecom In questo caso dovresti digitarewwwmysitecom nel tuo web browser Dopo aver premuto Invio inizia la seguente sequenza di eventi quando il tuobrowser ldquoparlardquo con il server web su mysitecom
e il sito Plone risponde con
Plone legge il suo database per cercare informazioni memorizzate in mysitecom Quindi restituisce la pagina web altuo computer in un codice chiamato HTML HTML egrave un linguaggio per computer che descrive come una pagina webappare Include testo grafica font il colore dello sfondo e tutto il resto Ci sono molte risorse online che possonoinsegnarti i dettagli di HTML ma uno dei vantaggi di Plone egrave che non crsquoegrave bisogno di sapere (molto) di HTMLQuesto egrave uno dei motivi per cui esistono Plone e altri software web simili perchegrave ti permettono di concentrarti sui tuoicontenuti come testo e grafica delle farfalle invece di imparare un nuovo linguaggio del computer
Ma torniamo alla nostra panoramica Il tuo browser ldquorenderizzardquo (traduce) questo HTML e viene visualizzata laseguente pagina web
11 Introduzione 3
Documentazione di Plone Release 4
4 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
11 Introduzione 5
Documentazione di Plone Release 4
6 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
11 Introduzione 7
Documentazione di Plone Release 4
Mentre stai guardando la pagina web della tua farfalla puoi decidere di cambiare o aggiungere nuovo testo Egrave inoltrepossibile caricare foto documenti ecc in qualsiasi momento
Dopo aver effettuato le modifiche e premuto su ldquosalva modificherdquo la nuova versione della pagina web saragrave immedi-atamente disponibile per chiunque navighi sul tuo sito
112 Design Grafico dei Siti Web Plone
Plone permette agli amministratori e ai designer dei siti web di creare design unici Ecco una panoramica dellayout Plone e alcuni esempi di design
Come dovrebbe apparire un sito web Plone Per anni crsquoegrave stato un design coerente per lrsquoaspetto predefinito di Plone Ildesign predefinito appare generalmente cosigrave
8 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
11 Introduzione 9
Documentazione di Plone Release 4
Il tuo sito web Plone potrebbe avere un design radicalmente diverso da questo ma dovresti essere in grado di trovareelementi comuni come il link al log-in e un pannello o menu di navigazione Nel design di default il menu dinavigazione si trova nella zona a sinistra e di solito appare come un elenco indentato delle cartelle del sito Ci puograveanche essere un insieme di schede nella striscia Log In Location Information in testata
Possiamo fare una distinzione tra il design e la funzionalitagrave di un sito web Per quanto riguarda i contenuti concentratisulla funzionalitagrave e non preoccuparti tanto dellrsquoaspetto e del layout del sito web Un punto di forza del sistema digestione dei contenuti Plone egrave che un sito web puograve essere radicalmente riprogettato con un nuovo look senza incideresul contenuto sottostante e sulle funzionalitagrave Il menu di navigazione potrebbe essere spostato da sinistra a destra mafunzionerebbe lo stesso Lrsquoarea di destra potrebbe essere cancellata se le funzionalitagrave che normalmente contiene nonsono necessarie Le aree sinistra centrale e destra come illustrato sopra e sotto potrebbero essere spostate in alto alcentro e in basso ma continuerebbe comunque a essere un sito web Plone
Useremo il design del layout di default di Plone come esempio di tipica divisione dello schermo
Potrebbe essere necessario adattare queste parti se servono per il design del tuo sito web Plone Ti potresti imbatterein diversi termini usati per descrivere le varie parti dello schermo come ad esempio ldquoslotrdquo sinistro e destro per lecolonne di sinistra e destra ldquoportletrdquo o ldquoviewletrdquo per zone o box specifici e molti altri termini
Per esempio selezioniamo tre siti web dalla lista di siti web Plone per fare un confronto
Questo egrave il sito web per Akamai un fornitore leader di strumenti web online e acceleration technology Lrsquoarea diintestazione ha un semplice menu testuale per cinque aree di contenuto principali disposte orizzontalmente nella parteinferiore dellrsquoarea di intestazione A destra lrsquointestazione contiene un altro menugrave orizzontale e una casella di ricercaLa parte inferiore dellrsquoarea di intestazione conterrebbe dati di accesso per lrsquouso da parte dei manutentori del sito Lagrafica principale in alto a sinistra egrave una zona di messa a fuoco per la grafica accattivante e gli argomenti attuali Crsquoegraveunrsquoarea principale al centro sinistra dove si trova il testo piugrave importante La colonna di destra contiene una serie dildquoportletrdquo Il piegrave di pagina contiene un menu orizzontale ripetendo le scelte di menu nellrsquointestazione per comoditagraveCrsquoegrave una colonna piugrave a destra che contiene le impostazioni di zoom
Questo egrave il sito web per Discover Magazine Lrsquoarea di intestazione contiene un menu orizzontale di grandi dimensioniil ldquomenu principalerdquo se si vuole chiamarlo cosigrave un menu orizzontale piugrave piccolo in alto a destra e una casella diricerca Questo sito egrave ricco di ldquoportletrdquo testuali che coprono molte aree tematiche divise in tre colonne sinistracentro e destra La parte superiore della colonna centrale contiene una zona focus con un video Ci sono grandi
10 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
11 Introduzione 11
Documentazione di Plone Release 4
12 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
box interattivi in diversi punti della pagina Il piegrave di pagina contiene le informazioni di identificazione di base delsito e un link al ldquochi siamordquo Per un grande sito web come Discover i manutentori del sito effettuano il log-in peraccedere a funzioni di editing personalizzate e crsquoegrave molta automazione nei flussi informativi - Plone utilizza Zope unsofisticato sistema di archiviazione e Python un celebre linguaggio di programmazione che facilita un intelligenteldquocollegamentordquo del flusso di testo e grafica nel sito web
Lrsquoultimo dei tre siti da esaminare egrave il sito web per lo Smeal College of Business della Penn State UniversityLrsquointestazione contiene un logo un menu orizzontale per le aree tematiche principali e una casella di ricerca a destraCrsquoegrave un menu principale per questo sito a sinistra il che egrave piugrave tradizionale per un sito web Plone Una vasta area graficacontiene unrsquoanimazione ldquorolling focusrdquo Crsquoegrave un altro piccolo focus grafico nella colonna di sinistra Tre colonne testu-ali completano il design al di sopra dellrsquoidentificazione di base a piegrave di pagina I manutentori di questo sito accedonoper mezzo di una pagina di log-in personalizzata con il log-in e le informazioni utente che appaiono lungo la parteinferiore dellrsquoarea piugrave in alto in testata
Allora come dovrebbe apparire un sito web Plone Tradizionalmente lrsquoaspetto out-of-the-box egrave simile a quellomostrato nella parte superiore di questa pagina con intestazione menu colonne e un piegrave di pagina Questi tresiti illustrano come i designer tipicamente combinano le aree di interesse i menu verticali e orizzontali ldquoportletrdquo econtenuti testuali di solito disposti in diverse colonne La struttura di base della pagina egrave generata da Plone Zope ePython ma il ldquotemardquo o ldquoskinrdquo di design puograve essere fatto risultare in qualunque modo il designer preferisca
113 Account e Ruoli di un utente Plone
In questo capitolo vedremo le basi di utilizzo di un account utente su un sito Plone la distinzione fra navigazioneanonima e quella autenticata e una descrizione dei ruoli degli utenti
11 Introduzione 13
Documentazione di Plone Release 4
I siti Plone possono essere di molti tipi dal sito personale con un solo utente ai portali di comunitagrave ed organizzazionicon centinaia di utenti Ogni persona che vuole aggiungere dei contenuti al sito deve avere un proprio account definitoda un nome utente e una password Alcuni siti Plone consentono di auto-iscriversi visitando il collegamento ldquoAccedirdquoe compilando un form con le proprie informazioni di base In altri siti invece gli account utente vengono creati solodagli amministratori del sito nel qual caso le persone normalmente ricevono un messaggio di posta elettronica con idettagli del loro nuovo account
In qualsiasi modo sia stato creato un account utente Plone permette sempre ad una persona di autenticarsi inserendoil proprio username e password Le password sono case-sensitive cioegrave la stessa lettera viene considerata diversa sescritta in maiuscolo o in minuscolo Ad esempio se la password egrave xcFGt6v lrsquoutente deve scrivere esattamente questapassword per potersi autenticare Le password con una buona variabilitagrave di caratteri sono preferibili a parole tropposemplici come ldquocanerdquo o ldquogiallordquo poichegrave sono piugrave difficili da indovinare e quindi sono piugrave sicure
Differenze tra navigazione anonima e autenticata
La distinzione tra navigazione anonima e navigazione autenticata egrave molto importante
Navigazione anonima
La navigazione anonima identifica la normale esperienza di un utente che naviga un sito web Si digita lrsquoindirizzo webdi un sito nel proprio browser e si visualizza la pagina si guardano video e immagini ma non egrave necessario autenticarsiEcco perchegrave questa viene chiamata navigazione anonima chiunque egrave anonimo prima dellrsquoautenticazione Da notareche la presenza del link Fatti riconoscere (ndt ldquoLog inrdquo in Inglese) nellrsquoangolo in alto a destra dellrsquoimmagine quisotto Se crsquoegrave un link ldquoFatti riconoscererdquo sulla pagina significa che non hai effettuato lrsquoaccesso e stai visitando il sitocome utente anonimo
14 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Navigazione autenticata
Se hai utilizzato il sito di una banca o qualsiasi altro sito che preveda lrsquouso di un account allora hai giagrave avutoesperienza di navigazione utenticata Il sito di una banca ad esempio ti permette di vedere le informazioni del tuoaccount di riempire dei form di trasferire dei fondi e altri tipi di operazioni ma tutto questo solo dopo aver effettuatolrsquoaccesso Un sito Plone non egrave molto differente ad eccezione del fatto che si possono fare cose piugrave complesseDai unrsquoocchiata allrsquoimmagine qui sotto catturata dopo che un utente ldquoMario Rossirdquo ha effettuato lrsquoaccesso Vicinoallrsquoangolo in alto a destra puoi vedere il link con il nome di Mario Rossi e un link di uscita Unrsquoaltra differenzaimportante che si nota quando si egrave autenticati egrave che nellrsquoarea principale al centro crsquoegrave una barra verde con dei tab (oschede) Questa specie di striscia di testa egrave presente quando un utente ha i permessi per modificare lrsquoarea del sito chesta visitando I tab nella striscia verde potrebbero variare ma avranno sempre questo aspetto e questo caratteristicocolore Nella seguente immagine lrsquoutente Mario Rossi si egrave autenticato in un nuovo sito Plone
Ruoli utente
In un sito Plone egrave molto importante la distinzione dei diversi ruoli degli utenti Per illustrare il caso piugrave sempliceconsideriamo due ruoli utente collaboratore e manager Vediamo i diversi permessi o ldquopoterirdquo di questi due ruoli
Collaboratore
bull ha un account utente quindi puograve autenticarsi
bull puograve aggiungere contenuti ma solo in aree specifiche e non puograve modificare niente al di fuori di queste areespesso agli utenti viene assegnata unrsquoarea ldquohomerdquo da utilizzare come uno spazio personale dove possono ag-giungere contenuti
11 Introduzione 15
Documentazione di Plone Release 4
bull non puograve pubblicare un contenuto per renderlo visibile nella navigazione anonima nemmeno nel caso dei con-tenuti che ha creato direttamente un utente con il ruolo di manager dovragrave approvare il contenuto per la pubbli-cazione
Manager
bull ha un account utente quindi puograve autenticarsi
bull puograve aggiungere contenuti ovunque e ha il potere di modificare qualunque cosa
bull puograve pubblicare qualsiasi contenuto
Quando ottieni il tuo nuovo account su un sito Plone ti dovrebbero fornire tutte le informazioni che indicano dove haiil diritto di aggiungere contenuti Dopo aver effettuato lrsquoaccesso se vai in una cartella in cui hai i permessi adeguativedrai la striscia di intestazione con il tipico colore verde e le schede Contenuti Visualizza Modifica Regole eCondivisione
Potrai navigare per scoprire di persona le differenze tra questi tab ma ecco qualche indicazione per aiutarti a comin-ciare
bull Contenuti - mostra la lista dei contenuti in una cartella
bull Visualizza - mostra come un utente anonimo vede il contenuto corrente
bull Modifica - mostra un pannello per modificare il contenuto
bull Condivisione - mostra un pannello per assegnare ad altri utenti i permessi per vedere e modificare il contenuto
Puoi inoltre vedere i menu nella parte finale della barra verde Vista Aggiungi e Stato
Esplora anche questi menu Ecco qualche indicazione per partire
bull Vista - mostra il menu per sciegliere il tipo di visualizzazione (vista tabellare vista riassuntiva etc)
bull Aggiungi - mostra il menu per aggiungere nuovi contenuti (immagini pagine cartelle etc)
bull Stato - mostra il menu per modificare lo stato di pubblicazione (privato bozza pubblicato etc)
Questi menu e tab sono il modo principale per interagire con Plone Ti saranno molto familiari quando imparerai dipiugrave su come gestire un sito Plone
114 Autenticazione
Cosa aspettarsi quando ci si autentica in un sito Plone
Quando visiti un sito Plone come anonimo oppure ti viene dato un indirizzo web per manutenzione del sito potraivedere un bottone ldquoFatti riconoscererdquo in alto a destra come questo
16 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Una volta cliccato il link Fatti riconoscere vedrai un pannello di autenticazione dove inserire il tuo nome utente e latua password
Dopo lrsquoautenticazione ad un sito web Plone potrai vedere il tuo nome solitamente in alto nellrsquoangolo a destra del tuoschermo Puoi cliccare sul tuo nome per effettuare alcune azioni relative al tuo utente come spiegato nelle sezionisuccessive
Da Plone 4 in poi tu (o lrsquoamministratore del sito) puoi permettere agli utenti di utilizzare il loro indirizzo di postaelettronica come nome utente per effettuare lrsquoautenticazione Questa funzionalitagrave puograve essere attivata nelle impostazionidi sicurezza nel pannello di controllo Lrsquoeffetto egrave tale per cui
bull nel modulo di registrazione non viene richiesto uno specifico nome utente
bull nel modulo di autenticazione viene chiesto allrsquoutente di inserire lrsquoemail
Vedi E-mail address based login in the Upgrade Guide per maggiori informazioni su questa funzionalitagrave
115 Impostare il tuo profilo
Una volta autenticato in un sito web Plone puoi cambiare il tuo profilo personale indicando informazioni circala tua identitagrave e scegliere le impostazioni del sito web
Il tuo nome completo viene mostrato nellrsquoangolo in alto a destra dello schermo Clicca sul tuo nome per aprire il menugravea discesa quindi clicca il link Dashboard per entrare nella tua area personale
Vedrai la dashboard (o scrivania personale)
La prima volta che ti autentichi la dashboard saragrave vuota come indica il messaggio di Info Le portlet sono specificheldquovisterdquo di vari tipi di contenuto Puoi scegliere quali vedere nella tua dashboard cliccando sul tab modifica ma ciarriveremo in un secondo
Prima di tutto diamo unrsquoocchiata al link Preferenze personali nel menugrave di cui parlavamo prima che ti porteragrave allamodifica del tuo profilo
I campi disponibili sono
bull Nome e cognome - Indica il tuo nome completo
11 Introduzione 17
Documentazione di Plone Release 4
18 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
bull Indirizzo e-mail - OBBLIGATORIO - Puoi ricevere email dallrsquoamministratore del sito web o da un forum seinstallato ecc Quando un campo egrave obbligatorio un piccolo quadrato rosso egrave presente a fianco del nome delcampo
bull Localitagrave - Questo egrave il nome della tua cittagrave stato provincia o qualsiasi altra informazione vorrai fornire
bull Selezione della lingua - Plone eccelle nellrsquooffire un supporto multilingua
bull Biografia - Inserisci una breve descrizione di te stesso in questo campo un paragrafo o poco piugrave
bull Pagina personale - Se hai un tuo web site personale o per esempio unrsquoarea dove condividi foto se vuoi puoiinserire qui lrsquoindirizzo web In questo modo altre persone potranno trovare piugrave informazioni su di te
bull Editor - Puoi scegliere di utilizzare TinyMCE o Kupu che ti permettono di modificare le pagine web con unainterfaccia grafica oppure una normale area di testo che egrave adatta se sei abituato a scrivere pagine web in HTML(il ldquocodicerdquo base delle pagine web) Lrsquoimpostazione di default per i siti appena creati egrave di utilizzare TinyMCEe in questo manuale si assume che sia questa lrsquoimpostazione
bull Abilita la modifica con lrsquoeditor esterno - Questa impostazione abilita e disabilita lrsquouso di un editor ldquoesternordquose questo egrave stato impostato dallrsquoamministratore del sito web Lrsquouso di un editor esterno egrave principalmente intesoper web designer e programmatori che modificano il codice sorgente ma puograve essere utile per la creazione dipagine quando si usa un linguaggio di markup specializzato (Non ti preoccupare di questa impostazione se iltuo amministratore non te ne ha parlato esplicitamente)
bull Ritratto - Il tuo ritratto appariragrave come una piccola immagine quindi egrave consigliata una foto del viso o del busto
Puoi cambiare le tue preferenze ogni volta che vuoi
116 La tua Dashboard
Ogni utente Plone ha una sua ldquodashboardrdquo da personalizzare
Plone ha diversi ldquovisterdquo predefinite per le notizie gli eventi i documenti modificati recentemente ecc Queste listesono raggruppate in aree rettangolari chiamate portlet Pensa ad una portlet come ad una finestra su un dato tipo dicontenuti Per esempio la portlet ldquonotizierdquo offre una vista delle notizie pubblicate recentemente
Tu controlli quali portlet vedi nella tua dashboard e dove sono disposte Il seguente screenshot mostra cosa vedrebbelrsquoutente Mario Rossi una volta che si fosse autenticato e che avesse cliccato sul suo nome posto in alto a destra perandare alla sua area personale
La dashboard appare vuota per un nuovo utente
Un click sul tab di modifica per la dashboard mostreragrave che ci sono portlet giagrave assegnate alla dashboard ndash la dashboardmostrata sopra egrave vuota perchegrave non ci sono contenuti disponibili da presentare nelle portlet di questo nuovo sito webEcco le portlet di default
Vedi le portlet Notizie ed Eventi nella colonna piugrave a sinistra i Contenuti recenti nella seconda colonna e lrsquoElenco direvisione nella colonna di destra La terza colonna non ha portlet assegnate
Lrsquoaccount di un nuovo utente in un sito web Plone base avragrave una dashboard come quella mostrata ma per un sito webche egrave stato personalizzato con funzionalitagrave aggiuntive potrebbero esserci piugrave portlet tra cui scegliere e la dashboard
11 Introduzione 19
Documentazione di Plone Release 4
potrebbe partire con diverse portlet giagrave posizionate nelle colonne Per esempio potrebbero esserci portlet per ldquoilmeteordquo ldquoquotazioni di borsardquo ldquofrase del giornordquo ecc a seconda di cosa egrave stato installato sul sito web (queste opzionirichiederebbero software personalizzato) Lrsquoutente puograve personalizzare le portlet che vuole vedere e la loro posizionetra le quattro colonne
Quindi per lrsquoaccount Plone tipico la dashboard parte con le portlet mostrate sopra che verrebbero popolate con lenews gli eventi e gli altri contenuti creati nel sito web
12 Aggiungere contenuti
Come aggiungere contenuti base ai siti web Plone
121 Aggiungere nuovi contenuti
Una panoramica generale su come aggiungere nuovi contenuti in Plone e definizione dei tipi di contenuto stan-dard
Per aggiungere nuovi contenuti si utilizza il menu a discesa Aggiungi
In Plone i contenuti vengono aggiunti localmente quindi devi navigare fino alla sezione dove desideri aggiungere ilcontenuto prima di usare la voce del menu Aggiungi Ersquo possibile ovviamente tagliare copiare e incollare contenutida una sezione ad un altra se necessario
Tipi di contenuti
In Plone hai a disposizione un certo numero di Tipi di contenuto che corrispondono ai diversi tipi di contenuto chepuoi pubblicare Ad esempio per caricare unrsquoimmagine devi utilizzare il tipo di contenuto Immagine Di seguito lalista dei tipi di contenuti disponibili nellrsquoordine in cui appaiono ed una breve descrizione
Collezione Le Collezioni sono utilizzate per raggruppare e visualizzare contenuti in base a dei criteri configurabiliIl funzionamento delle Collezioni egrave molto simile a quello delle query in un normale database
Evento Un Evento egrave un tipo di pagina speciale specifico per la pubblicazione di un evento (ad esempio una raccoltafondi un barbecue etc) Questo tipo di contenuto ha una funzione che permette ai visitatori del sito di ag-giungere lrsquoevento al proprio calendario personale utilizzando gli standard iCal e vCal Questi standard sonocompatibili con Google Calendar Outlook Sunbird e altri Per aggiungere un singolo evento al tuo calendariopersonale fai click sui link vCal o iCal accanto al testo ldquoAggiungi lrsquoevento al calendariordquo nella pagina principaledellrsquoEvento
A partire da Plone 33 egrave anche possibile scaricare tutti gli Eventi di una cartella in una sola volta (al momento egravedisponibile solo in formato iCal) Per scaricare il file iCal appendi ics_view alla fine dellrsquoURL della cartellache contiene gli eventi Ad esempio se si desidera ottenere tutti gli eventi della cartella eventi posizionata nella
20 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
12 Aggiungere contenuti 21
Documentazione di Plone Release 4
radice del tuo sito vai allrsquo indirizzo httptuodominiotldeventsics_view In un futuro rilascio di Plone egravein programma lrsquoinserimento di questo indirizzo direttamente nellrsquointerfaccia utente
File Un File in Plone egrave un file binario caricabile sul sito con lrsquointento di farlo scaricare dai visitatori Gli esempi piugravecomuni di file sono PDF Documenti di testo e fogli di calcolo
Cartella Le Cartelle in Plone funzionano come le cartelle del tuo computer Puoi utilizzare le cartelle per organizzarei contenuti e per dare al tuo sito Plone una struttura di navigazione
Immagine Il tipo di contenuto Immagine egrave utilizzato per caricare file di immagini (JPG GIF PNG) in modo tale chetu possa inserirli allrsquointerno di pagine o di contenuti simili
Collegamento Indicato anche come lsquoOggetto Linkrsquo non egrave da confondere con i collegamenti che vengono creatitramite TinyMCE o Kupu gli editor visuali per le pagine di Plone Il tipo di contenuto Collegamento egrave spessousato per includere un collegamento ad un sito web esterno nellrsquoalbero di navigazione o per altri usi specifici
Notizia Questo tipo di contenuto egrave molto simile agli Eventi anche se una Notizia si utilizza appositamente per lapubblicazione di notizie Egrave inoltre possibile allegare unrsquoimmagine ad una Notizia la miniatura appariragrave nellavista riassuntiva della cartella accanto alla descrizione della stessa
Pagina Una Pagina in Plone egrave uno dei tipi di contenuto piugrave semplici disponibili Utilizza questo oggetto per scriverela maggior parte delle pagine web del tuo sito Plone
Nota a seconda di quali prodotti aggiuntivi hai installato potresti vedere piugrave opzioni sotto la voce Aggiungi del tuomenu Per informazioni su questi tipi di contenuto fai riferimento alla documentazione dei vari prodotti installati
Titolo
Quasi tutti i tipi di contenuto in Plone hanno due campi in comune Titolo e Descrizione
Il campo Titolo delle cartelle delle immagini delle pagine etc puograve contenere tutto quello che vuoi ndash puoi usarequalsiasi carattere della tastiera inclusi gli spazi I Titoli vanno a comporre lrsquoindirizzo web dei contenuti creati Gliindirizzi web noti come URLs sono quello che digiti in un browser per passare in una specifica posizione di un sito(o il percorso del link selezionato) come ad esempio
wwwmysitecomaboutpersonnelsallybio
o
wwwmysitecomimagesbutterfliesskipperslong-tailed-skippers
Gli indirizzi web al contrario dei titoli sono soggetti a restrizioni Alcuni caratteri della tastiera non sono consentiticome ad esempio gli spazi Plone fa un buon lavoro nel mantenere gli indirizzi web molto simili ai Titoli forniticonvertendoli in lettere minuscole sostituendo gli spazi con i trattini e sostituendo altri segni di punteggiatura
In Plone lrsquoindirizzo web di un certo elemento egrave denominato nome breve Quando si utilizza la funzione Rinominaverragrave visualizzato sia il nome breve sia il titolo
I campi variano a seconda del tipo di contenuto Per esempio il tipo di contenuto Collegamento ha il campo URL Iltipo di contenuto File ha il campo File e cosigrave via
Descrizione
La Descrizione appare nella parte superiore delle pagine appena sotto il titolo Sono spesso visualizzate in molteviste assegnate a Cartelle e Collezioni (come in quella Standard e in quella Sintetica) La descrizione appare anche neirisultati delle ricerche eseguite con il motore di ricerca nativo di Plone
22 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
122 Aggiungere una Cartella
Aggiungere cartelle ad un sito web Plone egrave il passo fondamentale per controllare lrsquoorganizzazione dei contenuti
Traduzione Giampiero Lago (27112012)
Impaginazione Giacomo Spettoli (27112012)
Revisione Giacomo Spettoli (19052013)
I pc utilizzano una struttura gerarchica per organizzare i programmi e i files allrsquointerno del disco rigido In passatoavrai sicuramente creato delle cartelle (o directory) sul tuo computer per organizzare i tuoi documenti In Plone lecartelle sono utilizzate praticamente nello stesso modo lrsquounica differenza egrave che sono create in un sito web al fine didare una struttura al contenuto
Le cartelle si aggiungono cliccando sul menu Aggiungi e selezionando Cartella
Fig 11 add-item-menu-folderpng
Ora dovresti vedere il pannello Aggiungi Cartella
Ersquo necessario compilare il campo Titolo perchegrave si tratta di un campo obbligatorio (come egrave indicato dal quadratinorosso) Il campo Descrizione egrave invece opzionale potrai sempre tornare indietro al pannello di modifica se hai necessitagravedi aggiungere una descrizione alla cartella Le descrizioni sono utili quando un visitatore utilizza la ricerca di Plone ndashnei risultati saranno visualizzati sia il Titolo sia la Descrizione del contenuto
Potrete notare altri tab nella parte superiore
bull Default per inserire i campi Titolo e Descrizione
12 Aggiungere contenuti 23
Documentazione di Plone Release 4
bull Categorizzazione per specificare le categorie a cui appartiene la cartella (conosciute anche come keywords otag)
bull Date per settare il periodo di tempo durante il quale la cartella saragrave visibile nel sito
bull Proprietario per specificare lrsquoautore eo i collaboratori dellrsquoelemento in questione
bull Impostazioni per abilitare i commenti abilitare la navigazione precedentesuccessivo e scegliere se visualizzareil contenuto nel menu di navigazione del sito web
Queste schede sono standard e si trovano anche su altri tipi di contenuto Vedremo piugrave nel dettaglio queste schede piugraveavanti in questo manuale
Assicurati di cliccare sul bottone Salva in basso alla pagina quando hai finito di inserire le informazioni Questocompleteragrave il processo di creazione di una cartella
Guarda un video su come aggiungere una cartella
123 Cosa crsquoegrave in un nome Web
Ogni contenuto di un sito Plone ha un indirizzo web univoco Plone crea gli indirizzi automaticamente in baseal Titolo che avete fornito
Il Titolo di un contenuto incluse cartelle immagini pagine etc puograve essere tutto ciograve che vuoi ndash puoi usare tutti icaratteri della tastiera inclusi gli spazi bianchi I titoli diventano parte dellrsquoindirizzo web per ogni elemento che creiin Plone Gli indirizzi Web conosciuti anche come URL sono quello che scrivete in un browser web per andare aduna posizione specifica in un sito web (In alternativa come ad esempio
wwwmysitecomaboutpersonnelsallybio
o
24 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
wwwmysitecomimagesbutterfliesskipperslong-tailed-skippers
Al contrario dei titoli gli indirizzi web hanno restrizioni sui caratteri consentiti come gli spazi bianchiPlone fa unottimo lavoro per mantenere gli indirizzi web corretti utilizzando una struttura quasi equivalente al titolo che avetefornito convertendo tutte le lettere in minuscolo e sostituendo i trattini agli spazi bianchi e alla punteggiatura
Per capire meglio prendiamo ciascuno di questi due indirizzi web e dividiamoli nei vari componenti
wwwmysitecomaboutpersonnelsallybio^website name
^a folder named About
^a folder named Personnel
^a folder named Sally
^a folder named Bio
In questo caso Plone ha cambiato ogni titolo della cartella in lettere minuscole ad esempio da Personnel a personnelMa non dovete preoccuparvi di questo perchegrave Plone gestisce lrsquoindirizzamento web vi basteragrave digitare nei titoli quelloche volete
E per il secondo esempio
wwwmysitecomimagesbutterfliesskipperslong-tailed-skippers^website name
^a folder named Images
^a folder named Butterflies
^a folder named Skippers
^a folder named Long-Tailed Skippers
Questo esempio egrave simile al primo ed illustra come avviene la conversione in lettere minuscole del titolo di ciascunacartella alla corrispondente parte dellrsquoindirizzo web Da notare il caso della cartella nominata ldquoLong-tailed SkippersrdquoPlone conserva il trattino in quanto carattere consentito sia nel titolo che nella parte dellrsquoindirizzo web ma convertein un trattino nellrsquoindirizzo web lo spazio bianco tra le parole Tailed e Skippers oltre che le lettere da maiuscole aminuscole
Lrsquoindirizzo web di un certo contenuto egrave indicato in Plone come nome breve Quando usate la funzione Rinomina verragravevisualizzato il nome breve insieme al titolo
124 Aggiungere unrsquoImmagine
Aggiungere immagini in un sito web Plone egrave unrsquoattivitagrave di base che puograve comportare un porsquo di lavoro sul tuocomputer locale ma egrave essenziale percheacute fotografie mappe e grafica personalizzata sono molto importanti neisiti web
Preparare un immagine per il web
Note Ricorda di utilizzare per tutte le immagini i formati di file comunemente accettati come standard sul web Iformati accettabili includono JPG JPEG GIF e PNG Non usare i formati BMP e TIFF poichegrave non sono supportatida tutti i browsers
12 Aggiungere contenuti 25
Documentazione di Plone Release 4
Quando vuoi caricare una immagine utilizza il menu Aggiungi (vedrai il menu Aggiungi solo dopo aver effet-tuato lrsquoaccesso)
Dopo aver cliccato per aggiungere una Immagine vedrai il pannello Aggiungi Immagine
Ci sono i campi Titolo e Descrizione (campi intesi come ldquocampi di immissione datirdquo) cosigrave come visto nel caso dellacreazione di una cartella In fondo al pannello crsquoegrave un campo per caricare unrsquoimmagine Analizziamo i tre campi diimmissione dei dati
bull Titolo - Inserisci il testo che preferisci compresi spazi bianchi e punteggiatura (Plone gestisce automaticamentelrsquoadattamento del titolo per generare lrsquoURL dellrsquoimmagine)
bull Descrizione - Egrave sempre una buona idea valorizzare questo campo anche se non egrave obbligatorio
bull Immagine - Il campo Immagine egrave una casella di testo seguita da un bottone Sfoglia Nella casella di testotuttavia non devi scrivere niente clicca sul bottone Sfoglia e potrai scegliere il file da caricare selezionandolodirettamente dalle cartelle presenti sul tuo computer (per fare questo egrave utile tenere bene a mente in quale cartelladel proprio computer egrave stata salvata lrsquoimmagine da caricare)
Poichegrave Titolo e Descrizione non sono campi obbligatori per caricare unrsquoimmagine sul tuo sito Plone tutto quelloche serve egrave selezionare lrsquoimmagine stessa sul tuo computer tramite il bottone Sfoglia e cliccare sul bottone Salvapresente nella parte inferiore del pannello Dovrai aspettare qualche secondo per il completamento del caricamento(qualche minuto se hai una connessione internet lenta) Unrsquoanteprima dellrsquoimmagine verragrave visualizzata al termine delcaricamento
A partire da Plone 4 le immagini e i file che vengono caricati sul sito hanno un loro ID (URL) basato sul Titoloinserito tramite il campo visto in precedenza Se il campo Titolo non viene valorizzato (non egrave obbligatorio) lrsquoURLassegnato allrsquoimmagine (o al file) saragrave generato utilizzando il nome del file
26 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
12 Aggiungere contenuti 27
Documentazione di Plone Release 4
125 Aggiungere una Pagina
Le pagine in Plone possono variare molto ma ad ogni modo sono sempre ldquopagine webrdquo
Per aggiungere una pagina utilizza il menu Aggiungi presente in Plone a livello di cartella
Seleziona la voce Pagina dal menu a discesa e vedrai il pannello Aggiungi pagina
I campi Titolo e Descrizione sono i primi in alto riempili in maniera appropriata Crsquoegrave un campo Commento allemodifiche in fondo un normale campo di testo utile per memorizzare eventuali annotazioni che descrivano le modifichefatte al documento Ciograve egrave utile per le pagine sulle quali potresti dover collaborare con altri
Al centro del pannello crsquoegrave il campo Testo del documento Il software utilizzato per la composizione delle pagine egravecomunemente detto editor di testo visuale e nello specifico in Plone si utilizza TinyMCE Un editor di tipo testuale tipermette di comporre le pagine in maniera WYSIWYG WYSIWYG (What You See Is What You Get quello che vediegrave quello che avrai) egrave un termine che descrive il modo in cui lrsquoeditor funziona se ad esempio applichi il grassetto aduna parola vedrai immediatamente il risultato del nuovo stile applicato
Le persone normalmente si trovano subito a proprio agio con lrsquoapproccio utilizzato dagli editor WYSIWYG Vedremoin maniera piugrave approfondita questo argomento piugrave avanti in questo manuale
Linguaggi di markup
Se preferite scrivere il testo delle pagine utilizzando i formati di markup egrave possibile disabilitare lrsquoeditor di testo visualenel pannello delle preferenze personali e rimpiazzare cosigrave TinyMCE con un campo di testo semplificato I formati dimarkup disponibili in Plone sono
bull Markdown
28 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
12 Aggiungere contenuti 29
Documentazione di Plone Release 4
bull Textile
bull Structured Text
bull Restructured Text
Ognuno di questi formati si basa sullrsquoutilizzo di speciali codici di formattazione allrsquointerno del testo Ad esempio nelformato di markup Structured Text mettere tra doppi asterischi una parola o una frase renderagrave la parola o la frase ingrassetto cosigrave Questo testo sarebbe in grassetto Puograve essere utile imparare ad utilizzare questi formati di markupper aumentare la velocitagrave di input (soprattutto se si creano molte pagine) o se si preferisce un approccio leggermentepiugrave tecnico nellrsquoinserimento del testo Alcune persone preferiscono questi formati non solo per la velocitagrave in segrave maanche per la fluiditagrave di espressione
126 Aggiungere un File
File di vari tipi possono essere caricati su un sito Plone
Per aggiungere un file utilizza il menu Aggiungi presente a livello di cartella
Seleziona la voce File dal menu a discesa e vedrai il pannello Aggiungi file
Fai click sul pulsante Scegli file per cercare nelle cartelle del tuo computer locale il file da caricare Inserisci un titolo(puoi utilizzare lo stesso nome del file se vuoi) Inserisci anche una descrizione se vuoi Quando fai click sul bottoneSalva il file verragrave caricato nella cartella Plone
Puoi caricare file PDF documenti Word file di database archivi zip- praticamente qualunque cosa Allrsquointerno diun sito Plone i file vengono trattati semplicemente come file e verranno mostrati nelle liste di contenuti delle cartellePlone allrsquointerno delle quali sono caricati ma non ci saragrave nessuna visualizzazione speciale per loro Appariranno conil loro nome nelle liste e saragrave possibile scaricarli cliccando sul link costituito dal loro nome nella lista
30 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
12 Aggiungere contenuti 31
Documentazione di Plone Release 4
Esistono add-on specializzati per Plone che permettono la ricerca di contenuti allrsquointerno dei file Chiediallrsquoamministratore del tuo sito Plone se hai bisogno di queste funzionalitagrave
127 Aggiungere un Collegamento
Oltre ad inserire collegamenti nel testo delle pagine eacute possibile in Plone creare collegamenti anche come tipidi contenuto autonomi Avere collegamenti come tipi di contenuto ti permette ad esempio di organizzarli incartelle di impostare delle parole chiave ad essi associate per facilitarne il raggruppamento negli elenchi e neirisultati di ricerca o di inserirli nei menugrave di navigazione
Per aggiungere un oggetto di tipo Collegamento seleziona la voce corrispondente dal menu Aggiungi presente alivello di cartella Plone
Avrai accesso al pannello Aggiungi Collegamento
Scegliere dei buoni titoli egrave importante perchegrave sono proprio i titoli ad essere visualizzati nella lista di tutti i collegamentipresenti allrsquointerno di una cartella Plone Immagina cosa significhi questo se il numero di collegamenti nella cartellatende a crescere
Incolla lrsquoindirizzo web nel campo URL oppure digitalo Poichegrave non crsquoegrave alcuna funzionalitagrave di anteprima dellrsquoURLinserito egrave meglio copiare questrsquoultimo direttamente dalla finestra del browser nella quale lo si sta vedendo in mododa essere sicuri della sua correttezza
Comportamento dellrsquooggetto di tipo Collegamento
Un oggetto di tipo Collegamento si comporteragrave nei seguenti modi a seconda delle autorizzazioni di cui si dispone
32 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
12 Aggiungere contenuti 33
Documentazione di Plone Release 4
bull Se hai il permesso di modificare lrsquooggetto Collegamento quando clicchi sullrsquooggetto vieni rimandato al pan-nello di editazione del contenuto stesso per poterlo modificare (se cosigrave non fosse verresti indirizzato allrsquoURLassociato allrsquooggetto e non avresti modo di modificarlo)
bull Se non hai il permesso di modificare lrsquooggetto Collegamento quando clicchi sullrsquooggetto vieni indirizzatodirettamente allrsquoURL associato allrsquooggetto Il comportamento in questo caso egrave lo stesso che si avrebbe inserendodirettamente lrsquoindirizzo nel browser Lrsquooggetto collegamento in questo caso si comporta come un redirect
128 Aggiungere un Evento
I siti Plone hanno un sistema integrato per la gestione e la visualizzazione di eventi in un caledario
In una cartella utilizza la voce del menu Aggiungi per aggiungere un evento
Compariragrave un pannello abbastanza grande Aggiungi Evento
34 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
12 Aggiungere contenuti 35
Documentazione di Plone Release 4
Dallrsquoalto si hanno i seguenti campi
bull Titolo - OBBLIGATORIO
bull Descrizione
bull Luogo dellrsquoevento
bull Inizio dellrsquoevento - OBBLIGATORIO
bull Termine dellrsquoevento - OBBLIGATORIO
bull Testo dellrsquoevento (editor visuale)
bull Partecipanti
bull Tipo(i) di evento
bull URL dellrsquoevento
bull Nome del contatto
bull Indirizzo e-mail per contatti
bull Telefono del contatto
bull Commento alle modifiche
Nota che solo tre campi sono obbligatori titolo inizio e termine dellrsquoevento Anche se si tratta di una pannello conmolte informazioni da inserire se hai fretta ti basta inserire questi tre campi e salvare per creare lrsquoevento Ovviamentese hai altre informazioni puoi inserirle
Una parte del pannello richiede qualche informazione aggiuntiva lrsquoinizio e il termine dellrsquoevento Lrsquoanno il meseil giorno ed altri campi sono semplicemente menu a discesa Spesso perograve non egrave semplice ricordare esattamente ilgiorno da inserire e si ha la necessitagrave di consultare un calendario Crsquoegrave un comodo calendario pop-up che offre un modoalternativo per selezionare il giorno Se clicchi una volta sullrsquoicona del calendario accanto al selettore a discesa delgiorno
compariragrave questo calendario pop-up
Ersquo sufficiente cliccare sul giorno di interesse e questo verragrave automaticamente impostato nel pannello Compila i campiper i quali hai informazioni e salva ma ricorda
IMPORTANTE Lrsquoevento non verragrave visualizzato nel calendario principale del sito fino a quando non saragrave pubblicato
129 Aggiungere una Notizia
Plone integra un sistema nativo per la pubblicazione di notizie
Per aggiungere una nuova notizia utilizza la voce corrispondente del menugrave Aggiungi presente a livello di cartellaPlone
Avrai accesso al pannello Aggiungi notizia
36 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
12 Aggiungere contenuti 37
Documentazione di Plone Release 4
38 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Nel pannello ci sono i campi standard Titolo Descrizione e Commento alle modifiche insieme ad un editor visualeper inserire il corpo della notizia (Testo del documento) ed ai campi per lrsquoupload dellrsquoimmagine e per la sua didascaliaNel area Testo del documento puoi inserire qualsiasi tipo di testo con la formattazione di cui hai bisogno e tramitela funzionalitagrave Inseriscimodifica immagine dellrsquoeditor puoi aggiungere al testo della notizia tutte le immagini chedesideri Le immagini caricate verranno aggiunte alla cartella nella quale stai creando la notizia
I campi Immagine e Didascalia immagine servono ad aggiungere unrsquoimmagine che verragrave utilizzata come elementografico rappresentativo della notizia stessa allrsquointerno degli elenchi di notizie pubblicate sul sito Plone Lrsquoimmagineverragrave automaticamente ridimensionata e posizionata in ciascun elenco Se devi inserire unrsquoimmagine nel corpo deltesto della notizia pertanto non devi utilizzare il campo Immagine ma la funzionalitagrave dellrsquoeditor visuale presente peril campo Testo del documento
IMPORTANTE le notizie inserite non appariranno nellrsquoelenco principale o nella portlet utilizzata per pubblicare lenotizie sul tuo sito Plone finchegrave non saranno nello stato ldquoPubblicatordquo
1210 Impostazione delle proprietagrave di base
I tab disponibili per ogni tipo di contenuto Plone dispongono di campi per lrsquoimmissione delle informazioni dibase Fornire tali dati egrave importante significa fornire combustibile per il motore di Plone
Ogni tipo di contenuto se editato da un utente con diritti di modifica su di esso mostreragrave una serie di tab nella partesuperiore per lrsquoimpostazione delle proprietagrave di base
Questi tab per le proprietagrave di base sono
bull Default - mostra il form di inserimento dei dati principali per il contenuto
bull Categorizzazione - mostra un pannello per la creazione e lrsquoimpostazione delle categorie (parole chiave) per ilcontenuto
bull Date - mostra la data di pubblicazione e la data di scadenza per il contenuto
bull Possessore - mostra un pannello per lrsquoimpostazione dei creatori del contenuto e di tutti coloro che vi hannocontribuito noncheacute di tutte le informazioni sul copyright
bull Impostazioni - mostra un piccolo pannello per stabilire se lrsquoelemento appariragrave nel menu di navigazione e se sonoammessi i commenti sul contenuto
I campi di inserimento in queste schede coprono le informazioni descrittive di base chiamate metadati I metadativengono a volte chiamati ldquodati sui datirdquo Plone puograve utilizzare questi metadati in moltissimi modi
Ecco il pannello di Categorizzazione mostrato per un tipo di contenuto ldquoPaginardquo (sarebbe lo stesso per altri tipi dicontenuto)
Nota In Plone 3 i tag erano chiamati categorie Nelle versioni precedenti la 30 essi erano invece chiamati ParoleChiave
Il campo principale di inserimento del pannello serve a specificare le categorie associate al contenuto che si sta ed-itando Per crearne di nuove basta semplicemente digitare parole o frasi una per riga nel box Nuovi tag Quandosi salva il contenuto i nuovi tag saranno creati allrsquointerno dellrsquoelenco di tag del sito web e il contenuto stesso saragravearchiviato sotto di essi Se si ri-modifica questo contenuto o si modifica qualsiasi altro contenuto i tag creati sarannoautomaticamente disponibili come Tag esistenti
12 Aggiungere contenuti 39
Documentazione di Plone Release 4
40 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Il campo Elementi Correlati permette di impostare collegamenti tra i vari contenuti Quando un contenuto vienevisualizzato i contenuti correlati vengono mostrati come link a fondo pagina Ciograve egrave utile quando non si desiderautilizzare le categorie esplicite (tag) per la correlazione di contenuti diversi
Il campo Posizione fa riferimento ad una posizione geografica associabile al contenuto Ersquo adatto per lrsquouso con sistemidi mappatura ma utilizzabile per lrsquoarchiviazione del contenuto in generale
La Lingua scelta normalmente egrave quella di default del sito ma su siti web multilingue lingue diverse potrebbero essereutilizzate in un mix di contenuti
Il pannello Date presenta campi per impostare la data di pubblicazione e e quella di scadenza del contenuto Seimpostate esse definiscono in concreto le date di inizio e fine della validitagrave del contenuto
Le date di pubblicazione e di scadenza funzionano in questo modo
bull Se visualizzato ogni contenuto che ha una data di scadenza giagrave trascorsa viene contrassegnato come ldquoscadutordquoin rosso nel suo sottotitolo
bull Un oggetto la cui data di pubblicazione egrave posteriore alla data attuale non presenta testo aggiuntivo nel suosottotitolo
bull In entrambi i casi lrsquoelemento egrave ldquonon pubblicatordquo definizione che non deve essere confusa con uno stato del suoworkflow
bull Vuol dire semplicemente che lrsquoelemento non compare negli elenchi e nelle ricerche
bull Questi elenchi includono gli elenchi di contenuti presenti in una cartella
bull Tuttavia il proprietario dellrsquoelemento continueragrave a vederlo questo perchegrave egrave desiderabile sapere quali documentigiacenti ci sono nel nostro sito
bull Il permesso che controlla tutto questo si chiama ldquoAccess inactive portal contentrdquo
bull Gli elementi scaduti in una cartella sono contrassegnati come tali durante la visualizzazione folder_contents
12 Aggiungere contenuti 41
Documentazione di Plone Release 4
bull Non crsquoegrave un modo rapido di vedere se gli elementi in un elenco di cartelle sono non ancora pubblicati
bull Quando si imposta un elemento non pubblicato come visualizzazione predefinita per una cartella tale elementoverragrave visualizzato
bull Lrsquoannullamento della pubblicazione di un elemento non ha alcun effetto per gli amministratori Essi potrannosempre vedere gli oggetti non pubblicati nei loro elenchi e nelle ricerche
bull Anche se si assegnano permessi sul contenuto ad utenti non amministratori (ldquopuograve aggiungererdquo ldquopuograve modifi-carerdquo ldquopuograve revisionarerdquo) per questi utenti il contenuto resteragrave sempre ldquonon pubblicatordquo
bull Un modo pratico per un utente non amministratore per accedere a un elemento non pubblicato egrave direttamenteattraverso il suo URL
Il pannello Possessore dispone di tre campi liberi per assegnare i creatori del contenuto coloro che vi hanno con-tribuito e le informazioni in merito ai diritti drsquoautore e di proprietagrave
Il pannello Impostazioni ha campi che possono variare un porsquo da un tipo di contenuto allrsquoaltro ma in generale ci sonocampi di input per stabilire se lrsquoelemento debba apparire o meno nella navigazione o se sono autorizzati i commentie altri controlli simili
Raccomandazioni
Non vi egrave alcun obbligo di inserire le informazioni specificate attraverso questi pannelli ma farlo egrave una buona idea Peril pannello Possessore fornire i dati egrave importante per situazioni dove ci sono diverse persone coinvolte nella creazionedi contenuti soprattutto se ci sono piugrave creatori e collaboratori che lavorano in gruppo Non sempre egrave necessariocompilare campi quali la data di pubblicazione e di scadenza lingua e diritti drsquoautore ma questi dati devono esserespecificati al momento opportuno Un sistema di gestione dei contenuti egrave tanto buono quanta completezza nellagestione dei dati permette
Specificare le categorie richiede attenzione ma se si prende lrsquoabitudine e se ci si impegna a creare un insieme sig-nificativo di categorie vi egrave un grande ritorno dallo sforzo fatto Tale ritorno si concretizza nella maggiore efficaciadelle funzionalitagrave di ricerca e di altre funzionalitagrave Plone che si basano sulla categorizzazione Lo stesso vale perlrsquoimpostazione degli elementi correlati Sarai in grado di trovare rapidamente quello che ti serve e potresti diventareabile nello scoprire e sfruttare le relazioni fra i contenuti
Esposizione delle proprietagrave dei metadati come meta tag nel codice HTML
Da Plone 4 in poi in Configurazioni del sito Sito crsquoegrave una check box che permette di esporre le proprietagrave di base deimetadati Dublin Core Selezionando questa casella verranno aggiunti il titolo la descrizione ecc e altri metadaticome meta tag allrsquointerno dellrsquoHTML ltheadgt Per esempio
ltmeta content=short description name=DCdescription gtltmeta content=short description name=description gtltmeta content=texthtml name=DCformat gtltmeta content=Page name=DCtype gtltmeta content=admin name=DCcreator gtltmeta content=2009-11-27 170403 name=DCdatemodified gtltmeta content=2009-11-27 170402 name=DCdatecreated gtltmeta content=en name=DClanguage gt
Le proprietagrave Dublin Core Creator Contributors e Publisher saranno visualizzate solamente se egrave stata abilitata lavisualizzazione di queste informazioni per agli utenti anonimi La configurazione si trova in Configurazioni del sitoal link Sicurezza
Per saperne di piugrave su Dublin Core e HTML Metatags
42 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
12 Aggiungere contenuti 43
Documentazione di Plone Release 4
1211 Restrizioni sui tipi di contenuto in una cartella
Il menu ldquoAggiungi nuovordquo ha la possibilitagrave di limitare i tipi di contenuto che possono essere aggiunti allacartella
Limitare i tipi di contenuti che possono essere aggiunti ad una cartella egrave il modo piugrave semplice per controllare lacreazione di contenuti in un sito web Plone Puoi scegliere di utilizzare restrizioni sui tipi di contenuti se il tuosito viene gestito da numerose persone In questo modo puoi forzare buone pratiche come ad esempio inserire soloimmagini in una cartella cui hai dato nome ldquocartella immaginirdquo
Prima di tutto seleziona lrsquoultima opzione nel menu ldquoaggiungirdquo chiamata ldquoRestrizionirdquo
Ci sono tre scelte possibili per aggiungere restrizioni ai tipi di contenuto creabili in una cartella
La scelta di default egrave di utilizzare le impostazioni della cartella-padre Avere questa impostazione come default sig-nifica che se crei una cartella e crei restrizioni sui tipi che possono essere aggiunti ad essa ogni sottocartella creataerediteragrave automaticamente tali restrizioni
La seconda scelta permettere la sola aggiunta di tipi di contenuti standard egrave il modo di ritornare alle impostazioniiniziali senza restrizioni
Lrsquoultima scelta permette di selezionare da una lista di tipi di contenuti disponibili
I tipi di contenuti elencati sotto la voce Tipi consentiti sono quelli disponibili allrsquointerno del sito web Il default comemostrato egrave di permettere lrsquoaggiunta di tutti i tipi di contenuti A partire dalle impostazioni di default i vari tipi dicontenuti disponibili possono essere abilitati o disabilitati per permettere di aggiungerli o meno alla cartella
Lrsquouso di tipi supplementari permette un controllo ancora piugrave di dettaglio Per esempio se egrave si egrave deciso di salvaretutte le immagini in una sola cartella invece di spargerle in varie cartelle sul sito web ndash uno schema che in molti
44 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
12 Aggiungere contenuti 45
Documentazione di Plone Release 4
46 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
preferiscono ndash una cartella ldquoimmaginirdquo puograve essere creata impostando le immagini come unici tipi di contenuti creabilial suo interno
Allo stesso modo una cartella ldquoEventi aziendalirdquo potrebbe essere creata per contenere solo contenuti di tipo EventoSe si impostassero le cose in questo modo i creatori di contenuti sarebbero forzati a seguire questo schema restrittivo
Tuttavia un porsquo piugrave di flessibilitagrave egrave spesso desiderabile per le immagini Selezionando il contenuto ldquoImmaginerdquo nellavoce tipi supplementari per la cartella ldquoEventi aziendalirdquo le immagini possono essere aggiunte se egrave effettivamentenecessario utilizzando il sotto menugrave ldquoAltrirdquo che appare quando viene attivato questo meccanismo
Alcune persone preferiscono un mix eteronegeo di contenuti sul sito web senza restrizioni Altri preferiscono un ap-proccio piugrave regolamentato restringendo tipi secondo un dato schema organizzativo Plone ha la flessibilitagrave necessariaper accettare un ampio spettro di impostazioni
1212 Preparare le immagini per il web
Preparare le immagini per il web egrave una parte essenziale per utilizzare le immagini in Plone come in qualsiasicontesto online Come vedrai le dimensioni contano
Molte fotografie utlizzate dagli utenti sono scattate con una fotocamera digitale ma possono anche essere immaginiacquisite da scanner illustrazioni grafiche realizzate con software specifici e altri tipi di immagini particolari Prendi-amo il caso di una foto di una farfalla scattata con una fotocamera digitale
Le fotografie digitali scattate con macchine fotografiche moderne sono di solito troppo grandi per essere inseritedirettamente su un sito web quindi hanno bisogno di essere ridimensionate Un tipico design di un sito web potrebbeavere una larghezza di circa 1000 pixel Quando una foto viene scattata con una moderna macchina fotografica puograveavere diverse migliaia di pixel di larghezza e altezza e quindi risultare di diversi megabyte di dimensione come fileDovrai quindi utilizzare software appositi che ridimensionino lrsquoimmagine in qualcosa di meno di 1000 x 1000 pixelmolto spesso serviranno anche dimensioni piugrave piccole
I software che si utilizzano per visualizzare o stampare le foto digitali hanno spesso questa funzionalitagrave di ridimension-amento in alternativa si potrebbero utilizzare software di grafica come Corel Draw Adobe Photoshop Irfanview oGimp Il ridimensionamento di unrsquoimmagine a volte chiamato ricampionamento egrave una funzione standard che spessosi trova nei software di fotoritocco sotto la voce di menu Immagine
Come facciamo a sapere di che dimensione di larghezza in pixel abbiamo bisogno per ridimensionare la nostra immag-ine Dipende Per un ldquohead shotrdquo una fotografia da inserire in una biografia forse 200 pixel di larghezza potrebberobastare Per una foto di gruppo 200 pixel risulterebbero troppo poco per consentire lrsquoidentificazione delle personenella fotografia quindi magari si potrebbe aver bisogno di una larghezza di almeno 400 pixel Per una immagine diuna mappa presa da scanner forse la larghezza dovrebbe essere di 1000 pixel per permettere di visualizzare i dettaglidella mappa
Dopo aver salvato lrsquoimmagine ridimensionata diamogli un nome che indichi il nuovo formato (ad esempio butteryfly-resized-300pxjpg) Il formato del file egrave di solito jpg (o jpeg) Altri formati comuni per le immagini sono png e gifPrendi nota dove salvi le immagini sul tuo computer in modo da trovarle facilmente quando le carichi sul tuo sito webPlone
Per riassumere
1 Scatta la fotografia con la tua fotocamera o trova unrsquoimmagine esistente che desideri utilizzare
2 Trasferiscila sul tuo computer
3 Utilizza software di fotoritocco sul tuo computer per ridimensionare la fotografia o lrsquoimmagine
4 Carica la fotografia o lrsquoimmagine sul tuo sito Plone
12 Aggiungere contenuti 47
Documentazione di Plone Release 4
48 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
1213 Aggiungere collezioni
Le collezioni (precedentemente chiamate Smart Folders) sono contenitori virtuali di liste di contenuti trovatiattraverso specifiche ricerche
Consulta a questo proposito la sezione del manuale Utilizzo delle collezioni
13 Gestione dei contenuti
La scheda contenuti egrave il posto dove gli oggetti posso essere copiati tagliati incollati spostati rinominati etc
131 Tagliare Copiare e Incollare contenuti
Le operazioni taglia copia e incolla comportano lo spostamento di uno o piugrave contenuti da una cartella adunrsquoaltra
TagliaIncolla
Spostare contenuti da una area ad unrsquoaltra in un sito web egrave un operazione comune Spesso si ha necessitagrave di questaoperazione quando alcuni contenuti sono posizionati nella cartella sbagliata Ad esempio se il creatore della cartellasulle farfalle Skippers mostrata nella figura che segue (che contiene a sua volta le cartelle relative alla singole farfalle)si rende conto che la cartella Eastern Tiger Swallowtail evidenziata in figura egrave stata erroneamente creata nella cartella-padre Skippers puograve semplicemente spostarla con una operazione di tagliaincolla
Nota che la cartella Eastern Tiger Swallowtail egrave stata selezionata e che il pulsante Taglia sta per essere cliccatoDopo aver fatto clic sul pulsante Taglia lo schermo mostreragrave un nuovo pulsante Incolla La cartella Eastern TigerSwallowtail e tutto il suo contenuto sono ora nella ldquomemoriardquo del sito web La cartella Eastern Tiger Swallowtail nonscompare subito in quanto egrave in attesa della relativa operazione Incolla Il pulsante Incolla viene ora evidenziato permostrare che lrsquooperazione tagliaincolla egrave in corso
Il pulsante Incolla ora egrave attivo Il passo successivo egrave quello di selezionare la cartella di destinazione in questo caso lacartella Swallowtails
Dopo aver cliccato ed essere entrati nella cartella Swallowtails il pulsante Incolla continueragrave a vedersi percheacutelrsquooperazione Incolla non egrave ancora stata completata
Per ultimo facendo clic sul pulsante Incolla allrsquointerno della cartella di destinazione Swallowtails la cartella EasternTiger Swallowtail viene infine aggiunta nel giusto posto e viene quindi tagliata dalla posizione originale la cartellaSkippers Lrsquooperazione di CopiaIncolla egrave ora completata
Il pulsante Incolla rimane attivo percheacute egrave possibile continuare ad incollare la cartella in altri posti se si vuole Ciogravepotrebbe accadere in diverse situazioni quando magari egrave necessario copiare una pagina ad esempio una sorta dimodello o documento standard in diverse cartelle
CopiaIncolla
Lrsquooperazione di CopiaIncolla egrave identica allrsquooperazione di TagliaIncolla tranne che non crsquoegrave rimozione del contenutodalla cartella originale Esso funziona come ci si aspetta che funzioni
13 Gestione dei contenuti 49
Documentazione di Plone Release 4
50 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
13 Gestione dei contenuti 51
Documentazione di Plone Release 4
52 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
132 Modificare i contenuti
La modifica dei contenuti in Plone funziona allo stesso modo dellrsquoaggiunta - solitamente i pannelli perlrsquoimmissione dei dati e per la modifica dei contenuti sono gli stessi
Naturalmente quando si modifica un elemento lrsquooggetto esiste giagrave Fare clic sulla scheda Modifica di un contenutoper vedere il pannello di inserimento dati per quel contenuto insieme con i valori giagrave esistenti per quellrsquoelemento
Per un esempio molto semplice di come modificare un contenuto sia molto simile ad aggiungerlo possiamo rivederecome si modifica una cartella
Il pannello Modifica di una cartella mostra semplicemente le aree di input per il titolo e la descrizione Spessola descrizione non egrave prevista per una cartella quindi lrsquounica cosa da cambiare egrave il titolo Se si desidera dare unadescrizione che egrave una buona idea per distinguere le cartelle in un elenco la descrizione puograve essere inserita solo informato testo ndash non crsquoegrave alcuna possibilitagrave di impostare lo stile di testo come grassetto corsivo o altre formattazioniCiograve mantiene le descrizioni degli elementi Plone il piugrave semplice possibile
Ecco il pannello Modifica di una cartella in questo caso una cartella chiamata ldquoButterfliesrdquo
Tutto qui Cambia ciograve che si desidera e salva ed il contenuto dellrsquoelemento saragrave aggiornato nel sistema Plone Puoimodificare ripetutamente il contenuto degli elementi proprio come puoi farlo con i file presenti sul tuo PC Ormai avraiapprezzato il fatto che Plone memorizza gli elementi come entitagrave separate simili a ldquofilerdquo su un computer locale manon crsquoegrave bisogno di pensarla necessariamente in questo modo Plone egrave un CMS (sistema di gestione dei contenuti) incui il contenuto viene fornito sotto forma di numerosi elementi separati che possono essere modificati singolarmentea piacimento
Per fare un esempio di modifica di un contenuto che egrave un pograve diverso dal suo inserimento iniziale possiamo esaminare lamodifica di unrsquoimmagine La modifica di una immagine puograve essere fatta navigando fino a trovare la singola immaginee facendo clic sul pannello Modifica Facendo clic sul pannello Modifica verragrave visualizzato il seguente pannelloModifica immagine
Nellrsquoesempio in figura unrsquoimmagine chiamata ldquoEastern Tiger Swallowtail Butterflyrdquo sta per essere modificata Puoimodificare il titolo e la descrizione come al solito e in questo caso potresti lasciare lrsquoimpostazione ldquoMantieni
13 Gestione dei contenuti 53
Documentazione di Plone Release 4
54 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
lrsquoimmagine correnterdquo Egrave anche possibile modificare lrsquoimmagine stessa scegliendo ldquoSostituisci con la nuova immag-inerdquo In alternativa cliccando sul pulsante ldquoElimina immagine correnterdquo lrsquoimmagine saragrave eliminata del tutto
Si noti anche sulla parte superiore la presenza del tab Trasforma che egrave pertinente alle immagini e che offre la possi-bilitagrave di effettuare diverse trasformazioni dellrsquoimmagine
Quindi la modifica di un immagine egrave un operazione leggermente diversa rispetto alla sua aggiunta anche se non dimolto
I pannelli di modifica per gli altri tipi di contenuto sono solitamente simili ai pannelli per lrsquoaggiunta
Modifica in linea (opzionale)
La modifica in linea egrave disabilitata di default nelle ultime versioni di Plone (33 +) Puograve essere abilitata tramite ilpannello di controllo da un Amministratore del Sito (Configurazione del sito -gt Modifica -gt Spuntare la checkboxAbilita modifica in linea)
La normale procedura per modificare un contenuto egrave quello di fare clic sul pannello Modifica e utilizzare i relativicampi di input del contenuto Per i campi di testo ad esempio Titolo Descrizione Testo del documento ecc crsquoegrave unmodo piugrave rapido per farlo ed egrave chiamato modifica in linea La modifica in linea egrave utilizzata durante la visualizzazionedellrsquoelemento stesso (il pannello Visualizza egrave attivo)
Quando il mouse passa sopra parti di testo modificabili un piccolo box evidenzieragrave il testo modificabile Nella seguenteschermata il cursore del mouse non si trova sopra un testo da modificare titolo della pagina e testo del documentovengono pertanto mostrati come di consueto
Ma quando il mouse viene spostato sopra il testo del documento un box lo metteragrave in evidenza permettendo la modi-fica
13 Gestione dei contenuti 55
Documentazione di Plone Release 4
56 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Facendo clic allrsquointerno del testo del documento dopo che il box della modifica in linea egrave apparso si attiveragrave lrsquoeditordi testo
Puoi cambiare o aggiungere del testo e salvare e tornare quindi alla visualizzazione normale Questa procedura egravenotevolmente piugrave veloce (in termini di numero di click e tempo di attesa) rispetto a quella che prevede di fare clic sulpannello Modifica ed attivare lrsquointero pannello di modifica per tutta la pagina
Se il mouse viene spostato sopra il titolo anchrsquoesso editabile appare un box di modifica in linea
Facendo clic sul titolo dopo che compare il box si attiva un campo di editing molto semplice con due bottoni di sceltaSalva e Annulla
Puoi cambiare il titolo e salvare Il vantaggio della velocitagrave della modifica in linea si percepisce soprattutto quando sideve modificare qualcosa di molto semplice come ad esempio un titolo
133 Viste per una cartella
Le cartelle hanno il tab Visualizza che permette di impostare i vari modi in cui puograve essere mostrato il contenutodella cartella stessa
Per la maggior parte dei contenuti puoi editare il contenuto stesso per cambiare il modo in cui esso appare Male cartelle sono tipi di contenuto particolari In quanto contenitori di altri elementi le cartelle posso mostrare il loro
13 Gestione dei contenuti 57
Documentazione di Plone Release 4
58 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
contenuto in vari modi tra loro diversi Spiegheremo in questa sezione le varie opzioni di visualizzazione del contenutodi una cartella
Ipotizza uno scenario in cui un appassionato di farfalle John Smith ha effettuato lrsquoaccesso al suo sito web per lavoraresu una sezione dedicata alle farfalle Skipper Egli naviga fino alla cartella ldquoSkipperrdquo tramite click sui tab principali delsito web cioegrave tramite il menugrave di navigazione che egrave posto a sinistra nel layout di default del suo sito Plone Quandoclicca sulla cartella ldquoSkipperrdquo viene mostrato il pannello di visualizzazione standard della cartella piugrave semplicementela ldquovista standardrdquo
Il tab Visualizza mostra sempre il modo in cui un qualsiasi contenuto appare al navigatore anonimo del sito web Faiclick sul tab Visualizza perciograve ogni volta che vuoi vedere come un contenuto che hai modificato viene visualizzatodagli utenti del sito Nel caso delle cartelle vedrai la lista dei contenuti in essa compresi in una delle diverse possibilitagravedi presentazione selezionabili tramite il menugrave a tendina Vista La vista di default egrave chiamata Vista standard
Di seguito invece come appare la Vista riassuntiva
E ancora la Vista tabellare
E infine la Vista provini che egrave particolarmente utile per le immagini ma funziona anche per gli altri tipi di contenuto
Creare un album fotografico in Plone egrave molto semplice Devi solo aggiungere le foto (immagini tipicamente in formatojpg) in una cartella ed impostare per la cartella stessa la Vista provini La vista si aggiorneragrave automaticamente manmano che aggiungi nuove immagini alla cartella mostrandole in maniera raggruppata allrsquointerno della pagina senecessario in ragione del numero crescente
13 Gestione dei contenuti 59
Documentazione di Plone Release 4
Se stai caricando immagini fotografiche da una macchina fotografica digitale o da uno scanner ti converragrave probabil-mente ridimensionarle sul tuo PC prima di caricarle perchegrave spesso esse sono troppo grandi
Impostare un singolo contenuto come vista per una cartella
La funzionalitagrave appena descritta che permette di impostare la vista di una cartella come un elenco di contenuti bensi adatta al modo in cui noi pensiamo alle cartelle ndash come contenitori di contenuti appunto ndash Plone tuttavia offreanche un modo facile di impostare come vista di una cartella anche un qualsiasi singolo contenuto della cartella stessaQuesta possibilitagrave massimizza il vantaggio che deriva dal fatto che il menugrave di navigazione di un sito web Plone sicompone in maniera automatica mappando dinamicamente le sue voci sulla struttura delle cartelle man mano chequeste vengono create
Puoi ad esempio impostare una singola pagina come vista di una cartella e ciograve puograve tornare utile nel caso volessimostrare il documento piugrave recente tra quelli presenti allrsquointerno della cartella stessa Oppure puoi impostare comevista una collezione che di per se egrave giagrave un potente strumento di filtro di contenuti Le impostazioni della vista di unacartella dovrebbero essere usate con attenzione poichegrave cambiano il modo in cui una cartella si comporta dallrsquoessere unsemplice contenitore allrsquoessere un collegamento diretto ad un contenuto Invece puoi spesso ottenere ciograve che desiderisemplicemente usando le collezioni che saranno descritte piugrave avanti in questo manuale
Di seguito proseguiremo analizzando il tab Contenuti per descrivere altre importanti funzioni per lrsquoaccesso ai con-tenuti presenti nella lista allrsquointerno di una cartella
134 Contenuti delle cartelle
Il tab Contenuti mostra la lista degli elementi in una cartella Ersquo il posto dove eseguire semplici operazioni suglielementi e dove eseguire azioni come copiare tagliare incollare spostare riordinare etc
Il tab Contenuti delle cartelle egrave come il ldquoGestione filerdquo o ldquoRisorse del Computerrdquo dei PC con Windows e Linux o illdquoCercardquo nei Mac OS X con funzionalitagrave simili
60 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
13 Gestione dei contenuti 61
Documentazione di Plone Release 4
62 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Cliccando sul tab Contenuti di una cartella come ad esempio la cartella ldquoSkippersrdquo qui sotto verragrave mostrato la pannelloContenuti
La scheda Contenuti egrave immediatamente riconoscibile per la presenza delle caselle di spunta (check boxes) accanto allevoci della lista Spunta le caselle per selezionare piugrave elementi ed eseguire su di essi le funzioni copia taglia rinominaelimina o cambia lo stato
Plone ha una ldquoarea appuntirdquo interna per la gestione delle operazioni di copia e taglia Se selezioni uno o piugrave elementie premi taglia o copia saragrave aggiunto un pulsante incolla in fondo alla scheda nella stessa riga dove si trovano gli altripulsanti Se a questo punto vai in unrsquoaltra cartella vi potrai incollare lrsquoelemento Utilizzando la funzione taglia glielementi rimangono nella cartella di origine ndash non scompariranno ndash finchegrave non saranno incollati da unrsquoaltra parte
Quando si Rinominano i contenuti verragrave mostrata una scheda dove inserire un nuovo valore per il nome breve (oid) dellrsquoelemento cosigrave come per il titolo La differenza tra il nome breve ed il titolo diventa evidente solo quandosi utilizza la funzione rinomina perchegrave di solito Plone crea automaticamente il nome breve dal titolo (senza che sianecessario impostarlo) Ma se utilizzi la funzione rinomina allora ti verranno mostrati sia il nome breve sia il titoloperchegrave tipicamente se modifichi uno vorrai modificare anche lrsquoaltro Considera il seguente esempio
Se vuoi modificare il titolo in ldquoLong-tailed Skippersrdquo vorrai cambiare anche il nome breve in ldquolong-tailed-skippersrdquoIn questo modo i due valori saranno entrambi corretti ed allineati cosigrave che lrsquoURL dellrsquoelemento (basato sul nomebreve) lrsquoindirizzo web saragrave aggiornato rispetto allrsquoelemento stesso Nota che il nome breve non deve contenere spaziUtilizza i trattini al posto degli spazi e se non ce ne sono fai una copia precisa del titolo Inoltre usa solo lettereminuscole per il nome breve Guarda la pagina Cosa crsquoegrave in un nome web per una descrizione di come Plone gestiscegli indirizzi web e i nomi brevi Il seguente video include anche la funzione rinomina
13 Gestione dei contenuti 63
Documentazione di Plone Release 4
Lrsquooperazione cancella egrave lineare Clicca per selezionare uno o piugrave elementi in seguito premi il pulsante cancella e glielementi saranno cancellati
Lrsquooperazione cambia stato offre un ottimo modo per cambiare lo stato di pubblicazione delle cartelle selezionate (edelle relative sotto-cartelle se hai selezionato questa opzione) Nel seguente esempio lo stato di pubblicazione dellacartella ldquoLong-tailed Skippersrdquo saragrave modificato Selezionando ldquoIncludi gli elementi contenutirdquo il cambiamento dellostato avragrave effetto anche su tutto il contenuto della cartella (incluse eventuali sotto-cartelle) Non dimenticare che questaoperazione puagrave essere fatta ad esempio per tre cartelle alla volta (con tutti i loro contenuti comprese le sotto-cartelle)cosicchegrave in un colpo solo puoi velocemente pubblicare rimuovere dalla pubblicazione ecc
Utilizza Shift-click per selezionare un intervallo di elementi Questo egrave molto utile in una cartella con piugrave di una dozzinadi elementi e risulta indispensabile in cartelle con centinaia di oggetti
In aggiunta a queste operazioni il riordinamento puograve essere fatto in maniera naturale con il mouse come descrittonella sezione successiva
135 Ordinamento elementi
Il tab dei contenuti contiene una funzione per lrsquoordinamento veloce e preciso degli elementi di una cartella
Considera la seguente cartella chiamata ldquoSkippersrdquo che contiene informazioni su questo tipo di farfalle Spessoquando aggiungiamo contenuti non li inseriamo nellrsquoordine finale che vorremmo ottenere Lrsquoordine desiderato nonegrave sempre quello alfabetico ma in questo esempio possiamo presumere di volere proprio questo tipo di ordinamentoSotto puoi vedere che le sottocartelle di Skipper non sono in ordine alfabetico
Per muovere lrsquoelemento piugrave in alto chiamato ldquoSpread-winged Skippersrdquo in fondo alla lista dovrai cliccare nellacolonna di sinistra per lrsquoOrdinamento (quella con il simbolo dei due punti ripetuti) e trascinare la riga nella posizionedesiderata
Il trascinamento si esegue tenendo premuto il pulsante del mouse mentre sposti lrsquoelemento Lrsquooggetto che stai spo-stando diventeragrave giallo e inizieragrave a muoversi
Quando rilascierai il pulsante del mouse lrsquoelemento si posizioneragrave in quel punto
136 Link Precedente - Successivo
La visualizzazione dei link automatici Precedente-Successivo per i contenuti presenti in una cartella puograve essereabilitata nel tab Impostazioni della cartella stessa
64 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
13 Gestione dei contenuti 65
Documentazione di Plone Release 4
Il tab Impostazioni viene visualizzato al click del tab Modifica della cartella Crsquoegrave una casella di spunta per abilitare ilink Precedente-Successivo per i vari elementi contenuti nella cartella
Una volta abilitati i link Precedente-Successivo compariranno automaticamente se necessario man mano che i varicontenuti verranno aggiunti alla cartella
Tre pagine sono state create allrsquointerno della cartella Cloudywings ed egrave stata selezionata la ldquoPagina Duerdquo (che in questoesempio non ha testo) Alla fine della ldquoPagina Duerdquo sono presenti i link ldquoPrecedente Pagina Unordquo e ldquoSuccessivoPagina Trerdquo
Questa egrave una funzione veramente utile
137 Cancellare contenuti da una cartella
I vari contenuti possono essere cancellati facilmente da una cartella
Alcune volte egrave necessario cancellare un contenuto spesso per rimpiazzarlo con una versione aggiornata Oppure egravesemplicemente necessario cancellare quel contenuto per diverse necessitagrave Nellrsquoesempio del contenuto relativo allafarfalla swallowtail aggiunto per errore alla cartella Skippers esso puograve essere semplicemente cancellato invece chetagliato ed incollato in qualche altra cartella
Nellrsquoesempio mostrato sopra la cartella Eastern Tiger Swallowtail saragrave cancellata al click del bottone Cancella
Intere cartelle possono essere cancellate con un solo click perciograve egrave bene fare molta attenzione anche se questa egrave unaregola che vale in generale quando si lavora ad un PC Tutti noi abbiamo imparato a nostre spese che egrave sempre megliofare un ultimo controllo prima della cancellazione per essere sicuri che cancellare egrave proprio quello che vogliamo fare
66 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Fig 12 Esempio di Ordinamento
13 Gestione dei contenuti 67
Documentazione di Plone Release 4
68 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
13 Gestione dei contenuti 69
Documentazione di Plone Release 4
70 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
138 Blocco e sblocco automatico dei contenuti
Plone visualizza un messaggio che riporta se un contenuto egrave bloccato chi lrsquoha bloccato e da quanto tempo egravestato bloccato - in tal modo non potrai interferire con i cambiamenti apportati a quel contenuto da un altroutente
Quando qualcuno fa un click sul tab Modifica di un contenuto questrsquoultimo viene immediatamente bloccato Questafunzione previene che due persone editino contemporaneamente lo stesso contenuto e che un utente sovrascriva acci-dentalmente con le proprie modifiche quelle fatte da un altro utente In questo esempio George Schrubb ha iniziatoad editare il contenuto ldquoWidget Installationrdquo Quando Jane Smythe (anche lei con i permessi di modifica dellrsquooggetto)visualizza lo stesso contenuto vedragrave quanto mostrato nella figura che segue
Una volta che George ha finito di editare il contenuto e fatto click sul bottone Salva il contenuto viene automaticamentesbloccato e reso disponibile agli altri editori (sempre che come ovvio abbiano i permessi di modifica sul contenuto inquestione)
In ogni caso se egrave evidente che George non sta lavorando in quel momento sul contenuto (ad esempio il messaggioriporta che il contenuto egrave stato bloccato diversi giorni prima e non pochi minuti prima) allora egrave la stessa Jane che puograveldquosbloccarlordquo e renderlo disponibile per nuove modifiche
Nelle versioni a partire da Plone 33
Se un utente abbandona la pagina di modifica di un contenuto senza un click sui bottoni Salva o Cancella il blocco delcontenuto rimane attivo per i successivi dieci minuti trascorsi i quali il contenuto viene automaticamente sbloccatoQuesta funzione ldquotimeoutrdquo egrave importante soprattutto per tutti quei browser come ad esempio Safari che non eseguonocorrettamente lrsquoazione javascript ldquoon-unloadrdquo
Se desideri disabilitare le funzioni di blocco dei contenuti devi accedere al pannello di controllo di Plone (Configu-razione Sito -gt Sito) e deselezionare la casella di spunta Enable locking for through-the-web edits
139 Controllo di versione
Una panoramica su come visualizzare la cronologia delle versioni di un elemento confrontare le versioni visu-alizzare in anteprima le versioni precedenti e ripristinare versioni precedenti
13 Gestione dei contenuti 71
Documentazione di Plone Release 4
Creare una nuova versione
Plone include una funzione per gestire le versioni Per impostazione predefinita i seguenti tipi di contenuti hanno ilcontrollo di versione abilitato
bull Pagina
bull Notizia
bull Eventi
bull Collegamento
Si noti che tutti gli altri tipi di contenuto mantengono la storia del flusso del workflow associato
I tipi di contenuto possono essere configurati per avere il controllo di versione abilitatodisabilitato attraverso il pan-nello di Configurazione del Sito alla voce ldquoTipi di contenutordquo
Quando modifichi un elemento puoi utilizzare il campo commento alle modifiche in fondo il commento alle mod-ifiche verragrave memorizzato nella cronologia delle versioni dellrsquoelemento Se il commento alle modifiche viene lasciatovuoto Plone includeragrave una nota standard ldquoRevisione inizialerdquo
Una nuova versione viene creata ogni volta che un elemento viene salvato Il controllo di versione tiene traccia diqualsiasi modifica effettuata contenuti metadata impostazioni etc
Visualizzazione della cronologia delle versioni
Una volta salvato un oggetto egrave possibile utilizzare il link Cronologia situato nella parte superiore della pagina Conun semplice click sul link egrave possibile visualizzare la Cronologia in una finestra sovrapposta alla pagina
La versione piugrave recente egrave la prima voce dellrsquoelenco La viewlet della Cronologia fornisce le seguenti informazioni
bull Il tipo di modifica (al contenuto o al workflow)
bull quale utente ha fatto la modifica
bull in che data e ora egrave stata fatta la modifica
72 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Confrontare le versioni
Dalla viewlet della Cronologia puoi confrontare qualsiasi versione precedente con quella corrente o qualsiasi altraversione con quella appena prima
Per confrontare qualsiasi versione precedente con quella appena prima cliccare sul link Confronta collocato tra le dueversioni nella finestra della Cronologia
Cliccando su questo link vedrai un una schermata come questa in cui egrave possibile vedere le differenze fra le dueversioni
In questo esempio il testo in rosso egrave quello che egrave stato cancellato e il testo in verde egrave quello che egrave stato aggiunto allaversione piugrave recente Egrave possibile visualizzare le differenze tra le versioni in modalitagrave in linea o come codice
13 Gestione dei contenuti 73
Documentazione di Plone Release 4
Egrave inoltre possibile confrontare qualsiasi versione precedente con la versione corrente cliccando sul link Confronta conversione attuale nella finestra della Cronologia situato allrsquoestrema destra di ogni versione elencata
Visualizzare e tornare alle versioni precedenti
Puoi fare una anteprima di qualsiasi versione precedente di un documento cliccando il link Visualizza alla destradi ogni versione elencata
Per tornare ad una versione precedente clicca sul pulsante Ripristina questa versione alla destra di ogni versioneelencata
1310 Modalitagrave di presentazione
Plone viene fornito con la possibilitagrave di creare semplici presentazioni di diapositive
La Modalitagrave di Presentazione egrave una funzione speciale del tipo di contenuto Pagina Puoi abilitare la Modalitagrave diPresentazione modificando la pagina entrando nella linguetta Impostazioni Nota che ligrave saragrave presente la checkboxModalitagrave di Presentazione Una volta selezionata un link appariragrave nella vista della pagina per dare la possibilitagrave ad unutente di visualizzarla nella Modalitagrave di Presentazionee
Come creare una diapositiva
Tutto il contenuto di una presentazione rimane in una sola pagina Non devi creare una pagina per ogni diaposi-tiva Una dispositiva viene creata quando vedi la classe Intestazione (h1) nella pagina - queste intestazioni indicanoeffettivamente a Plone dove si vuole far iniziare una diapositiva
Non ci sono limiti al numero di diapositive che puoi aggiungere in una presentazione Ti basta inserire piugrave tagsIntestazione (h1) nella tua pagina ed il contenuto tra quel tag h1 e quello successivo diverragrave il contenuto della tuadiapositiva
Come Formattare una Diapositiva
Ersquo molto importante notare che i contenuti con associato lo Stile Paragrafo Normale non vengono visualizzati nellediapositive Le diapositive sono pensate per visualizzare informazioni di riepilogo non blocchi di testo Per questodevi dare uno stile diverso dal Paragrafo Normale al contenuto di ogni diapositiva Esempi di questi stili sono
bull Intestazione (h1)
bull Sottotitolo (h3)
bull Definizioni di liste
bull Liste non ordinate
bull Liste ordinate
bull Literal
bull Pull-quote
bull Call out
bull Evidenziato
74 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
1311 Copia di lavoro
La Copia di Lavoro ti permette di avere due versioni del tuo contenuto in parallelo
Quando un sito Plone viene creato per la prima volta ci sono diverse funzioni aggiuntive che possono essere abilitatetra cui la ldquoCopia di Lavorordquo Se il sito Plone che stai usando non presenta lrsquoopzione ldquoEstrai versionerdquo nel menu Azioni devi contattare lrsquoamministratore del sito e richiedere che il ldquoSupporto alla Copia di Lavorordquo venga installato
Panoramica
In precedenza potresti esserti trovato in una situazione come questa hai pubblicato un contenuto e lo devi aggiornarecon frequenza ma vuoi che la vecchia versione continui ad esistere sul sito web finchegrave non hai quella nuova dapubblicare Vuoi anche che il nuovo contenuto sostituisca quello attuale ma ti piacerebbe mantenere la storia diquello vecchio La Copia di Lavoro rende tutto questo possibile
In sostanza ldquoestrairdquo la versione attualmente pubblicata del contenuto creandone cosigrave una ldquocopia di lavorordquo A questopunto potrai modificare la copia di lavoro (mettendoci tutto il tempo che ti serve) e quando la nuova versione saragravepronta per essere pubblicata utilizzando lrsquoazione ldquocrea versionerdquo la tua copia di lavoro sostituiragrave quella online Dietrole quinte Plone sostituiragrave il contenuto originale con quello nuovo nellrsquoesatta posizione e con lo stesso indirizzo webe archivieragrave la vecchia versione come parte della storia nel controllo di versione del contenuto nuovo
Utilizzare la funzione ldquoEstrairdquo
In primo luogo raggiungi la pagina che intendi rivedere Poi dal menu ldquoAzionirdquo seleziona ldquoEstrairdquo
Appariragrave un messaggio per informarti che da quel momento stai lavorando su una copia di lavoro
13 Gestione dei contenuti 75
Documentazione di Plone Release 4
Ora puoi liberamente modificare la copia locale del contenuto pubblicato Il contenuto originale risulteragrave ldquobloccatordquo ndashovvero nessun altro potragrave modificare la versione pubblicata finchegrave avrai una copia di lavoro estratta Questo impediragraveche mentre stai modificando la tua copia di lavoro altre modifiche vengano apportate (e conseguentemente perse)sulla versione pubblicata
Utilizzare la funzione ldquoCrea versionerdquo
Quando sei pronto a sostituire la tua copia locale con quella pubblicata ti basta semplicemente selezionare ldquoCreaversionerdquo dal menu ldquoAzionirdquo
Ti verragrave richiesto di inserire un commento legato alla creazione della nuova versione Compilalo e clicca su ldquoCreaversionerdquo
Il tuo contenuto aggiornato diventeragrave la nuova copia pubblicata
Verrai inoltre informato che non esisteragrave piugrave una copia di lavoro del documento nella tua cartella personale
Nota che non egrave necessario (ed infatti non egrave consigliata) lrsquoutilizzo del menu ldquoStatordquo con una copia di lavoro Se tuttavialo utilizzi senza volere non farti prendere dal panico Ti basta tornare nella tua copia di lavoro e utilizzare la funzioneldquoCrea versionerdquo dal menu ldquoAzionirdquo
76 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
13 Gestione dei contenuti 77
Documentazione di Plone Release 4
Cancellare una ldquoCopia di lavorordquo
Se per qualsiasi motivo devi cancellare una copia di lavoro e non vuoi salvare le tue modifiche vai semplicementenella copia di lavoro e clicca su ldquoAnnulla il check-outrdquo
Ti verragrave chiesto di confermare il comando ldquoAnnulla il check-outrdquo o di ldquoMantenere il checkoutrdquo
Nota che se un utente che ha estratto una copia di lavoro non egrave disponibile per effettuare la pubblicazione della copiadi lavoro o annullarla gli utenti con il ruolo di Manager possono accedere alla copia di lavoro ed effettuare sia lacreazione della versione che lrsquoannullamento della copia di lavoro Questo percheacute non tutti i collaboratoti hanno ilprivilegio di eseguire la funzione ldquoCrea versionerdquo Se tale opzione non egrave presente dal menu Azioni
1 Utilizza il menu ldquoStatordquo
2 Sottoponi per pubblicazione
3 Chiedi ad un recensore di non cambiare lo stato
4 Chiedi invece al revisore di effettuare il ldquoCrea versionerdquo per tuo conto
La procedura ldquoCrea versionerdquo si occuperagrave della gestione dello stato
78 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
14 Usare TinyMCE come visual editor
141 Introduzione
Introduzione a TinyMCE
TinyMCE egrave un editor WYSIWYG (What You See Is What You Got) in Javascript basato su una piattaforma webindipendente con il quale egrave possibile creare contenuti HTML sul proprio sito web TinyMCE supporta molti SistemiOperativi e browsers Alcuni esempi sono Mozilla Internet Explorer Firefox Opera Safari e Chrome TinyMCE haalle spalle una consistente base di utenti e una community di sviluppo molto attiva
TinyMCE egrave lrsquoeditor visuale di default a partire da Plone 40 sebbene Kupu sia comunque disponibile per gli utentiche lo preferiscono Si egrave deciso di fornire TinyMCE come editor di default perchegrave Kupu non egrave un componenteadeguatamente manutenuto laddove TinyMCE puograve vantare sia un utilizzo molto piugrave diffuso in diverse communitysia una piugrave ampia disponibilitagrave di plugin oltre a funzioni native molto interessanti come ad esempio la possibilitagrave diaggiungere link sia interni sia esterni utilizzando lo stesso pulsante
142 Nozioni di base
Opzioni base di TinyMCE
Lrsquoeditor TinyMCE di default ha il seguente aspetto
Nella parte alta puoi vedere la barra degli strumenti sotto lrsquoarea di testo ed in fondo una barra per il ridimensionamentoSe trascini lrsquoangolo in basso a destra puoi allargare o ridurre la finestra dellrsquoeditor
Barra degli strumenti
La seguente tabella descrive le funzioni ed il risultato di ogni pulsante
143 Inserire delle immagini
Una panoramica delle opzioni disponibili per lrsquoinserimento di immagini in TinyMCE
Lrsquoeditor TinyMCE ti permette di inserire delle immagini caricate in Plone nella tua pagina utilizzando il bottone sullabarra degli strumenti di TinyMCE
Cliccando su questo bottone si apre la finestra per inserire un immagine
Le tre colonne della finestra sono
bull nella prima colonna crsquoegrave la lista di navigazione delle cartelle
bull nella seconda colonna crsquoegrave la lista dei contenuti della cartella corrente
bull nella terza colonna crsquoegrave lrsquoanteprima dellrsquoimmagine le opzioni di allineamento le dimensioni disponibili permostrare lrsquoimmagine e la didascalia
Nellrsquoesempio sopra egrave stata selezionata lrsquoimmagine di una rosa - rosepng ( lrsquoimmagine originale egrave piuttosto grande600450 pixel)
Lrsquoimmagine verragrave posizionata nella pagina in accordo al ldquoAllineamentordquo scelto e verragrave generato il seguente codiceHTML
bull A sinistra (ltimg class=rdquoimage-left captionedrdquo src=rdquorosepngrdquo alt=rdquoroserdquo gt)
bull A destra (ltimg class=rdquoimage-right captionedrdquo src=rdquorosepngrdquo alt=rdquoroserdquo gt)
14 Usare TinyMCE come visual editor 79
Documentazione di Plone Release 4
80 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
14 Usare TinyMCE come visual editor 81
Documentazione di Plone Release 4
82 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
bull In linea (ltimg class=rdquoimage-inline captionedrdquo src=rdquorosepngrdquo alt=rdquoroserdquo gt)
Puoi anche scegliere la dimensione dellrsquoimmagine di cui hai bisogno Questo egrave particolarmente utile quando hai a chefare con immagini di grandi dimensioni poichegrave non crsquoegrave bisogno di utilizzare Photoshop o altre applicazioni esterneper ritagliare o modificare lrsquoimmagine Il menu a tendina ldquoDimensionirdquo ti consente di scegliere tra diverse dimensionie formati
bull Large (ltimg src=rdquorosepngimage_largerdquo alt=rdquoroserdquo gt)
bull Preview (ltimg src=rdquorosepngimage_previewrdquo alt=rdquoroserdquo gt)
bull Mini (ltimg src=rdquorosepngimage_minirdquo alt=rdquoroserdquo gt) - questa egrave la dimensione minima per la visualizzazionedellrsquoimmagine
bull Thumb (ltimg src=rdquorosepngimage_thumbrdquo alt=rdquoroserdquo gt) - a thumb(inch)- dallrsquoimmagine verragrave estratta unaminiatura (un pograve piugrave piccola di 25cm)
bull Tile (ltimg src=rdquorosepngimage_tilerdquo alt=rdquoroserdquo gt) - dallrsquoimmagine viene ricavata una lsquomattonellarsquo
bull Icon (ltimg src=rdquorosepngimage_iconrdquo alt=rdquoroserdquo gt) - dallrsquoimmagine verragrave ricavata unrsquoicona
bull Listing (ltimg src=rdquorosepngimage_listingrdquo alt=rdquoroserdquo gt) - dallrsquoimmagine verragrave ricavata una piccola immaginein stile lsquoelencorsquo
Didascalia dellrsquoimmagine
In TinyMCE egrave possibile inserire una didascalia sotto lrsquoimmagine La didascalia egrave presa dalla descrizionedellrsquoimmagine Il testo alternativo egrave tratto dal titolo dellrsquoimmagine Il testo alternativo e la didascalia si aggiornanoautomaticamente se lrsquoimmagine viene aggiornata
Per abilitare questa funzione accedi a Configurazione del sito -gt Editor TinyMCE Assicurati di selezionare Con-senti la lsquotitolazionersquo delle immagini nel pannello Tipi di risorse
Quando aggiungi unrsquoimmagine sul sito puoi inserire una breve descrizione e questa verragrave utilizzata come didascalia
Ora quando crei una pagina e inserisci unrsquoimmagine in essa seleziona il box Didascalia
Salvando le modifiche il risultato dovrebbe essere simile a questo con la descrizione dellrsquoimmagine inserita comedidascalia allrsquointerno di una cornice
144 Inserire collegamenti (links)
Inserire collegamenti interni esterni ed ancore
14 Usare TinyMCE come visual editor 83
Documentazione di Plone Release 4
84 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
14 Usare TinyMCE come visual editor 85
Documentazione di Plone Release 4
86 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Collegamenti interni
Seleziona una parola o una frase fai click sullrsquoicona Inseriscimodifica collegamento ed appariragrave il pannello In-
seriscimodifica collegamento
Il pannello va usato selezionando la cartella Home o quella corrente per iniziare a navigare allrsquointerno del sito Plonealla ricerca della cartella della pagina o dellrsquoimmagine cui far puntare il collegamento Nellrsquoesempio della figurasopra la pagina ldquoLong-tailed Skippersrdquo egrave stata scelta come destinazione del link Una volta chiuso il pannello un col-legamento alla pagina ldquoLong-tailed Skippersrdquo verragrave creato per la parola o la frase scelta come testo del collegamento
Collegamenti esterni
Seleziona una parola o una frase fai click sullrsquoicona Inseriscimodifica collegamento seleziona ldquoBarra degli strumentiesternardquo nella colonna Librerie si apriragrave un pannello simile a questo
Digita lrsquoindirizzo del sito web esterno cui vuoi far puntare il collegamento nella casella dopo http Quando premiInvio sulla tastiera o clicchi in un altro punto del pannello diverso dal campo di input appariragrave una preview perpermetterti di verificare che il sito web scelto sia quello giusto Se incolli lrsquoindirizzo web assicurati che la stringahttp non venga duplicata Quindi clicca Ok Il collegamento esterno verragrave impostato per la parola o la frase che haiselezionato
Ancore
Le ancore sono lsquosegnapostirsquo allrsquointerno di un documento legate a titoli sottotitoli o altri stili impostati per il documentostesso Ad esempio per la pagina ldquoEastern Tiger Swallowtail con sottotitoli Descriptionrdquo ldquoHabitatrdquo ldquoBehaviorrdquoldquoConservation Statusrdquo e ldquoLiteraturerdquo egrave possibile impostare un insieme di collegamenti ai vari sottotitoli utilizzando leancore
Per prima cosa crea il documento impostanto i vari sottotitoli nel corpo e riscrivi i sottotitoli allrsquoinizio del documento
14 Usare TinyMCE come visual editor 87
Documentazione di Plone Release 4
Ora crea le ancore per ciascun sottotitolo Per creare unrsquoancora muovi il cursore allrsquoinizio del sottotitolo e fai clicksullrsquoicona ldquoInseriscimodifica ancorardquo Inserici il nome dellrsquoancora nellrsquoapposito campo Quindi fai click su Ok
Poi seleziona uno dei sottotitoli che hai riscritto allrsquoinizio del documento e fai click sullrsquoicona Inseriscimodificacollegamento
Selezionando Ancore dalla colonna ldquoLibrerie appariragrave un pannello che ti permette di selezionare il sottotitolo cui farpuntare il collegamento
Il tab ldquoCollegamento ad unrsquoancorardquo appariragrave La parte destra del pannello mostra le ancore che sono state impostateper il documento Nellrsquoesempio lrsquoancora Description egrave stata scelta come destinazione del collegamento (ed impostataper la parola Description allrsquoinizio del documento)
Ci si puagrave sbizzarrire con questa potente funzionalitagrave impostando ancore per i vari stili del documento ed inserendo irelativi collegamenti allrsquointerno delle parti narrative di un documento Ciograve puograve rivelarsi particolarmente utile nel casodi documenti di grosse dimensioni
145 Inserire Tabelle
Inserire aggiornare e cancellare tabelle colonne righe e celle
Le tabelle sono ideali per mostrare dati in formato tabulare e liste Per aggiungere una tabella posiziona il cursore nelpunto in cui vuoi che la tabella sia creata e fai click sullrsquoicona Inserisci una nuova tabella Avrai accesso al pannelloInserisciModifica Tabella
Impostare il numero di colonne e righe egrave intuitivo Se lo desideri puoi aggiungere anche un sommario della tabelletramite lrsquoapposito campo Le classi assegnabili alla tabella ti permettono di decidere lo stile da applicare Puoiscegliere tra opzioni come quelle mostrate nella figura che segue
Di seguito alcuni esempi degli stili disponibili
88 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
14 Usare TinyMCE come visual editor 89
Documentazione di Plone Release 4
90 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
14 Usare TinyMCE come visual editor 91
Documentazione di Plone Release 4
Subdued grid
Invisible grid
Fancy listing
Fancy grid listing
Fancy vertical listing
Una volta creata la tabella egrave possibile far apparire i comandi di ridimensionamento manuale cliccando in una cellaqualsiasi
Nellrsquoesempio mostrato dalla figura sopra il cursore viene posizionato nella prima cella in alto a sinistra ciograve fa appariredei piccoli quadratini lungo i bordi della tabella che possono essere utilizzati per modificare le dimensioni della tabellastessa Cliccando su una cella qualsiasi compariranno inoltre nella barra degli strumenti i comandi specifici dellatabella potremo cosigrave editare le proprietagrave di una riga a di una cella aggiungere o eliminare righe o colonne dividere ounire celle
15 Usare Kupu come visual editor
Kupu egrave una piattaforma indipendente un editor Javascript HTML WYSIWYG web based Questo significache ti consente di creare contenuti HTML sul tuo sito web
Da Plone 4 in poi TinyMCE egrave il visual editor predefinito per i nuovi siti Tuttavia Kupu egrave ancora disponibile se lopreferisci Controlla la sezione Impostare il tuo profilo per imparare a impostare Kupu come il tuo editor predefinito
Una tipica barra degli strumenti Kupu assomiglia a questa
92 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
15 Usare Kupu come visual editor 93
Documentazione di Plone Release 4
94 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Il formato testo viene normalmente lasciato con lrsquoimpostazione HTML ma alcuni siti offrono testo strutturato o altrilinguaggi di markup per la modifica delle pagine
Le icone sono
bull grassetto
bull italico
bull giustificato a sinistra
bull giustificato centrato
bull giustificato a destra
bull elenco numerato
bull elenco puntato
bull elenco di definizioni
bull tab a sinistra (blocco)
bull tab a destra (blocco)
bull immagine (lrsquoicona ldquoalberordquo)
bull link interno (lrsquoicona ldquoanello della catenardquo crea un link a unrsquoaltra pagina nel sito)
bull link esterno (lrsquoicona ldquomondordquo crea un link a una pagina web altrove)
bull ancora (lrsquoicona ldquoancorardquo crea un link ad una sezione specifica di una pagina)
bull tabella (aggiunge una tabella con righe e colonne)
bull HTML editing diretto (lrsquoicona ldquoHTMLrdquo se si conosce HTML modifica direttamente il codice HTML per lapagina)
bull menu a tendina per lo stile del testo
151 Immagini
Posizionare il cursore allrsquointerno del testo di una pagina fare click sullrsquoicona ldquoalberordquo Si apriragrave questo pannello
15 Usare Kupu come visual editor 95
Documentazione di Plone Release 4
Fare click su ldquoCartella Correnterdquo nella parte sinistra del pannello se non egrave giagrave evidenziata La cartella corrente egrave lacartella che contiene la pagina che si sta modificando - tutte le pagine sono contenute in cartelle Ci sono molti modi pergestire la memorizzazione di immagini tra cui avere una cartella centrale di immagini ma un metodo comune egrave quellodi memorizzare le immagini mostrate su una pagina nella cartella che contiene la pagina stessa (la cartella corrente)In questo modo le pagine e le immagini ad esse associate sono memorizzate insieme allrsquointerno della struttura dellecartelle Se fai click sul pulsante Carica ti verragrave chiesto di selezionare unrsquoimmagine sul tuo computer e caricarlaDopo aver selezionato lrsquoimmagine da caricare il pannello di destra ti permetteragrave di dare allrsquoimmagine un titolo perlrsquouso sul sito web e diverse opzioni per la posizione e il dimensionamento dellrsquoimmagine Facendo click su OK vienecaricata lrsquoimmagine e collocata nella pagina Lo stesso pannello appariragrave se si seleziona unrsquoimmagine nella pagina esi fa click sulla stessa icona ldquoalberordquo per modificare le opzioni dellrsquoimmagine selezionata o sostituirla con un altraimmagine Sei responsabile per il dimensionamento e lrsquoediting delle immagini sul tuo computer prima di caricarle maun modo semplice per gestire le immagini da usare sulla maggior parte delle pagine web egrave quello di fare una copia diunrsquoimmagine sul computer quindi ridimensionarla a qualcosa come 1000 pixel nella dimensione piugrave grande Questoegrave una dimensione ragionevole per il caricamento - non egrave necessario caricare le tue immagini gigantesche provenientidalla fotocamera digitale Plone creeragrave automaticamente diversi formati di unrsquoimmagine caricata tra cui ldquolargerdquoldquominirdquo e altre dimensioni Si sceglie la dimensione che si desidera utilizzare quando si carica o modifica lrsquoimmaginecon lrsquoicona ldquoalberordquo Egrave anche possibile impostare la dimensione dellrsquoimmagine modificando direttamente il codiceHTML
152 Collegamenti Interni
Selezionare una parola o una frase fare click sullrsquoicona Collegamento interno e appariragrave il pannello Inserisci ollega-mento
Puoi utilizzare questo pannello facendo click sulla cartella Home o sulla cartella Corrente per iniziare la navigazionenel sito web Plone e per trovare una cartella una pagina o lrsquoimmagine verso cui creare un collegamento Nel prece-dente esempio egrave stata scelta per il collegamento una pagina denominata ldquoLong-tailed Skippersrdquo Dopo che il pannellosi egrave chiuso verragrave impostato un collegamento alla pagina ldquoLong-tailed Skippersrdquo per la parola o per la frase selezionataper il collegamento
96 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
153 Collegamenti Esterni
Selezionare una parola o una frase fare click sullrsquoicona Collegamento esterno e appariragrave il pannello CollegamentoEsterno
Digitare lrsquoindirizzo web del sito esterno nel box che inizia con http Egrave possibile fare click su anteprima se haibisogno di controllare lrsquoindirizzo Se incolli lrsquoindirizzo web assicurati di non duplicare http allrsquoinizio dellrsquoindirizzoPoi fai click su OK Il collegamento esterno verragrave impostato per la parola o la frase selezionata
15 Usare Kupu come visual editor 97
Documentazione di Plone Release 4
154 Le Ancore
Le Ancore sono dei link in un documento che puntano direttamente ad una sezione del documento stesso sulla basedi titoli sottotitoli o altri stili definiti allrsquointerno del documento stesso Ad esempio in una pagina chiamata ldquoEasternTiger Swallowtailrdquo in cui sono definite delle sottosezioni intitolate ldquoDescriptionrdquo ldquoHabitatrdquo ldquoBehaviorrdquo ldquoConserva-tion Statusrdquo e ldquoLiteraturerdquo egrave possibile creare un semplice elenco di link a queste sottovoci (che puntano direttamentealla sottovoce allrsquointerno del documento) utilizzando le ancore
Per prima cosa crea il documento con i sottotitoli e riscrivi i sottotitoli allrsquoinizio del documento come per un indice
Quindi seleziona ogni sottotitolo riscritto allrsquoinizio del documento e clicca lrsquoicona a forma di ancora
Appariragrave una maschera che permetteragrave di selezionare quale sottotitolo deve essere collegato allrsquoancora
Verragrave visualizzata la scheda Collegamento allrsquoancora La sezione di sinistra mostreragrave una lista di stili che posso essereutilizzati nel documento Nel nostro esempio i sottotitoli verranno usati per ogni sezione ed egrave il caso piugrave comune Laparte destra mostreragrave i sottotitoli che sono stati creati nel documento Nel nostro caso verragrave selezionato il sottotitoloDescription (per creare il collegamento con lo stesso riscritto allrsquoinizio del documento)
Puoi essere molto creativo con questa potente funzione tessendo un testo dinamico intelligente con diversi riferimentiinterni alle varie sezioni della narrazione Questa funzionalitagrave egrave particolarmente importante per i documenti lunghi
155 Tabelle
Le tabelle sono ideali per la visualizzazione di dati tabulari e liste Per aggiungere una tabella posiziona il cursore nelpunto desiderato e fai click sullrsquoicona Aggiungi tabella Vedrai il pannello Aggiungi tabella
Lrsquoimpostazione delle righe e delle colonne egrave semplice Se selezioni il box Crea Intestazioni avrai un posto dovedigitare le intestazioni della colonna per la tabella La classe della tabella si riferisce al suo stile Hai scelte comequeste
Ecco alcuni esempi di questi stili per la tabella
plain
Thoroughbred Champions Quarter Horse ChampionsMan Orsquo War First Down DashSecretariat Dashing FollyCitation Special LeaderKelso Gold Coast ExpressCount Fleet Easy Jet
listing
Thoroughbred Champions Quarter Horse ChampionsMan Orsquo War First Down DashSecretariat Dashing FollyCitation Special LeaderKelso Gold Coast ExpressCount Fleet Easy Jet
Dopo che la tabella egrave stata creata puoi fare click in una cella per far apparire i comandi necessari al ridimensionamentodella tabella e le icone per aggiungereeliminare righe e colonne
98 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
15 Usare Kupu come visual editor 99
Documentazione di Plone Release 4
100 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
15 Usare Kupu come visual editor 101
Documentazione di Plone Release 4
Nella tabella sopra il cursore egrave stato posizionato nella cella ldquoSpecial Leaderrdquo esso attiva i quadratini di gestioneintorno ai bordi per ridimensionare lrsquointera tabella Attiva anche le icone aggiungereeliminare per la cella corrente lacella ldquoSpecial Leaderrdquo Cliccando sulla piccola x nel cerchio si elimina lrsquointera riga o colonna che contiene lrsquoattualecella Cliccando le piccole icone a punta di freccia si aggiunge una riga sopra o al di sotto o una colonna a sinistra oa destra della cella corrente
156 Stile del Testo
Lrsquoimpostazione dello stile del testo egrave fatta con un menu a tendina Ecco le scelte
Come in un normale editor di testi seleziona una parola una frase o paragrafo con il mouse quindi scegli una delle
102 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
opzioni di stile del menu a tendina e vedrai la modifica immediatamente
157 Salvare
Fare click sul pulsante Salva in fondo e le modifiche della pagina saranno memorizzate
158 Note a piegrave di pagina
Linguaggi di mark-up
Se sei il tipo di persona che ama inserire il testo utilizzando i cosiddetti formati mark-up egrave possibile disattivarelrsquoeditor visuale sotto le tue preferenze personali e un pannello semplificato di inserimento testo andragrave a sostituireKupu I formati mark-up disponibili in Plone sono
bull Markdown
bull Textile
bull Structured Text
bull Restructured Text
Ognuno di questi funziona incorporando speciali codici di formattazione allrsquointerno del testo Ad esempio con laformattazione Structured Text circondando una parola o una frase da un asterisco doppio si otterragrave quella parola ofrase in grassetto come in Questo testo saragrave in grassetto Vale la pena di imparare questi formati di mark-up per lavelocitagrave di inserimento se si creano molte pagine o se si preferiscono approcci per lrsquoinserimento di testo leggermentepiugrave tecnici Alcune persone preferiscono questi formati non solo per la velocitagrave in seacute ma per fluiditagrave di espressione
16 Collaborazione e flusso di lavoro
Imparare a condividere e controllare lrsquoaccesso al contenuto utilizzando la Scheda Condivisione e il menu Stato
161 Stati di pubblicazione di base
Il sistema di controllo della pubblicazione di Plone egrave molto flessibile a partire dalle impostazioni di base per lacreazione di un elemento privato o pubblico
Nellrsquoangolo in alto a destra del riquadro di modifica di qualsiasi tipo di contenuto ndash cartelle immagini pagine etc etutti i tipi di contenuto specializzati ndash crsquoegrave il menu per gestire lo stato di pubblicazione Questo menu degli stati gestiscelo stato della pubblicazione
Lrsquointestazione del menu mostreragrave lo stato di pubblicazione attuale del contenuto ad esempio Stato Privato comemostrato sopra Lo stato Privato egrave lo stato iniziale al momento della creazione di un elemento ndash unrsquoimmagine caricatauna pagina una notizia ndash ed in questo stato come indica il nome lrsquoelemento non saragrave generalmente fruibile daivisitatori del sito web Scegliendo dal menu lo stato Pubblica il contenuto diverragrave fruibile agli utenti anonimi delsito Lrsquoopzione Sottoponi per pubblicazione viene utilizzata nei siti dove ci sono dei revisori di contenuti che devonoapprovare lrsquoelemento per la pubblicazione come descritto in seguito
Inoltre e questo saragrave molto importante certi tipi di contenuto come ad esempio le notizie e gli eventi non apparirannosul sito web come ti aspetteresti fino a quando non verranno esplicitamente pubblicati
Imprimiti nella memoria che Lo stato di pubblicazione egrave importante
16 Collaborazione e flusso di lavoro 103
Documentazione di Plone Release 4
Lo stato di pubblicazione puograve essere modificato solo dagli utenti che dispongono delle autorizzazioni necessarie Lescelte nel menu rispecchieranno le autorizzazioni possedute Ad esempio in un sito web di un grande giornale ungiornalista potrebbe aggiungere delle pagine come se fossero degli articoli ma il menu di pubblicazione non mostreragravela scelta Pubblica ma solo Sottoponi per pubblicazione Questo perchegrave il giornalista prima della pubblicazione deveinviare lrsquoarticolo alla redazione per lrsquoapprovazione Se tuttavia il tuo account ha i permessi la scelta Pubblica saragravedisponibile e potrai semplicemente pubblicarlo in un solo passaggio
Per un editore un contenuto che egrave stato sottoposto per la pubblicazione puograve essere pubblicato o revocato revocatonei casi in cui lrsquoinvio sia inappropriato rispetto alla situazione o per la ragione piugrave comune ovvero che il contenuto habisogno di essere revisionato
Dopo che un elemento egrave stato pubblicato puograve essere revocata la pubblicazione per reimpostare lo stato alla bozzapubblica o mandarlo indietro allo stato privato Le scelte del menu di pubblicazione cambieranno di conseguenza
Occorre prendere in considerazione di revocare (ldquoannullamento della pubblicazionerdquo) o di rendere privato qualsiasicontenuto che egrave diventato obsoleto o indesiderato per qualsiasi ragione Lrsquoimpostazione privato renderagrave lrsquoelementoinvisibile al pubblico e nei risultati delle ricerche ma rimarragrave nel caso in cui il format o i contenuti (testo immaginietc) servano in futuro Questo egrave utile soprattutto per i contenuti relativi a eventi che possono ripresentarsi o a contenutiche fanno parte di una serie di contenuti simili La decisione di cancellare un contenuto a semplicemente impostarlocome privato dipende dalla disponibilitagrave di una copia del contenuto stesso sul proprio PC Se il contenuto egrave di grandidimensioni nel senso di spazio su disco occupato egrave probabilmente opportuno farsene una copia locale prima diconcellarlo se lo spazio sul server egrave un problema
162 Controllo avanzato
Il sistema di controllo della pubblicazione alla voce del menu avanzate ha caratteristiche sofisticate per im-postare la disponibilitagrave per data e per contesto
Il menu Stato ha una voce Avanzate
che porta al pannello per la gestione avanzata della pubblicazione
104 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
16 Collaborazione e flusso di lavoro 105
Documentazione di Plone Release 4
Di seguito una spiegazione dellrsquoimmagine partendo dallrsquoinizio del pannello crsquoegrave una casella che mostra il contenutoche saragrave interessato dalla modifica dello stato di pubblicazione Nel caso mostrato nella figura la cartella ldquoLong-tailedSkipperrdquo saragrave interessata da questo cambiamento
Il campo successivo Includi gli elementi contenuti egrave una casella per controllare se il cambiamento di stato debba avereeffetto solo sullrsquooggetto selezionato (la cartella ldquoLong-tailed Skipperrdquo) o anche sugli elementi contenuti includendo siaeventuali sottocartelle e relativi sottocontenuti sia altri tipi di elementi Questa egrave una casella importante Ti permette dicambiare semplicemente lo stato di unrsquointera sezione del sito internet Per esempio la cartella ldquoLong-tailed Skipperrdquopotrebbe contenere quattro sottocartelle una per le fotografie una per le occorrenze speciali una per la tassonomia euna per delle descrizioni tutte lasciate private durante il lavoro iniziale per la creazione della sezione Tutte possonoessere rese pubbliche ndash possono essere pubblicate ndash selezionando questo controllo e selezionando Pubblica in bassoprima di salvare Analogamente la scelta Sottoponi per pubblicazione puograve essere usata nei siti web dove gli editorirevisionano cosa pubblicare
Allo stesso modo una intera sezione potrebbe essere immediatamente resa privata Per esempio se un agenzia dinoleggio auto ha deciso di rimuovere un modello di auto dalla sua flotta unrsquointera sezione del loro sito web dedicatoa questa vettura con diverse sottocartelle piene di pagine immagini e file potrebbe essere impostata su privato
I successivi due campi data sono per impostare la data di pubblicazione e la data di scadenza Il loro significato egravesemplice Se un elemento o un insieme di elementi devono essere pubblicati per un certo lasso di tempo si possonoimpostare questi campi
Puoi lasciare un commento con la spiegazione legato a tutti i contenuti interessati dal cambiamento di stato Ciograve egraveparticolarmente utile quando piugrave persone lavorano sullo stesso sito web una persona che ha meno familiaritagrave conunrsquoarea del sito web si chiederebbe il motivo per cui certi elementi non sono stati pubblicati Si domanderebberoldquoQuesta informazione sembra buona Percheacute non egrave giagrave stata pubblicatardquo In seguito perograve potrebbero leggere uncommento che dice qualcosa del tipo ldquoNon pubblicare fino a che Richard non abbia fatto dei controlli su possibiliproblemi di copyright per quanto riguarda elementi descritti quirdquo Lrsquouso dei commenti egrave molto utile per annotareinformazioni sensibili anche se si egrave lrsquounica persona che lavora sul sito web in quanto si potrebbe dimenticare ilmotivo di una decisione presa sullo stato di pubblicazione
Infine nella parte finale si puograve scegliere lo stato da applicare tra quelli disponibili per questa azione Varieragrave aseconda dello stato attuale dellrsquoelemento Ad esempio se lrsquoarticolo egrave attualmente nello stato pubblicato non vi saragravela scelta pubblica se si trova nello stato privato non saragrave presente la scelta per renderlo privato ecc Se un elementoegrave giagrave pubblicato in questa parte inferiore del pannello saranno presenti le scelte per revocare e mandare indietro cheldquoannulleranno la pubblicazionerdquo dellrsquoelemento reimpostandolo allo stato bozza o allo stato privato
163 Politiche dei workflow
Le politiche dei workflow consentono ad un amministratore del sito di creare un sistema formalizzato percontrollare la pubblicazione e la gestione dei contenuti come in un flusso che passo a passo coinvolge utentidiversi con ruoli prestabiliti
I workflow sono un argomento avanzato Implicano la creazione di un controllo piugrave rigido nellrsquoaggiunta revisionee pubblicazione di contenuti Se disponi di un account su un tipico sito Plone di piccole dimensioni probabilmentenon utilizzerai le politiche di workflow personalizzate percheacute non crsquoegrave bisogno di questo controllo sofisticato Ma lapotenzialitagrave di questo strumento egrave presente in quanto egrave parte di Plone
Per una introduzione al concetto di workflow considera un esempio che coinvolge il sito web di un quotidiano dovelavorano questi differenti gruppi di persone
Reporters Possono creare articoli ma solo inviarli per essere revisionati
Redattori Possono revisionare articoli ma non possono pubblicarli direttamente Mandano la revisione positiva efanno avanzare il flusso alla successiva approvazione
Editori Fanno il controllo finale le correzioni la revisione e possono pubblicare gli articoli
106 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Una politica di workflow spesso abbreviata in workflow descrive i vincoli che esistono per i diversi gruppi di personedurante i cambiamenti di stato dei contenuti Una volta che la politica di workflow egrave stata creata deve essere applicataad unrsquoarea del sito web in modo tale che le regole abbiano effetto Nellrsquoesempio del sito del quotidiano una politicadi workflow dovragrave essere impostata e applicata alla cartella dove i reporters aggiungono nuovi articoli In seguito ireporters vi potranno creare gli articoli ed inviarli per la revisione e lrsquoapprovazione
I reporter dovrebbe aggiungere articoli e dovrebbero solo sottoporli per la pubblicazione (lrsquoopzione pubblica delmenu non egrave disponibile per loro) Allo stesso modo i redattori possono rifiutare lrsquoarticolo da revisionare o possonoa loro volta sottoporre lrsquoarticolo agli editori per la correzione finale e la pubblicazione Nellrsquoesempio del sito webdel quotidiano questa politica potrebbe essere chiamata ldquoPolitica di revisione editorialerdquo Nella configurazione di unapolitica di workflow egrave fondamentale assegnare la stessa ad unrsquoarea del sito web ndash per definire il campo di applicazionedel workflow Questo egrave compito dellrsquoamministratore del sito Lrsquoamministratore deve usare il pannello di controllo diPlone per specificare dove la ldquoPolitica di revisione editorialerdquo si applica se a livello globale o in una sottosezione
Plone egrave dotato di diverse politiche di workflow utili - quella di default egrave un semplice politica di pubblicazione webIl tuo amministratore del sito potrebbe impiegare una politica piugrave specifica ad esempio configurata per una comunitagraveweb o configurata per una Intranet aziendale (sistema web interno) In tal caso potrebbe essere necessario impararealcuni passi procedurali per la pubblicazione ma queste sono solo varianti della politica base di default
164 Collaborazione attraverso la condivisione
La scheda Condivisione consente di collaborare con altri utenti attraverso lrsquouso di diversi ruoli integrati
Esempio 1 Consentire ad altri di aggiungere contenuti in una cartella che hai creato
In questo esempio Jane Smythe ha pieno accesso al suo sito Plone Lei egrave in grado di aggiungere modificare cancellaree pubblicare contenuti in qualsiasi parte del sito Per ora ha creato una cartella denominata ldquoDocumentazionerdquo e viha aggiunto una pagina ldquoPresentazione Progettordquo Non ha pubblicato neacute la cartella neacute il documento Il workflow didefault per questo sito Plone non egrave stato modificato Ora vuole dare il permesso al suo collega George Shrubb diaggiungere contenuti alla cartella Documentazione Lui ha il permesso di modificare qualsiasi contenuto esistente malei ha bisogno che lui inizi ad aggiungere contenuti Prima di proseguire insieme a Jane diamo uno sguardo a quelloche George vede quando si autentica in questo sito Plone
Nota che in questo momento George non puograve nemmeno vedere la cartella Documentazione percheacute quando Jane lrsquohacreata lrsquoha lasciata nello stato Privato Tutte le autorizzazioni predefinite sono attualmente in atto e funzionano comeprevisto
Jane conferisce a George le autorizzazioni necessarie per aggiungere contenuti alla cartella Documentazione
Jane passa alla cartella Documentazione e fa clic sul tab Condivisione
Una delle prime cose da notare egrave che Jane ha giagrave tutte le autorizzazioni disponibili per questa cartella Queste autoriz-zazioni erano in realtagrave state concesse in una sezione superiore del sito come indicato dal simbolo di spunta verde
16 Collaborazione e flusso di lavoro 107
Documentazione di Plone Release 4
108 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Dando unrsquoocchiata piugrave da vicino le autorizzazioni disponibili sono
bull Puograve aggiungere - Questo significa che quando questa autorizzazione viene concessa ad un particolare utente (ogruppo di utenti) egli puograve aggiungere nuovi contenuti Dal momento che lrsquoutente egrave stato anche il creatore diquel contenuto saragrave in grado di modificarlo a suo piacimento
bull Puograve modificare - Quando questa autorizzazione viene concessa per una cartella lrsquoutente puograve non solo mod-ificare la Cartella (il titolo e la descrizione) ma puograve anche modificare uno qualsiasi degli elementi contenutiNota tuttavia che lrsquoutente non egrave autorizzato ad eliminare il contenuto Se questa autorizzazione viene concessasu una pagina per esempio lrsquoutente puograve modificare solo quella pagina e nessuno degli altri elementi presentinella cartella
bull Puograve vedere - Quando questa autorizzazione viene utilizzata su una cartella o un altro elemento lrsquoutente puogravevisualizzare il contenuto ma non apportare modifiche
bull Possono revisionare - Quando questa autorizzazione viene concessa lrsquoutente puograve pubblicare i contenuti
Nota queste autorizzazioni sovrascrivono i permessi definiti nel workflow Ad esempio se si concede ad un utentelrsquoautorizzazione ldquoPuograve vedererdquo in una pagina che egrave nello stato privato lrsquoutente potragrave vederla
In questo esempio Jane concede a George lrsquoautorizzazione ldquoPuograve aggiungererdquo nella Cartella ldquoDocumentazionerdquo inmodo che possa aggiungere contenuti in essa Per fare questo come primo passo lo cerca utilizzando il suo nome
Jane ora puograve aggiungere le autorizzazioni necessarie a George per la cartella ldquoDocumentazionerdquo Deve selezionare ilpermesso ldquoPuograve aggiungererdquo e premere ldquoSalvardquo
Questo egrave tutto ciograve che deve fare Vediamo come George vede il sito ora
Nota George NON ha bisogno di disconnettersi e riconnettersi Le autorizzazioni sono sempre aggiornate percheacutesono controllate ogni volta che un utente accede a qualsiasi cosa (ad esempio cliccando su un link) su un sito Plone
George clicca sulla scheda Home (per esempio) per aggiornare la sua visione del sito e visualizzeragrave la cartella ldquoDocu-mentazionerdquo
16 Collaborazione e flusso di lavoro 109
Documentazione di Plone Release 4
110 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Quando George fa click sulla scheda ldquoDocumentazionerdquo si accorge che puograve visualizzare tutto il contenuto e che egrave orain grado di aggiungere i tipi di contenuto disponibili nela cartella come mostrato nel menu Aggiungi
George vuole visionare ciograve che Jane ha giagrave creato quindi seleziona il link Project Overview e vede
Anche se George puograve visualizzare il documento le sue autorizzazioni limitate non gli consentono di modificarlo o dicambiare il suo stato Lrsquounica cosa che puograve fare al di lagrave di visualizzare il documento egrave di farne una sua copia
George aggiunge una pagina intitolata ldquoWidget Installationrdquo e ne crea il contenuto Quando ha terminato la salva
Jane vede il lavoro fatto da George Seleziona la scheda ldquoDocumentazionerdquo e vede che George si egrave dato da fare Clicca
16 Collaborazione e flusso di lavoro 111
Documentazione di Plone Release 4
sulla pagina ldquoWidget Installationrdquo per dare unrsquoocchiata piugrave da vicino
Si noti che Jane ha pieno accesso alla pagina che ha creato George Lei puograve modificarla cosigrave cometagliarlacopiarlaincollarla In realtagrave lei attenderagrave che George invii la pagina per la revisione prima di modificarlaeventualmente
Esempio 2 Permettere ad altri di modificare contenuti creati da te
Sia Jane sia George hanno lavorato duramente per creare le pagine della cartella Documentazione Jane ha pubblicatola cartella e diverse pagine
Jane ha deciso che vuole consegnare a George i permessi di modifica (ma non di pubblicazione) per tutti gli elementicartella ldquoDocumentazionerdquo Per fare questo Jane deve tornare nella cartella ldquoDocumentazionerdquo e cliccare sulla schedaCondivisione
Da qui deve solo selezionare la casella di controllo ldquoPuograve modificarerdquo e George saragrave in grado di modificare tutto ilcontenuto nella cartella ldquoDocumentazionerdquo ndash compresa la cartella ldquoDocumentazionerdquo stessa Quando successivamenteGeorge visiteragrave la cartella e cliccheragrave su ldquoPresentazione del progettordquo (che egrave una pagina che Jane ha creato) questo egravequello che vedragrave
Ora George puograve modificare qualsiasi elemento nella cartella ldquoDocumentazionerdquo indipendentemente da chi lo ha creatoo da quando egrave stato creato
Nel frattempo Molly si egrave unita a George come nuovo membro del team Molly aiuteragrave George nellrsquoaggiornamentodel documento ldquoWidget Installationrdquo George va nella scheda condivisione dellrsquoelemento ldquoWidget Installationrdquo cercail nome completo di Molly (non il nome utente) e seleziona ldquoPuograve modificarerdquo per darle lrsquoautorizzazione su questodocumento
Quando Molly entreragrave nella cartella ldquoDocumentazionerdquo potragrave vedere i due articoli pubblicati e lrsquoelemento privato cheora egrave autorizzata a modificare
112 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
16 Collaborazione e flusso di lavoro 113
Documentazione di Plone Release 4
114 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
E infatti quando faragrave un click sul documento ldquoWidget Installationrdquo saragrave in grado di modificarlo
Si noti tuttavia che quando Molly selezioneragrave uno dei due elementi dove non ha il permesso di modifica non avragravealcun ulteriore accesso Puograve visualizzare questi due elementi percheacute sono pubblicati come definito nel workflow didefault di Plone (il chegrave significa che chiunque puograve vederli)
Una nota finale su questo esempio se la cartella ldquoDocumentazionerdquo non fosse stata nello stato di pubblicazione OMolly non avesse avuto delle autorizzazioni particolari (per esempio ldquoPuograve visualizzarerdquo nella cartella Documen-tazione) Molly avrebbe avuto bisogno dellrsquoURL completo per raggiungere il documento a cui le era stato datolrsquoaccesso per la modifica Le autorizzazioni sono molto specifiche in Plone
17 Utilizzo delle collezioni
Le collezioni sfruttano lrsquointelligenza di Plone
171 Introduzione alle Collezioni
Una Collezione in Plone funziona come un report o una query fatta in un database Utilizza le Collezioni perordinare e visualizzare in modo dinamico il tuo contenuto
Una Collezione in Plone funziona come un report o una query fatta in un database Lrsquoidea egrave di utilizzare una collezioneper cercare nel tuo sito web in base ad un insieme di Criteri quali il tipo di contenuto (pagina notizia immagine) ladata di pubblicazione o parole chiave contenute nel titolo nella descrizione o nel corpo
17 Utilizzo delle collezioni 115
Documentazione di Plone Release 4
116 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Diciamo che sul tuo sito web hai un ampio catalogo di foto e mappe Si possono facilmente visualizzare tutte in unasola volta creando un collegamento ipertestuale alla cartella dove sono archiviate Potresti persino creare collegamentidifferenti per differento sotto-cartelle se hai organizzato le cose in questo modo Tuttavia se le immagini e le mappefossero inserite in piugrave cartelle sparse nel sito questa operazione potrebbe diventare macchinosa Inoltre non crsquoegrave modocon le cartelle normali di visualizzare contenuti diversi provenienti da diverse parti del tuo sito basandosi su critericome
bull parole chiave nel titolo
bull data di creazione
bull autore
bull tipo di contenuto
La necessitagrave di visualizzazione i contenuti in una varietagrave di modi dinamici viene soddisfatta dalle Collezioni (prece-dentemente note come Smart Folders o Rich Topic nelle versioni piugrave vecchie di Plone) Le Collezioni di fatto noncontengono elementi come accade in una cartella Al contrario sono i Criteri stabiliti che determinano quali contenutifar apparire nella pagina dove egrave definita la Collezione
I casi piugrave comuni nei quali viene utilizzata una Collezione sono
bull Archivio di Notizie
bull Archivio di Eventi
bull Visualizzazione di Foto dato un intervallo di date
bull Visualizzazione di contenuti data una parola chiave
17 Utilizzo delle collezioni 117
Documentazione di Plone Release 4
118 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
172 Aggiungere Collezioni
Le Collezioni (una volta chiamate Smart Folders) sono contenitori virtuali con liste di elementi trovati utiliz-zando ricerche specifiche
Comprendere che i contenuti possono essere memorizzati ovunque in un sito Plone ma possono essere recuperati concollezioni personalizzate che creano ldquovisterdquo sui contenuti stessi egrave un passo importante per poter utilizzare Plone inmodo efficace Ersquo un sistema intelligente
Per aggiungere una collezione utilizza il menu ldquoAggiungirdquo nello stesso modo in cui aggiungi altri tipi di contenuto
Ti compariragrave il riquadro per aggiungere una Collezione
Sotto i campi titolo e descrizione ci sono un insieme di campi per specificare il formato dei risultati restituiti dal criteriodi ricerca della nuova collezione I quattro campi nel riquadro sopra sono a coppie I primi due in alto consentono dilimitare i risultati della ricerca a un certo numero di elementi Gli ultimi due consentono di controllare lrsquoordinamentodei risultati
Impostare il criterio di ricerca
Dopo aver impostato le configurazioni di visualizzazione nel riquadro di modifica sopra indicato fai click sulla schedacriteri per visualizzare il pannello per impostare i criteri di ricerca
Lrsquoarea superiore del pannello Aggiungi nuovo Criterio consente di impostare un campo e un criterio di corrispon-denza Lrsquoarea inferiore Ordinamento permette semplicemente di selezionare un campo per lrsquoordinamento
I tipi di criteri per la ricerca dipendono da quale campo viene selezionato
Dopo aver salvato la collezione i criteri di ricerca saranno applicati ed il risultato mostrato quando la collezione vieneselezionata Egrave possibile creare un numero qualsiasi di collezioni per ogni visualizzazione che si vuole personalizzare
17 Utilizzo delle collezioni 119
Documentazione di Plone Release 4
120 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
17 Utilizzo delle collezioni 121
Documentazione di Plone Release 4
122 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Per lrsquoesempio delle farfalle sopra descritto oltre ad un vincolo sulla data per trovare gli elementi recenti il campocategorie potrebbe essere utilizzato per abbinare il colore alle farfalle e ottenere una serie di collezioni di ldquoFarfalleblurdquo ldquoFarfalle Biancherdquo ecc
Criteri multipli possono essere utilizzati nella stessa collezione Per esempio una collezione chiamata ldquoFarfalle fo-tografate nel mese scorsordquo potrebbe essere creata impostando un criterio relativo alla data di creazione ed uno relativoal tipo di elemento che dovragrave essere unrsquoimmagine Le collezioni con criteri basati sulle date sono veramente efficaciper mostrare viste di contenuti sempre aggiornate che non richiedono alcun lavoro da parte dellrsquoamministratore delsito - una volta che la collezione egrave stata creata essa mostreragrave automaticamente i contenuti piugrave recenti
Nota Una collezione non si comporta come una normale cartella non puoi aggiungere elementi tramite la voce delmenu aggiungi come egrave possibile fare in una normale cartella
173 Regolazione delle Impostazioni di Visualizzazione
Scopri come le impostazioni di visualizzazione possono modificare lrsquoaspetto della pagina Collezione
Mentre il punto di forza delle Collezioni sta nei Criteri le impostazioni di visualizzazione possono fare una grandedifferenza nel modo in cui la vostra Collezione saragrave mostrata Tutte e tre le impostazioni che tratteremo in questasezione possono essere trovate facendo click sulla scheda Modifica di una Collezione
Eredita Criteri
Selezionando lrsquoopzione Eredita Criteri la Collezione erediteragrave i Criteri da una Collezione padre Questo egrave utile soloquando si utilizzano Collezioni Subordinate Se questa opzione egrave selezionata egrave possibile creare unrsquoaltra Collezioneche egrave piugrave specifica rispetto alla Collezione Padre pur mantenendo i Criteri di base della Collezione Padre Un sempliceesempio potrebbe essere una Collezione Padre per la visualizzazione di tutti gli Eventi in un sito e una CollezioneSubordinata che visualizza Eventi (ereditando i Criteri) ma solo gli Eventi con una particolare parola chiave
Limita i Risultati della Ricerca
Possiamo usare Limita i Risultati della Ricerca per limitare il numero di risultati che verranno visualizzati per paginaIn questo modo se abbiamo una Collezione che sta mostrando Notizie siamo in grado di limitare i risultati a cinque odieci invece di mostrare tutte le Notizie in un singolo elenco di grandi dimensioni
Visualizza come Tabella
Visualizza come Tabella egrave semplicemente un altro modo per visualizzare i risultati di una Collezione Invece diavere una Collezione che mostra i risultati in una lista possiamo generare una tabella con i risultati e impostareesattamente le informazioni che desideriamo visualizzare nel risultato Si puograve personalizzare la tabella selezionandole Colonne della Tabella nellrsquoelenco a sinistra e facendo clic sul pulsante freccia destra per spostarle nellrsquoelencoa destra Nellrsquoesempio precedente abbiamo scelto di includere il Titolo dellrsquooggetto i suoi Creatori e la Data diAccessibilitagrave Egrave possibile utilizzare qualsiasi numero di colonne o tutte se lo si vuole
Quando si considera cosa scegliere bisogna tenere presente che non tutti gli oggetti disporranno delle informazioniper ogni colonna disponibile Per esempio la Data di Inizio e la Data di Fine valgono solo per gli Eventi Pertantose si aggiungono queste colonne e la tabella include Pagine oltre agli Eventi allora le righe per le pagine non avrebberole date di inizio e di fine popolate Lrsquoaltra cosa da considerare egrave che piugrave colonne stai mostrando piugrave affollata diventeragravela tabella La migliore regola egrave quella di visualizzare solo ciograve che egrave assolutamente necessario
Alcune note ulteriori sulla selezione delle colonne egrave possibile selezionarne piugrave di una alla volta tenendo premutoil tasto (Ctrl) mentre si fa click Se si desidera rimuovere una colonna selezionarla a destra e fare clic sul pulsantefreccia sinistra Inoltre egrave possibile aggiungere e rimuovere le colonne con un doppio click sul loro nome
174 Definizione dei Criteri
Definizioni ed esempi dei vari campi criteri disponibili
17 Utilizzo delle collezioni 123
Documentazione di Plone Release 4
Il potere delle Collezioni dipende certamente dai criteri che si possono impostare per esse Imparare come utilizzare idiversi Criteri vi permetteragrave di creare Collezioni molto utili In questa sezione useremo esempi per illustrare i moltimodi di utilizzare i Criteri
Categorie
Il criterio Categoria consente di ricercare il campo Categoria degli oggetti Perchegrave funzioni egrave necessario aver specifi-cato prima le Categorie per i contenuti (questo egrave fatto tramite la scheda Categorizzazione sugli oggetti contenuto) Unesempio di come sia possibile utilizzare questo campo egrave creare una Collezione che riporti tutti gli oggetti relativi allaCategoria Organizzazione Siamo in grado di selezionare il valore Organizzazione per il nostro criterio Quindi sal-vando questo criterio e visualizzando la nostra Collezione i risultati saranno tutti gli oggetti di contenuto che avevamomarcato con la Categoria Organizzazione
Ancora una volta i valori disponibili sono completamente dipendenti da ciograve che abbiamo specificato sui nostri oggettinella scheda Categorizzazione
Creatore
Quando utilizziamo il criterio Creatore stiamo creando un filtro sugli oggetti basato su chi li ha creati Ciograve potrebbeessere utile se si vuole creare una sezione autore in cui si desidera visualizzare solo i contenuti sul tuo sito che sonostati creati da un certo autore
Abbiamo diverse opzioni per questo tipo di criterio Essi ci permettono di limitare il creatore alla persona attualmenteconnessa immettere manualmente il nome di un altro utente oppure selezionare gli utenti da un elenco
Se si vogliono visualizzare i risultati di piugrave utenti egrave necessario utilizzare lrsquoopzione Elenco dei Valori In caso con-trario si usa normalmente lrsquoopzione Testo a meno che il creatore che si vuole selezionare non siate voi stesso nelqual caso si utilizza lrsquoopzione Limita a Utente Attuale
Descrizione
Il campo Descrizione egrave essenzialmente un criterio che funziona come le ricerche testuali sul sito fatte con un campodi tipo search box dove immettere i termini da cercare Tuttavia invece di cercare nel titolo e nel corpo di una paginala collezione effettueragrave una ricerca solo per il testo nel campo Descrizione di un contenuto Questo criterio egraverealmente utile solo se si compila il campo Descrizione in modo coerente per tutti i tipi di contenuto
Posizione
Utilizzare il criterio Posizione egrave molto simile a specificare una posizione nella ricerca di un documento sul disco rigidodel tuo PC Specificando un criterio Posizione i risultati che vengono visualizzati nella tua Collezione provengonosolo da quella posizione tipicamente una Cartella Ciograve puograve essere utile se si desidera visualizzare solo il contenutoche si trova nella sezione Chi siamo del sito per esempio Il criterio Posizione egrave anche utile per restringere risultatidelle Collezioni quando egrave combinato con altri criteri
Per specificare una Posizione egrave sufficiente fare click sul pulsante Aggiungi si apre quindi una nuova finestra chemostra una directory del tuo sito Se seguiamo il nostro esempio e vogliamo cercare la sezione Chi siamo del nostrosito dobbiamo fare click sul pulsante Inserisci accanto alla cartella Chi siamo
Egrave possibile aprire le cartelle per visualizzare i contenuti in essi presenti sia facendo clic sul pulsante Sfoglia siafacendo click direttamente sul titolo della cartella che si desidera aprire Egrave inoltre possibile utilizzare la casella diricerca per cercare il Titolo di un oggetto
124 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Testo Ricercabile
Il Testo Ricercabile egrave un criterio molto utile Egrave simile al box di ricerca sul tuo sito o un motore di ricerca InternetPrende il testo che hai indicato cerca il Titolo la Descrizione e il Corpo di tutti gli oggetti e restituisce quelli chehanno la parola o la frase specificata Ciograve egrave utile quando si desidera trovare oggetti che hanno a che fare con unacerta cosa soprattutto se la parola o la frase appare in molti tipi di contenuto Utilizzando LearnPloneOrg comeesempio se voglio creare una Collezione che consente di visualizzare tutti gli oggetti che fanno riferimento alla parolaCollezioni lo devo fare utilizzando il criterio Testo Ricercabile specificando collezioni come valore del criterio Tuttii Tutorial Video voci di Glossario ecc con Collezioni nel Titolo nella Descrizione o nel Corpo del Testo dovrebberoquindi comparire come risultati delle Collezione
Contenuti Correlati
Il campo Contenuti Correlati egrave un altro campo come Categoria che deve essere specificato su un oggetto contenutoprima di essere utilizzato per una Collezione Il campo Contenuti Correlati su un oggetto consente di specificarequali altri oggetti nel tuo sito sono simili o sono rilevanti per lrsquooggetto creato Specificando questo campo quando sicrea un oggetto egrave possibile creare una rete di contenuti correlati che faranno riferimento a vicenda (si pensi a un tipo difunzione ldquovedi ancherdquo) Una volta fatto questo egrave possibile utilizzare il criterio Contenuti Correlati in una Collezioneper visualizzare tutto ciograve che egrave collegato a un specifico oggetto
Ad esempio se abbiamo creato contenuti che hanno come Contenuti correlati le pagine Nostro Staff Storia e la Home-page Chi siamo possiamo selezionare questi valori per il criterio della Collezione e la nostra collezione visualizzeragravetutti i contenuti che hanno quei valori come contenuti correlati
Se avessimo scelto la pagina Storia come valore dellrsquoopzione del criterio Contenuti correlati la nostra Collezionemostrerebbe tutto ciograve che egrave legato alla pagina Storia
Tenete a mente che se ad esempio scelgo la pagina Storia come valore dellrsquoopzione del criterio Contenuti correlati lacollezione non tireragrave fuori tutti i contenuti impostati come Contenuti Correlati della pagina Storia ma tutti i contenutiche hanno la Pagina Storia come Contenuto correlato
Stato
Utilizzare il criterio Stato egrave molto semplice Ci permette di fare una selezione in base allo stato pubblicato o pri-vato Egrave una buona idea limitare le Collezioni agli elementi visibili pubblicamente impostando il filtro sullo statopubblicato in modo che i contenuti privati non appaiano nei risultati della Collezione Puograve essere utile anche im-postare il filtro sullo stato Privato Per esempio un amministratore del sito potrebbe desiderare di vedere rapidamentei contenuti privati in modo da poter determinare quale lavoro deve essere ancora fatto e che cosa potrebbe esserecancellato
Date
Avrete notato che sono disponibili parecchie date da utilizzare come Criteri Poicheacute ci sono un grande numero didate esse avranno una propria sezione nel manuale
175 Impostazione del criterio di Ordinamento
Scopri come utilizzare la funzione di Ordinamento per personalizzare lrsquoordine in cui i risultati vengono visual-izzati
LrsquoOrdinamento determina lrsquoordine dei risultati della Collezione LrsquoOrdinamento consente di ordinare su tre princi-pali categorie testo proprietagrave degli oggetti e date Quando si ordina in base al testo gli oggetti saranno ordinati inordine alfabetico Quando si ordina in base alle proprietagrave degli oggetti stiamo effettivamente raggruppando gli oggetti
17 Utilizzo delle collezioni 125
Documentazione di Plone Release 4
attraverso le proprietagrave specificate Quando si ordina per data i risultati saranno visualizzati con la data piugrave recente perprima (anche se ci sono molte lsquodatersquo in Plone) Tutti gli Ordinamenti sono in Ordine Crescente a meno che il checkboxOrdine Inverso sia selezionato Selezionandolo egrave possibile visualizzare in ordine inverso o visualizzare prima le datepiugrave recenti ecc
Date
Ci sono numerose opzioni Data che saranno descritte nella prossima sezione del manuale
Proprietagrave degli oggetti
Tipo
Quando si ordina per Tipo si ottiene una Collezione che presenta i risultati raggruppati per Tipo Possiamo utilizzarequesto Ordinamento se abbiamo una Collezione che deve restituire molti Tipi diversi di elementi In questo modopossiamo rendere la Collezione molto facile da navigare per il visitatore del sito
Stato
LrsquoOrdinamento per Stato visualizzeragrave i risultati raggruppandoli per lo stato di pubblicazione Dal momento che ci sonosolo due Stati nella configurazione di default di Plone ci saranno solo le voci Pubblicato e Privato Possiamo usarequesto Ordinamento per separare tutte le pagine del nostro sito e vedere facilmente quello che egrave pubblico (Pubblicato)e ciograve che si nasconde agli occhi del pubblico (Privato)
Categoria
LrsquoOrdinamento Categoria egrave utile quando si desidera visualizzare gli oggetti del nostro sito raggruppati in base alla Cat-egoria nella quale li abbiamo posti Tenete a mente che egrave necessario aver specificato la Categoria sulla maggior partedegli oggetti percheacute lrsquoordinamento per Categoria sia utile Se non avete specificato alcuna Categoria lrsquoordinamentoper categorie non faragrave nulla
Correlato con
LrsquoOrdinamento Correlato applica di fatto un criterio alla tua Collezione Esso infatti limita i risultati unicamente aicontenuti quelli che hanno lrsquoinformazione Correlato con specificata nelle loro proprietagrave
Testo
Nome breve
LrsquoOrdinamento per il Nome Breve restituisce i risultati in ordine alfabetico Di default Plone imposta il Titolo comeNome Breve di un oggetto La differenza tra i due egrave che il Nome breve egrave tutto in minuscolo e ha trattini tra tutte leparole Per esempio il Nome breve per la pagina dal titolo Chi siamo egrave chi-siamo Il Nome breve egrave quello che Ploneutilizza anche nellrsquoURL della pagina (wwwmyplonesiteorgchi-siamo) Egrave possibile specificare un diverso NomeBreve per un oggetto utilizzando il pulsante Rinomina nella scheda Contenuti
Creatore
LrsquoOrdinamento Creatore raggrupperagrave tutti i risultati in ordine alfabetico sul loro autore Per esempio diciamo cheabbiamo diversi documenti pubblicati da Bob Baker e molti altri documenti pubblicati da Jane Smith LrsquoOrdinamentoCreatore si tradurrebbe in tutti i documenti creati da Bob Baker elencati per primi seguiti da quelli di Jane Smith
Titolo
LrsquoOrdinamento per Titolo visualizzeragrave i risultati in ordine alfabetico sui Titoli
Nella prossima sezione tratteremo le date che abbiamo saltato in questa sezione e in quella sui Criteri
126 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
176 Uso e comprensione delle Date
Spiegazione delle Date associate alle Collezioni ed il loro uso
Ci sono diversi tipi di date che possiamo scegliere molti di essi sembrano simili Per questo motivo egrave molto facileconfondersi su quale data utilizzare Di seguito egrave definita ogni opzione data
Definizione delle Date
Data di Creazione
La Data di Creazione egrave la data in cui egrave stato fatto il documento Si puograve pensare questa data come il suo compleannoil giorno in cui egrave nato Non egrave possibile modificare la Data di Creazione di un oggetto
Data di Accessibilitagrave
La Data di Accessibilitagrave egrave la data in cui un oggetto viene pubblicato Questo data egrave personalizzabile attraverso il tabModifica presente sul tab Data di un contenuto Tuttavia in quella scheda essa egrave indicata come Data di Pubblicazione(un discrepanza nella nomenclatura di Plone)
La Data di Creazione e la Data di Accessibilitagrave sono molto simili Entrambe rappresentano il punto di inizio di unoggetto Un importante punto da tenere a mente quando si sceglie la data da utilizzare egrave che un oggetto puograve esserecreato molto prima che diventi pubblico Una pagina potrebbe venire modificata per diverse settimane prima che siaeffettivamente pubblicata Quindi si dovrebbero avere risultati diversi in un Collezione a seconda di quale data egrave statoutilizzata Si consiglia di utilizzare la Data di Accessibilitagrave invece della Data di Creazione per Collezioni basatesulle date In questo modo la tua Collezione mostra i risultati sulla base di quando sono diventati visibili il che egrave piugraverilevante per il pubblico della tua collezione Inoltre egrave possibile modificare la Data di Accessibilitagrave per controllarelrsquoordinamento cosa che non si puograve fare con la Data di Creazione
Data di Scadenza
La Data di Scadenza si riferisce al giorno in cui il contenuto non saragrave piugrave pubblico Questa data egrave anche personal-izzabile attraverso il tab Modifica (indicata sopra) come la Data di Accessibilitagrave Per impostazione predefinita glioggetti non hanno la Data di Scadenza
Data di Modifica
La Data di Modifica egrave la data dellrsquoultima modifica fatta sullrsquooggetto Notare che questa data egrave inizialmente impostataal giorno in cui lrsquooggetto viene creato e saragrave cambiata automaticamente ogni volta che lrsquooggetto viene modificato Nonvi egrave alcun modo per personalizzarla Per esempio egrave possibile utilizzare questa data come Ordinamento insieme adun criterio Tipo impostato su Pagina per visualizzare tutte le pagine modificate di recente entro la settimana scorsaLrsquoelenco Whatrsquos New sulla homepage di LearnPloneOrg usa la Data di Modifica come criterio data In questo modoi documenti appena creati e quelli che sono stati aggiornati appaiono nellrsquoelenco
Date specifiche degli Eventi
Le due seguenti date si applicano solo agli oggetti Eventi Queste due date sono molto efficaci per la creazione diCollezioni Eventi Recenti e Prossimi Eventi che permetteragrave al tuo pubblico di conoscere ciograve che la tua organizzazionesta facendo e faragrave in futuro
Data di Inizio
La Data di Inizio egrave semplicemente la data da cui parte un evento
Data di Fine
La Data di Fine egrave semplicemente la data in cui lrsquoevento si conclude
Data di Pubblicazione
17 Utilizzo delle collezioni 127
Documentazione di Plone Release 4
La Data di Pubblicazione egrave la data in cui un oggetto egrave stato pubblicato lrsquoultima volta Puograve essere impostata manual-mente per mezzo del campo Data di Accessibilitagrave o se questrsquoultima non egrave stato impostata puograve essere calcolata in basealla data in cui oggetto egrave stato pubblicato lrsquoultima volta
Per visualizzare la Data di Pubblicazione sulle proprie pagine egrave necessario attivare lrsquoopzione ldquoVisualizza la data dipubblicazione nelle informazioni personalirdquo nel Pannello di Configurazione del Sito La Data di Pubblicazionesaragrave mostrata prima della Data di Modifica dellrsquooggetto allrsquointerno dellrsquoarea informazioni personali Per essere sicuriche tutto funzioni attivare anche lrsquoopzione ldquoConsenti a chiunque di vedere le informazioni personalirdquo allrsquointerno delPannello di Impostazioni sicurezza
Impostazione Date
Una cosa che puograve causare confusione sulle date egrave come impostare i loro Criteri Essi hanno una configurazione chenon egrave come quella degli altri Prima di tutto devi scegliere se desideri una Data Relativa o un Intervallo di Date
La Data Relativa permette di costruire unrsquoistruzione condizionale Come ad esempio gli articoli modificati da menodi 5 giorni nel passato LrsquoIntervallo di Date consente di specificare un determinato range di date ad esempiodal 010208 al 020208 LrsquoIntervallo di Date egrave utile quando si desidera creare una Collezione con una data staticache non cambieragrave La Data Relativa puograve essere molto utile in quanto vi permetteragrave di creare Collezioni che sonoautomaticamente auto-aggiornate come una Collezione News Recenti o una Sezione Prossimo Evento
Data Relativa
Osservando per prima lrsquoopzione Data Relativa si nota che abbiamo tre opzioni da compilare
La prima opzione egrave Quale giorno Questo ci permette di selezionare il numero di giorni che il nostro criterio com-prenderagrave Una delle opzioni egrave chiamata Adesso Lrsquoutilizzo di questa opzione imposteragrave lrsquointervallo di date al giornocorrente Le altre due opzioni non hanno importanza e possono essere ignorate quando si utilizza Adesso
La seconda opzione egrave Nel passato o nel futuro Questo ci permette di scegliere se stiamo cercando in avanti o indietronel tempo
Lrsquoultima opzione egrave Prima o dopo Qui si puograve scegliere tra tre opzioni Minore di ci permette di includere tuttoda ora a un periodo di tempo pari o inferiore allrsquoimpostazione Quale giorno sia in passato che nel futuro Mag-giore di includeragrave tutto ciograve oltre il nostro numero di giorni specificato pari o superiore di Quale giorno Infine InGiornata comprenderagrave solo gli oggetti del giorno che abbiamo specificato in Quale giorno Utilizzando lrsquoesempionellrsquoimmagine qui sopra se avessimo selezionato In Giornata invece di Minore di la nostra Collezione mostrerebbesolo gli oggetti che sono stati modificati 5 giorni fa (stiamo usando il criterio Data di Modifica)
Se questo per te egrave fonte di confusione prova a leggerlo come una frase sostituendo nei campo le opzioni che hai sceltoldquoVoglio i risultati per includere oggetti Prima o dopo di Quale giorno Nel passato o nel Futuro Il nostro esempiodiventerebbe ldquoVoglio i risultati che includono gli oggetti Minore di 5 giorni nel passatordquo
Intervallo di Date
LrsquoIntervallo di Date egrave molto piugrave facile da capire Sono obbligatori sia una Data di Inizio che una Data di Fine (nonconfondere questi termini con le date specifiche dellrsquoEvento) LrsquoIntervallo di Date ci permette di inserire un inizioe una fine e viene mostrato tutto ciograve che egrave entro la suddetta finestra Si noti anche che ci permette di specificare unadeterminata ora del giorno
18 Gestione delle Portlet
Una introduzione allrsquouso e alla gestione delle portlets
128 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
181 Gerarchia delle Portlet
Le Portlet utilizzano un approccio gerarchico che determina come e se devono apparire in ogni sezione del sito
Le Portlet utilizzano un approccio basato sulla gerarchia Per impostazione predefinita le portlet che assegni allaradice (home page) del sito si propagano verso tutte le sottosezioni dello stesso Se desideri un diverso insieme diportlet o un ordinamento differente per una particolare sotto-sezione dovrai utilizzare il controllo Bloccasbloccaportlets per ldquobloccarerdquo le portlet ereditate dalla pagina superiore Quando blocchi le Portlet egrave necessario aggiungereesplicitamente tutte quelle che desideri vedere sulla pagina figlia
La schermata di gestione delle portlet egrave stata aggiornata in Plone 4 per mostrare tutte le portlet incluse quelle bloccateGli utenti ora possono vedere ciograve che egrave stato bloccato e ciograve che egrave stato ereditato Quando una portlet egrave bloccata sinoteragrave un sottile cambiamento di colore nella schermata di gestione portlet
In questo schema le nostre Portlets sono rappresentate in blu sotto il titolo della Pagina
Come puoi vedere abbiamo due Portlet nella nostra pagina iniziale (navigation and recent items) Entrambe appari-ranno nella pagina About a causa della gerarchia delle portlet
18 Gestione delle Portlet 129
Documentazione di Plone Release 4
Tuttavia nella pagina Documentation abbiamo aggiunto una terza portlet - la Collection Portlet Qui stiamo ancorapermettendo la visualizzazione delle Portlet della pagina genitore ma in piugrave abbiamo espressamente aggiunto la Col-lection Portlet
Su entrambe le pagine Tutorials e Videos dobbiamo bloccato le portlet ereditate dai genitori percheacute non vogliamo chela Collection Portlet che si trova nella pagina Documentation venga mostrata Quando blocchiamo le Portlet ereditatedai Genitori dobbiamo ri-aggiungere le portlet a ogni pagina figlia In questo caso ri-aggiungiamo la NavigationPortlet ad entrambi e successivamente la Search Portlet a tutti e due
Ricorda che le pagine figlie ereditano solo dalla loro pagina padre superiore Nel nostro esempio se aggiungessimouna pagina chiamata Staff sotto About senza altre portlet se non quelle ereditate dal genitore essa mostrerebbe lestesse portlet mostrate sia nella Home Page che nella pagina About Tuttavia le sue portlet non sarebbero ereditatedalla Home page ma dalla pagina About Se dovessimo cambiare la pagina About e aggiungere una Search Portlet lanostra Pagina Staff rispecchierebbe le portlet nella pagina About e non piugrave quelle nella Home Page
182 Gestione delle Portlets
Come aggiungere rimuovere e riordinare le portlets
Per iniziare a manipolare le portlet egrave necessario trovare il link Gestione Portlet solitamente posizionato nella parteinferiore di ogni colonna laterale In Gestione Portlet egrave possibile crearne di nuove rimuoverle rinominarle e riordi-narle
Cliccando su questo link verremo portati ad una nuova pagina che ci permetteragrave di modificare le portlet Lrsquoaltro metodoper arrivare a questa schermata egrave quello di aggiungendo manage-portlets alla fine dellrsquoURL della pagina dovesi vuole modificare le portlet Ad esempio per modificare le portlet della pagina About Us lrsquoURL deve diventarewwwmyplonesiteorgaboutmanage-portlets
130 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Aggiungere una Portlet
Per aggiungere una Portlet basta semplicemente selezionare Aggiungi Portlet dalla casella a discesa e cliccare sultipo che si desidera aggiungere Le diverse opzioni disponibili saranno spiegate nella sezione successiva
Modificare una Portlet Esistente
Per modificare le proprietagrave di una Portlet esistente egrave sufficiente fare click sul suo nome Nellrsquoesempio a sinistra sevolessimo modificare le proprietagrave della portlet di navigazione si dovrebbe Cliccare su Navigazione Ogni tipo diportlet avragrave diverse opzioni di configurazione disponibili
Riodinare le Portlet
Per modificare lrsquoordine delle Portlet egrave sufficiente fare click sulle frecce blu Questo influenzeragrave lrsquoordine di visualiz-zazione delle portlet nella pagina
Rimuovere le Portlets
Per rimuovere una Portlet cliccare sulla ldquoXrdquo rossa di fianco al nome della stessa
18 Gestione delle Portlet 131
Documentazione di Plone Release 4
Nascondere le Portlets
Da Plone 4 puoi visualizzarenascondere le portlets utilizzando il rispettivo link visualizzanascondi
Come avrai notato nella schermata ldquoGestisci Portletrdquo puoi modificare le portlets sia sul lato destro sia su quello sinistrodella pagina Questo percheacute ci sono due colonne per le portlet una a sinistra e una a destra Le Portlet apparirannosolo sul lato in cui vengono aggiunte
Ersquo possibile aggiungere piugrave di una portlet dello stesso tipo in una pagina Non crsquoegrave nessun limite rispetto a quante voltepossa essere utilizzata la stessa portlet o al numero di portlet per pagina
183 I tipi di Portlet
Descrizione dei tipi di Portlet disponibili
Ci sono diversi tipi di Portlet da scegliere A volte il nome dei vari tipi puograve essere ambiguo Inoltre alcuni possonoessere configurati attraverso la Gestione Portlet e altri richiedono configurazioni attraverso la ZMI o la preventivacreazione di un oggetto Di seguito egrave riportato un elenco con la descrizione base drsquouso e le funzionalitagrave di ogni tipo diportlet disponibile
Navigazione
La portlet di Navigazione permette agli utenti di navigare il sito con facilitagrave fornendo una ldquomappa del sitordquo strut-turata o albero di navigazione Hai la possibilitagrave di configurare la portlet in modo tale che la navigazione mostrilrsquointero sito o scegliere solo di visualizzare il contenuto della cartella corrente In LearnPloneOrg egrave possibile vedereun esempio della Portlet di Navigazione nella colonna di sinistra Addentrandosi nel sito lrsquoalbero continueragrave adespandersi Ci sono diverse opzioni disponibili per modificare il comportamento della Portlet di Navigazione
Calendario
La portlet Calendario egrave molto semplice e permette di visualizzare un Calendario sul proprio sito Questa portlet nonha opzioni personalizzabili Se hai pubblicato degli oggetti eventi sul tuo sito i giorni in cui si verificheranno sarannoin grassetto e cliccandoci sopra si verragrave indirizzati allrsquo evento corrispondente sul sito
Classico
La Portlet Classico si riferisce al modo in cui le portlet sono state utilizzate nelle vecchie versioni di Plone primadi Plone 3 Egrave necessario creare un Page Template nella ZMI ed impostare correttamente il percorso e le macro perattivare la portlet Questo richiede una conoscenza tecnica sia di TALES sia della ZMI
Collezione
La Portlet Collezione ti permette di visualizzare i risultati di una Collezione Egrave necessario creare precedentementeuna collezione e dopo aver aggiunto questa Portlet si potragrave specificare la Collezione da utilizzare Questo egrave un ottimomodo per riassumere i risultati di una importante raccolta in modo che sia facilmente visibile al pubblico
Eventi
La Portlet Eventi mostreragrave gli Eventi Futuri a condizione che ci siano Eventi sul proprio sito Egrave possibile personal-izzare il numero di eventi che si desidera visualizzare e specificare un filtro in base allo stato di pubblicazione
132 Chapter 1 Plone 4 Manuale utente
Documentazione di Plone Release 4
Autenticazione
La Portlet di Autenticazione egrave unrsquoaltra portlet non configurabile che semplicemente visualizza la Form di Log inper consentire agli utenti di autenticarsi Una volta che un utente egrave loggato sul sito questa Portlet verragrave nascostaautomaticamente
Notizie
La Portlet Notizie funziona esattamente come la Portlet Eventi Tuttavia invece che visualizzare Eventi mostreragrave leultime Notizie Nuovamente potrai personalizzare il numero di Notizie da visualizzare e filtrarle in base allo stato dipubblicazione
Flusso RSS
La Portlet Flusso RSS ti permette di fare un link ad un Flusso RSS di scegliere quante notizie visualizzare e dispecificare il tempo di aggiornamento
Contenuti Recenti
La Portlet Contenuti Recenti visualizza un numero personalizzabile di Contenuti Recenti elencati per Titolo UnContenuto viene classificato Recente in base alla Data dellrsquoultima Modifica fatta
Elenco di Revisione
La Portlet Elenco di Revisione visualizzeragrave un elenco di oggetti da revisionare Se si utilizza un workflow dove egravepresente uno stato di revisione (e sono impostati correttamente i ruoli globali per gli utenti) questa portlet egrave moltocomoda ai revisori per tenere sottrsquoocchio quando un oggetto viene inviato per essere sottoposto a revisione QuestaPortlet appare solo ai revisori poichegrave i contentuti in stato sottoposto a revisione non sono visibile al pubblico
Ricerca
La Portlet Ricerca visualizzeragrave una casella di ricerca nella colonna dove viene aggiunta La ricerca del testo specificatoavverragrave nel titolo nella descrizione e nel corpo degli oggetti del sito Crsquoegrave la possibilitagrave di abilitare la Ricerca Istantaneache mostra i risultati durante la digitazione del testo da ricercare se il browser supporta JavaScript
Testo Statico
La Portlet Testo Statico permette di inserire del testo come in una normale Pagina Ersquo utile per aggiungere collegamentiad altri siti o qualsiasi informazione statica Un esempio egrave la Portlet ldquoAncora Perplessirdquo sulla destra di questo sito
18 Gestione delle Portlet 133
Documentazione di Plone Release 4
134 Chapter 1 Plone 4 Manuale utente
CHAPTER 2
Altri manuali
21 Creare un tema con Diazo
Questa guida fornisce una panaromica sullrsquouso di DIAZO per creare un tema in Plone
135
Documentazione di Plone Release 4
Contents
bull Creare un tema con Diazondash Che cosrsquoegrave un tema Diazondash Uso del pannello di controllo
Selezionare un tema Creare un nuovo tema Caricamento di un tema esistente Modifica del tema Ispezione del tema Il generatore delle regole Impostazioni avanzate
ndash Riferimenti Sviluppo e test dei temi
middot Installazione sul filesystemmiddot Installazione attraverso il webmiddot Installazione come file zipmiddot Installazione tramite un pacchetto Python (solo per programmatori)
Il file lsquomanifestorsquo Sintassi delle regole
middot Selettorimiddot Condizionimiddot Regole disponibilimiddot rulesmiddot thememiddot replacemiddot beforemiddot dropmiddot mergemiddot Modifiche avanzate
Parametri del tema Debug del tema Regole di uso comune Uso avanzato di portal_css per la gestione del proprio CSS
211 Che cosrsquoegrave un tema Diazo
Un ldquotemardquo definisce lrsquoaspetto grafico e le modalitagrave di interazione per un sito web (in questo caso un sito basato suPlone)
Diazo (giagrave conosciuto cone XDV) egrave una tecnologia utilizzabile per creare il tema di un sito web Non egrave specifico perPlone ma egrave stato creato dalla comunitagrave Plone e a partire dalla versione Plone 43 fornisce la modalitagrave predefinita perlrsquoapplicazione di un tema ad un sito Plone Per saperne di piugrave httpdiazoorg
I temi Diazo possono esseri un porsquo differenti da quelli creati in altri sistemi ed anche dai temi creati per le precedentiversioni di Plone Un tema Diazo egrave in realtagrave la trasformazione di contenuti ndash in questo caso lrsquooutput di un Plone ldquobaserdquondash in un diverso insieme di modelli HTML mediante lrsquoapplicazione di regole che combinano il modello HTML staticodel risultato finale che si vuole ottenere con il contenuto dinamico proveniente da Plone
La precedente modalitagrave per la creazione di un tema in un sito Plone (come pure la modalitagrave presente in molti altrisistemi di gestione dei contenuti) si basa sulla sovrascrittura (overriding) selettiva di template e script che Ploneutilizza per costruire una pagina con le versioni personalizzate che producono un diverso markup HTML Questrsquoultimastrategia puograve risultare sicuramente piugrave potente ma richiede perograve una profonda conoscenza dei meccanismi interni di
136 Chapter 2 Altri manuali
Documentazione di Plone Release 4
Plone e dei comandi di tecnologie usate lato server come Zope Page Templates ed anche Python I temi Diazo sonoinvece facili da capire per i progettisti web ed anche per chi non egrave sviluppatore
Un tema Diazo si compone di tre elementi
1 Uno o piugrave modelli HTML indicati anche come file del tema che rappresentano lrsquoaspetto e lrsquointerfacciadesiderati
Essi conterrano segnaposti per il contenuto che deve essere fonito dal sistema di gestione dei contenuti di PloneI modelli fanno di solito riferimento a file CSS JavaScript e di immagini con i relativi percorsi La modalitagrave piugravecomune usata per creare un tema prevede lrsquoutilizzo di software come Dreamweaver o di un editor di testo perimpostare i relativi markup stili e script e testare poi localmente il tema in un browser web
2 Il contenuto a cui il tema deve essere applicato In questo caso si tratta dellrsquooutput da Plone
3 Un file di regole che definisce il modo in cui i segnaposti nel tema (cioegrave il modello HTML) dovranno esseresostituiti dal markup pertinente nel contenuto
Il file delle regole usa la sintassi XML (simile allrsquoHTML) Questo egrave un semplice esempio
ltxml version=10 encoding=UTF-8gtltrules
xmlns=httpnamespacesploneorgdiazoxmlnscss=httpnamespacesploneorgdiazocssxmlnsxsl=httpwwww3org1999XSLTransformgt`
lttheme href=themehtml gt
ltreplace csscontent-children=content csstheme-children=maingt
ltrulesgt
Nellrsquoesempio si sostituiscono i contenuti (nodi figli) di un elemento segnaposto con id HTML main nel file del tema(themehtml che si trova nella stessa directory del file rulesxml come indicato nel riferimnto della regola lttheme gt)con i contenuti (figli) dellrsquoelemento con lrsquoid HTML content nel markup generato da Plone
Quando viene applicato questo tema il risultato avragrave un aspetto molto simile a quello del file HTML statico themehtml(ed ai suoi file di riferimento CSS JavaScript ed immagini) eccezzion fatta per il segnaposto identificato nel tema dalnodo con id main che saragrave riempito dallrsquoarea di contenuto principale di Plone
Plone viene fornito con un tema di esempio chiamato appunto Example theme che usa il venerabile Twitter Bootstrapper costruire un tema semplice ma funzionale che espone la maggior parte delle funzionalitagrave di Plone ldquobaserdquo Siconsiglia di studiarlo - in particolare il file rulesxml ndash per capire meglio come lavorano i temi Diazo
212 Uso del pannello di controllo
Dopo lrsquoinstallazione del package lsquoDiazo theme supportrsquo in un sito Plone nella pagina di configurazione del sito Plonecompariragrave il pannello di controllo Theming
La scheda principale Themes di questo pannello di controllo mostreragrave tutti i temi disponibili con i tasti comando perattivaredisattivare modificare copiare o cancellare ciascun tema come pure i tasti comando per creare nuovi temi ofar apparire il contenuto di questo documento
Con un click sullrsquoimmagine con lrsquoanteprima del tema si apre lrsquoanteprima del tema in una nuova scheda o in una nuovafinestra Lrsquoanteprima egrave navigabile ma lrsquoinvio di un form ed alcune funzioni avanzate non funzionano
21 Creare un tema con Diazo 137
Documentazione di Plone Release 4
Selezionare un tema
Per applicare un tema esistente basta un click sul tasto comando Activate posizionato sotto lrsquoanteprima del tema Iltema attualmente attivo saragrave evidenziato in giallo Se il tema attivo viene disattivato non risulteragrave applicato alcun temaDiazo pertanto verragrave applicato il tema ldquobaserdquo di Plone
nb Al pannello di controllo Theming non si applica mai il tema assicurando in tal modo che si potragrave sempredisattivare un tema che genera errore e che potrebbe rendere inutilizzabile lo stesso pannello di controllo Non si vedragravepertanto alcuna differenza immediatamente dopo lrsquoabilitazione di un tema Basta perograve passare a unrsquoaltra pagina delsito Plone e si dovrebbe vedere il tema applicato
Creare un nuovo tema
I nuovi temi possono essere creati in due modi
bull Nel pannello di controllo Theming Click sul tasto comando New theme nella parte superiore della schedaThemes ed immettere un titolo e una descrizione nel form visualizzato Verragrave creata la struttura essenziale deltema e verragrave visualizzata la pagina Modify theme dove si potranno modificare o creare i file del tema e delleregole
bull Click sul tasto comando Copy presente sotto ad ogni tema esistente e nel form visualizzato inserire il titolo e ladescrizione del tema Verragrave creato un nuovo tema copia del tema esistente e verragrave visualizzata la pagina Modifytheme dove si potranno modificare o creare i file del tema e delle regole
Caricamento di un tema esistente
I temi possono essere distribuiti come file Zip contenenti i file del modello HTML e delle regole Per caricare unfile esistente basta un click sul tasto comando Download presente sotto al tema nella scheda Themes del pannello dicontrollo di Theming
Per caricare un file di questo tipo in un altro sito si usa il tasto comando Upload Zip file nella scheda Themes delpannello di controllo di Theming Si puograve scegliere se sostituire o meno un tema esistente ed avente lo stesso nome (inbase al nome della directory di livello superiore contenuta allrsquointerno del file Zip)
Si puograve anche caricare il file di un modello statico HTML che non contiene il file delle regole quale puograve essere peresempio un progetto fornito da un progettista che non egrave un praticante di Plone
In questo caso verragrave aggiunto automaticamente un file di base (rulesxml) per permettere di iniziare a costruire un temautilizzando la schermata Modify theme Il file di regole generato assume che il file principale del modello HTML abbianome indexhtml che potragrave comunque essere cambiato in rulesxml
Una volta caricato con successo un file Zip del tema verragrave presentata la schermata Modify theme dove si potragravemodificare il file del tema o creare un nuovo file
Suggerimento Se si riceve un messaggio di errore del tipo ldquoIl file caricato non contiene un archivio valido di temardquoquesto di solito significa che egrave stato caricato un file zip che contiene piugrave file e cartelle piuttosto che una singolacartella di livello superiore contenente tutte le risorse del tema Ciograve potrebbe accadere se egrave stato compresso un tema oun modello HTML aggiungendo i relativi file e cartelle direttamente in un archivio Zip piuttosto che comprimere ladirectory in cui sono stati trovati Per risolvere questo problema egrave sufficiente decomprimere lrsquoarchivio in una nuovadirectory sul computer locale salire di un livello e comprimere questa directory da sola in un nuovo file Zip che egravepoi possibile caricare
Modifica del tema
Si accede alla modifica di un tema con un click sul tasto comando Modify theme posto sotto al tema nella schedaThemes del pannello di controllo di Theming Questa schermata viene aperta automaticamente quando si crea o si
138 Chapter 2 Altri manuali
Documentazione di Plone Release 4
carica un nuovo tema
nb Da Plone si possono modificare solo i temi creati o caricati dal pannello di controllo di Theming Non possonoinvece essere modificati i temi installati dagli add-on di terze parti anche se le modifiche apportate sul file systemsi rifletteranno immediatamente se Zope viene eseguito in modalitagrave di debug Per modificare un tema presente sulfilesystem si puograve copiarlo in un nuovo tema Plone con il tasto comando Copy presente sotto il tema nel pannello dicontrollo di Theming
La schermata Modify theme mostra inizialmente un gestore di file con lrsquoalbero dei file sulla sinistra ed un editor sulladestra Un Click su un file nellrsquoalbero dei file apre un editor o unrsquoanteprima file HTML CSS JavaScript ed altri filedi testo possono essere visualizzati direttamente nellrsquoeditor Altri file (pes immagini) saranno aperti in anteprima
Nb Nel browser Internet Exploredi Microsoft non egrave disponibile lrsquoeditor avanzato con la sintassi evidenziata
Un click su New folder per creare una nuova cartella Questo si puograve ottenere anche con un click destro su una cartelladellrsquoalbero dei file
Un click su New file per creare un nuovo file Questo si puograve ottenere anche con un click destro su una cartelladellrsquoalbero dei file
Un click su Upload file per caricare un file dal computer locale Questo si puograve ottenere anche con un click destro suuna cartella dellrsquoalbero dei file
Un click su Preview theme per per visualizzare in anteprima il tema secondo il modello e le regole attualmente salvateLrsquoanteprima egrave navigabile ma i form ed alcune funzionalitagrave avanzate non funzionano
Per salvare le modifiche fatte nel file corrente click sul tasto comando Save file oppure utilizzare i tasti di scelta rapidaCtrl+S (WindowsLinux) o Cmd+S (Mac)
Per rinominare o cancellare un file o una cartella basta un click destro sullrsquoelemento di interesse nellrsquoalbero dei file esi seleziona poi lrsquoazione desiderata
Ispezione del tema
Lo strumento di ispezione di un tema fornisce unrsquointerfaccia avanzata per scoprire e costruire le regole di un temaDiazo Puograve essere lanciato con il tasto comando Show inspectors presente nella schermata Modify theme per i temipropri di Plone o con il tasto comando Inspect theme presente sotto ad un tema del filesystem nella scheda Themesdel pannello di controllo di Theming
Lo strumento di ispezione di un tema egrave costituito da due pannelli
bull Il mockup HTML Se ci sono diversi file HTML in un tema egrave possibile passare da uno allrsquoaltro utilizzando lalista a discesa posizionata sotto il pannello del modello HTML
bull Il Unthemed content Mostra Plone senza alcun tema applicato
La dimensione di entrambi i pannelli possono essere massimizzate con un click sulle icone delle frecce presenti in altoa destra in ciascun pannello
I pannelli HTML mockups ed Unthemed content possono passare alla vista sorgente e mostrare il codice HTMLsottostante con un click sulle icone tag presenti in alto a destra in ciascun pannello
Posizionando il mouse sopra gli elementi nei pannelli del mockup HTML o del Unthemed content si vedragrave
bull Un contorno che mostra lrsquoelemento sotto il cursore
bull Un selettore CSS o XPath nella barra di stato nella parte inferiore del pannello il selettore identifica univoca-mente lrsquoelemento in una regola Diazo
Click su un elemento o premere Enter quando il mouse egrave posizionato sopra un elemento per selezionarlo Lrsquo elementoselezionato piugrave di recente in ciascun pannello viene mostrato nella barra di stato presente nella parte inferiore diciascun pannello
21 Creare un tema con Diazo 139
Documentazione di Plone Release 4
Premendo Esc quando il mouse egrave posizionato sopra un elemento per selezionare il suo genitore Ciograve egrave utiite quando sicerca di selezionare elementi contenitori ldquonon visibilirdquo Premere Enter per salvare la selezione
I contenuti del pannello del mockup HTML o (piugrave comunemente ) di quello del Unthemed content sono navigabiliper ottenere per esempio una pagina di contento che richiede regole del tema specifiche disabilitando lo strumento diispezione Utilizzare i commutatori in basso a destra del pannello in questione per attivare o disattivare il selettore
Il generatore delle regole
Usare il tasto comando Build rule nella parte superiore della schermata Modify theme o Inspect theme per lanciarela procedura guidata per la costruzione interattiva delle regole Verragrave richiesto il tipo di regola da costruire e quindidi selezionare come richiesto i relativi elementi nei pannelli del mockup HTML eo di Unthemed content Perimpostazione predefinita vengono utilizzate le selezioni salvate a meno che non si deselezioni la casella Use selectedelements nella prima pagina della procedura guidata
Al termine della procedura guidata verragrave mostrata la regola generata Se si vuole la regola puograve essere modificata Conun click su Insert la nuova regola generata viene inserita nellrsquoeditor di rulesxml in corrispondenza o vicino allrsquoattualeposizione del cursore Egrave possibile spostare o modificare ulteriormente la regola a proprio piacimento
Click Preview theme per lrsquoanteprima del tema in una nuova scheda o finestra Se sono state fatte modifiche ricordarsidi salvare il file rulesxml
Nb In modalitagrave di solo lettura si possono costruire regole ed ispezionare il modello HTML ed il tema ma non cam-biare il file rulesxml file In questo caso anche il tasto comando Insert del generatore di regole non saragrave disponibile
Nb Nel browser Internet Explorer di Microsoft non egrave disponibile la possibilitagrave di inserire regole con la proceduraguidata Build rule anche se saragrave data la possibilitagrave di copiare la regola negli appunti quando si utilizza questo browser
Impostazioni avanzate
Il pannello di controllo di Theming contiene anche una scheda con nome Advanced settings E qui comincialrsquoavventura
La scheda Advanced settings egrave divisa in due aree La prima Theme details contiene le impostazioni che vengonomodificate quando viene applicato un tema dal pannello di controllo Themes
Queste sono
bull Abilitazione dei temi Diazo
bull Il percorso del file di regole chiamato convenzionalmente rulesxml sia relativo alla root del sito Plone o comepercorso assoluto verso un server esterno
bull Il prefisso da applicare per passare nei temi da percorsi relativi (p es i riferimenti ad immagini nellrsquoattributosrc del tag ltimg gt ) a percorsi assoluti in fase di visualizzazione dei contenuti
bull Il DOCTYPE HTML da applicare allrsquooutput generato se diverso dal valore predefinito XHTML 10 Transi-tional
bull Se permettere o meno la lettura dalla rete delle risorse del tema (come rulesxml) Disattivare questa voce portaad un modesto miglioramento delle prestazioni
bull Una lista di nomi di host ai quali non viene mai applicato un tema Spesso contiene 127001 che consentedi vedere per esempio nella fase di sviluppo un sito senza tema in http1270018080 ed il sito con tema inhttplocalhost8080
bull Una lista di parametri del tema e le espressioni TALES che li generano (vedi di seguito)
140 Chapter 2 Altri manuali
Documentazione di Plone Release 4
Il secondo Theme base controlla la presentazioni dei contenuti senza lrsquoapplicazione di alcun tema utilizzabile anchese non viene applicato alcun tema Diazo Queste sono le impostazioni che si trovavano nel pannello di controlli diThemes nelle precedenti versioni di Plone
213 Riferimenti
Il resto di questa guida contiene materiale di riferimento utile per i realizzatori di temi
Sviluppo e test dei temi
Per costruire e testare un tema si deve prima creare un modello statico HTML con lrsquoaspetto grafico e le modalitagrave diinterazione che si desiderano e realizzare poi un file di regole per descrivere come il contenuto di Plone viene mappatonei segnaposto di questo modello
Il modello puograve essere creato ovunque con lrsquoutilizzo dello strumento che si ritiene piugrave adatto per la realizzazione dipagine web Per semplificare lrsquointegrazione con Plone si raccomanda di essere certi che vengano usati i collegamentirelativi per le risorse quali file CSS JavaScript ed immagini in modo che siano visualizzati correttamente quandovengono aperti in un browser Web da un file locale Plone convertiragrave automaticamente questi collegamenti relativinegli appropriati percorsi assoluti assicurando cosigrave il corretto funzionamento del tema indipendentemente dllrsquoURLvisualizzato dallrsquoutente quando il tema egrave applicato ad un sito Plone
Ci sono diversi modi per rendere disponibile il tema in Plone
Installazione sul filesystem
Se si usa unrsquoinstallatore o un ldquobuildoutrdquo standard per allestire un sito Plone dovrebbe allora essere presente una direc-tory con nome resources nella root dellrsquoinstallazione Plone (questa directory viene creata se si usa lrsquoopzione resourcesnella ricetta del buildout plonerecipezope2instance Vedi httppypipythonorgpypiplonerecipezope2instance permaggiori dettagli)
Dentro questa directory si puograve trovare (o creare) una directory theme che viene usata per contenere temi Ciascuntema richiede una propria directory con un nome univoco Se ne crea una (p es resourcesthememytheme) e siinseriscono al suo interno i file HTML e ogni risorsa di riferimento Se lo si desidera si possono usare subdirectoryma si consiglia di conservare i file HTML di base del tema nella parte superiore della cartella del tema
Saragrave necessario anche un file di regole chiamato rulesxml allrsquointerno della directory Se non egrave giagrave disponibile se necrea uno vuoto
ltxml version=10 encoding=UTF-8gtltrules
xmlns=httpnamespacesploneorgdiazoxmlnscss=httpnamespacesploneorgdiazocssxmlnsxsl=httpwwww3org1999XSLTransformgt`
lttheme href=themehtml gt
ltreplace csscontent-children=content csstheme-children=main gt
ltrulesgt
Se si esegue Zope in modalitagrave debug (p es egrave stato avviato con bininstance fg) le modifiche fatte al tema e alle regolehanno effetto immediato Si puograve avere unrsquoanteprima o abilitare il tema attraverso il pannello di controlloThemes equindi modificare come si desidera ed in modo interattivo il file rulesxml o il modello del tema
21 Creare un tema con Diazo 141
Documentazione di Plone Release 4
Installazione attraverso il web
Se lo si preferisce (o non si ha lrsquoaccesso al filesystem) si puograve creare completamente il tema dal pannello di controllodi Plone sia per duplicazione di un tema esistente sia partendo da zero con un tema quasi vuoto
Per maggiori dettagli si rimanda alle istruzioni sullrsquouso del pannello di controllo descritte precedentemente
Una volta creato il tema puograve essere modificato dal pannello di controllo di Theming Per maggiori dettagli si rimandaalle istruzioni descritte precedentemente
Installazione come file zip
I temi possono essere scaricati da Plone come file Zip questi file possono essere poi caricati in altri siti web
Per maggiori dettagli si rimanda alle istruzioni sullrsquouso del pannello di controllo descritte precedentemente
Ersquo infatti possibile creare archivi zip del tema validi comprimendo la cartella di un tema presente su filesystem utiliz-zando uno strumento standard di compressione come 7-Zip o Winzip (per Windows) o lrsquoazione Compress incorporatanel Mac OS X Finder Bisogna solo essere certi di comprimere esattamente la cartella che contiene tutti i file del temaed il file rulesxml (Non comprimere direttamente i contenuti della cartella il file zip quando viene scompattato deveprodurre esattamente una cartella che a sua volta contiene i relativi file)
Installazione tramite un pacchetto Python (solo per programmatori)
Se si sta creando un pacchetto Python che contiene le personalizzazioni di Plone che si intendono installare nel sito sipuograve usarlo per registrare un tema da installare nel sito
Per fare questo si posiziona una directory p es di nome Themeallrsquoinizio del pacchetto accanto al file Zopeconfigurezcml ed si aggiunge una dichiarazione ltplonestatic gt nel file configurezcml
ltconfigurexmlnsplone=httpnamespacesploneorgplonexmlns=httpnamespaceszopeorgzopegt
ltplonestatic name=mytheme directory=theme type=theme gt
ltconfiguregt
Si noti la dichiarazione del namespace plone nellrsquoelemento radice ltconfigure gt I file del tema ed il file rulesxmlvanno posizionati nella directory theme
Se il pacchetto ha un GenericSetup profile si puograve abilitare dopo lrsquoinstallazione di questo profilo aggiungendo nelladirectory profilesdefault un file themexml contenente p es
ltthemegtltnamegtmythemeltnamegtltenabledgttrueltenabledgt
ltthemegt
142 Chapter 2 Altri manuali
Documentazione di Plone Release 4
Il file lsquomanifestorsquo
Ersquo possibile dare ulteriori informazioni sul tema inserendo allrsquoinizio della directory di un tema un file con nomemanifestcfg accanto al file rulesxml
Il file ha un aspetto di questo tipo
[theme]
title = My theme
description = A test theme
Come si vede il file lsquomanifestorsquo puograve essere utilizzato per fornire un titolo del tema piugrave comprensibile ed una de-scrizione piugrave lunga da usare poi nel pannello di controllo Ersquo richiesta solo lrsquointestazione [theme] ndash tutte le altre chiavisono opzionali
Si puograve anche impostare
rules = httpexampleorgmyrulesxml
per usare un nome per il file delle regole diverso da rulesxml (si deve fornire un URL o un percorso relativo)
Per cambiare l prefisso per il percorso assoluto (vedi Impostazioni avanzate) si usa
prefix = someprefix
Per impiegare un DOCTYPE diverso da XHTML 10 Transitional per il contenuto a cui viene applicato il temaaggiungere p es
doctype = html
Per visualizzare nel pannello di controllo Theming unrsquoanteprima user-friendly del tema aggiungere
preview = previewpng
previewpng egrave il file di unrsquoimmagine relative to the location del file manifestcfg
Estensioni del motore di Diazo possono aggiunger il supporto per ulteriori blocchi di parametri configurabili
Sintassi delle regole
Nel seguito un breve sommario della sintassi delle regole di Diazo Vedi httpdiazoorg per maggiori dettagli ed altriesempi
Selettori
Ciascuna regola egrave composta da un tag XML che opera su uno o piugrave elementi HTML nel contenuto e o sul tema Glielementi su cui operare sono indicati da attributi delle regole noti come selettori
Il modo piugrave semplice per selezionare gli elementi egrave quello di utilizzare una espressione selettore CSS come ad esempiocsscontent=rdquocontentrdquo o csstheme=rdquomain contentrdquo Si puograve utilizzare una qualsiasi espressione CSS3 valida (inclusipseudo-selettori qualifirst-child)
I selettori standard csstheme e csscontent operano sullrsquoelementoi che soddisfano la selezione Se invece si vuoleoperare sui figli degli elementi selezionati si deve usare csstheme-children=rdquordquo o csscontent-children=rdquordquo
Se non egrave possibile costruire una espressione CSS 3 adeguata egrave possibile utilizzare espressioni XPath come con-tent=rdquoheadlinkrdquo o theme=rdquodiv[id=rsquomainrsquo]rdquo (si noti la mancanza di un prefisso css quando si usano le espressioni
21 Creare un tema con Diazo 143
Documentazione di Plone Release 4
XPath) I due approcci sono equivalenti e si possono combinare liberamente ma non si puograve avere ad esempio sia uncsstheme ed un attributo theme nella stessa regola Per operare sui figli di un nodo selezionato con unrsquoespressioneXPath si puograve usare theme-children=rdquordquo o content-children=rdquordquo
Per approfondire XPath vedi httpwwww3schoolscomxpathdefaultasp
Condizioni
Per impostazione predefinita ogni regola viene eseguita anche se le regole a cui non corrispondono elementi nonmodificano nulla nella pagina attuale Si puograve creare una regola unrsquoinsieme di regole o un riferimento al tema (vedisotto) a condizione che un elemento sia presente nel contenuto aggiungendo un attributo alla regole del tipo cssif-content=rdquosome-elementrdquo (per usare invece unrsquoespressione XPath eliminare il prefisso css ) La regola viene ignoratase nessun elemento soddisfa lrsquoespressione
Suggerimento se una regola ltreplace gt corrisponde a un elemento nel tema ma non nel contenuto il nodo temasaragrave eliminato e non sostituito Se non si desidera questo comportamento e non si egrave sicuri se il contenuto conterragravelrsquoelementoi in questione egrave possibile utilizzare la regola condizionale cssif-content Poicheacute questa egrave una situazionecomune egrave disponibile una scorciatoia cssif-content=rdquordquo che significa ldquousare lrsquoespressione dallrsquoattributo csscontentrdquo
Allo stesso modo egrave possibile creare una condizione in base al percorso della richiesta corrente utilizzando un attributodel tipo if-path=rdquonewsrdquo (si noti lrsquoassenza di cssif-path ) Se questo percorso inizia con una barra () lrsquoeventualecorrispondenza saragrave con la fine dellrsquoURL Si puograve impostare un percorso assoluto usando un barra iniziale ed una finale()
Si possono infine usare espressioni XPath arbitrarie invece di una variabile definita con un attributo del tipo if=rdquo$host= lsquolocalhostrdquorsquo Per impostazione predefinita sono disponibili le variabili url scheme host e base che rappresentanolrsquoURL attuale I temi possono definire ulteriori variabili nei rispettivi manifesti
Regole disponibili
Di seguito il riassunto dei vari tipi di regole
rulesltrulesgt
ltrulesgt
Racchiude un insieme di regole Deve essere utilizzato come elemento radice del file delle regole ltrules gt nidificatopuograve essere utilizzato assieme ad una condition per applicare una singola condizione ad unrsquoinsieme di regole
Quando viene utilizzato come elemento radice del file delle regole debbono essere dichiarati i vari namespace XML
ltrulesxmlns=httpnamespacesploneorgdiazoxmlnscss=httpnamespacesploneorgdiazocssxmlnsxsl=httpwwww3org1999XSLTransformgt
ltrulesgt
144 Chapter 2 Altri manuali
Documentazione di Plone Release 4
themelttheme href=themehtml gtlttheme href=newshtml if-path=news gtltnotheme if=$host = adminexampleorg gt
Sceglie il file del tema da utilizzare Lrsquoattributo href egrave un percorso relativo a file di regole Se sono presenti piugraveelementi lttheme gt solo per uno di essi puograve essere assente una condizione Verragrave utilizzato il primo tema con unacondizione che sia vera con il tema senza condizioni utilizzato come riserva
ltnotheme gt puograve essere usato per specificare una condizione che non prevede lrsquouso di alcun tema ltnotheme gt ha laprecedenza su lttheme gt
Suggerimento Per essere sicuri di non applicare gli stili a pagine non Plone aggiungere allrsquoultimo tema della listauna condizione del tipo cssif-condition=rdquovisual-portal-wrapperrdquo e non inserire alcun tema senza condizione
replaceltreplace
csscontent=contentcsstheme=main
gt
Sostituisce gli elementi che soddisfano la regola nel tema con i corrispondenti che soddisfano la regola nel contenuto
beforeltbefore
csscontent-children=portal-column-onecsstheme-children=portlets
gt
ltaftercsscontent-children=portal-column-twocsstheme-children=portlets
gt
Inserisce gli elementi che soddisfano la regola nel contenuto prima o dopo i corrispondenti nel tema Utilizzandotheme-children si possono inserire gli elementi del contenuto selezionati allrsquoinizio (prepend) o alla fine (append)allrsquointerno dei corrispondenti elementi che soddisfano la regola nel tema
dropltdrop csscontent=documentByLine gtltdrop theme=headlink gtltdrop csstheme=content attributes=onclick onmouseup gtltstrip csscontent=parent-fieldname-text gt
Rimuove gli elementi dal tema o dal contenuto Si noti che a differenza di altre regole una regola ltdrop gt o ltstrip gtpuograve operare sul theme o sul content ma non su entrambi ltdrop gt rimuove gli elementi corrispondenti ed i relativifigli mentre ltstrip gt rimuove gli elementi corrispondenti ma non i relativi figli
A ltdrop gt puograve essere data una lista di attributes da rimuovere separati da spazi bianchi In questo caso gli elementicorrispondenti non saranno rimossi Usando attributes=rdquordquo si rimuovono tutti gli attributi
merge
21 Creare un tema con Diazo 145
Documentazione di Plone Release 4
ltmergeattributes=classcsscontent=bodycsstheme=body
gt
ltcopyattributes=classcsscontent=contentcsstheme=main
gt
Queste regole operano sugli attributi ltmerge gt aggiungeragrave i contenuti letti nel tema per gli attributi indicati aivalori di ogni attributo esistente nel contenuto avente lo stesso nome i valori sono separarti da spazi bianchi Ersquoprincipalmente usato per aggiungere classi CSS
ltcopy gt copia gli attributi dagli elementi che soddisfano la regola nel contenuto nei corrispondenti elementi nel temagli attributi con lo stesso nome eventualmente giagrave presenti nel tema vengono completamente sostituiti
Lrsquoattributo attributes puograve contenere una lista di attributi separati da spazi bianchi oppure il valore speciale peroperare su tutti gli attributi degli elementi che soddisfano la regola
Modifiche avanzate
Invece di selezionare il markup da inserire nel tema dal contenuto egrave possibile inserire il markup direttamente nel filedelle regole come nodi figlio dellrsquoelemento della relativa regola
ltafter csstheme=headgtltstyle type=textcssgt
body gt h1 color red ltstylegt
ltaftergt
Nello stesso modo si puograve operare sul contenuto Ersquo cosigrave possibile modificarlo prima dellrsquoapplicazione delle regole
ltreplace csscontent=portal-searchbox inputsearchButtongtltbutton type=submitgt
ltimg src=imagessearchpng alt=Search gtltbuttongt
ltreplacegt
Oltre ad aggiungere in questo modo HTML statico si possono usare le istruzioni XSLT che operano sul contenuto InXSLT si possono anche usare direttamente i selettori css
ltreplace csstheme=detailsgtltdl id=detailsgt
ltxslfor-each cssselect=tabledetails gt trgtltdtgtltxslcopy-of select=td[1]text()gtltdtgtltddgtltxslcopy-of select=td[2]node()gtltddgt
ltxslfor-eachgtltdlgt
ltreplacegt
Utilizzando lrsquoattributo href per specificare il percorso di una risorsa relativamente alla root del sito Plone le regolepossono operare su contenuti provenienti da sorgenti che non siano lrsquoattuale pagina restituita da Plone
ltaftercsstheme-children=leftnav
146 Chapter 2 Altri manuali
Documentazione di Plone Release 4
csscontent=navitemhref=extra-nav
gt
Parametri del tema
Ersquo possibile passare al tema parametri arbitrari a cui si puograve far riferimento come a variabili nelle espressioni di XPathI parametri possono essere impostati nel pannello di controllo Theming di Plone e possono anche venire importati daun file manifestcfg
Si potrebbe avere per esempio un parametro mode impostabile con la stringa live o test Nelle proprie regole sipotrebbe fare qualcosa del genere per inserire un avviso visualizzato quando si lavora sul server di prova
ltbefore csstheme-children=body if=$mode = testgtltspan class=warninggtAttenzione questo egrave il server di provaltspangt
ltbeforegt
Si puograve usare anche direttamente il valore del parametro p es
ltbefore csstheme-children=bodygtltspan class=infogtQuesto egrave il server di ltxslvalue-of select=$mode gtltspangt
ltbeforegt
I seguenti parametri sono sempre disponibili per i temi Plone
scheme Il nome dello schema dellrsquoURL in entrata (la parte che precede i due punti) normalmente http o https
host Il nome nellrsquoURL in entrata del server che ha inviato i dati
path Il segmento dellrsquoURL in entrata relativo al percorso Non include alcun virtual hosting tokens egrave cioegrave il percorsovisto dallrsquoutente finale
base Il Zope base url (la variabile BASE1 di una request a Zope)
Si possono aggiungere ulteriori parametri dal pannello di controllo utilizzando espressioni TALES I parametri sonoelencati uno per riga nella scheda Advanced nel formato ltnamegt = ltexpressiongt
Se per esempio si vuole evitare di applicare il tema ad ogni pagina caricata dai diversi livelli (overlays) di Plone sipuograve far uso del parametro ajax_load della request parameter impostato dai livelli (overlays) In questo caso ii file delleregole includerebbe
ltnotheme if=$ajax_load gt
Per aggiungere questo parametro come pure il parametro mode descritto in precedenza egrave possibile aggiungere quantosegue nel pannello di controllo
ajax_load = python requestformget(ajax_load)
mode = string test
La parte destra presenta unrsquoespressione TALES Deve restituire un valore di tipo string integer float boolean o Nonele liste i dizionari e gli oggetti non sono supportati python string ed espressioni di percorso funzionano come neiZope Page Templates
Sono disponibili le seguenti variabili quando si costruiscono queste espressioni TALES
context Il contesto dellrsquoattuale request normalmente un oggetto contenuto
request Lrsquoattuale request
21 Creare un tema con Diazo 147
Documentazione di Plone Release 4
portal Lrsquooggetto radice del portale
context_state La vista plone_context_state da cui egrave possibile cercare altri valori come lrsquoURL del contesto o lavista predefinita
portal_state La vista plone_portal_state da cui egrave possibile cercare altri valori come la root dellrsquoURL di nav-igazione o se lrsquoutente attuale egrave collegato (autenticato) o meno
Vedi ploneapplayout per i dettagli circa le viste plone_context_state e plone_portal_state
I parametri del tema sono normalmente parte integrante di un temaTheme e saranno pertanto impostati in base al man-ifesto del tema quando il tema viene importato od abilitato Questo egrave fatto utilizzando la sezione [themeparameters]nel file manifestcfg Per esempio
[theme]
title = My theme
description = A test theme
[themeparameters]
ajax_load = python requestformget(ajax_load)
mode = string test
Debug del tema
Quando Zope egrave in modalitagrave sviluppo (cioegrave esecuzione in foreground in una console con bininstance fg) il tema saragravericompilato ad ogni request Se la modalitagrave non egrave di sviluppo viene compilato al primo accesso poi ricompilato solose vengono cambiati i valori del pannello di controllo
Anche nella fase di sviluppo egrave possibile disabilitare temporaneamente il tema aggiungendo alla request una querystring con il parametro diazooff=1 Per esempio
httplocalhost8080Plonesome-pagediazooff=1
Il parametro viene ignorato se la modalitagrave non egrave di sviluppo
Regole di uso comune
Le ricette che seguono mostrano le regole di uso comune nella costruzione di temi per Plone
Per copiare il titolo della pagina
ltreplace csstheme=title csscontent=title gt
Per copiare il tag ltbase gt (necessario perchegrave funzionino i link di Plone)
ltreplace csstheme=base csscontent=base gt
Se non egrave presente nel tema il tag ltbase gt si puograve procedere cosigrave
ltbefore csstheme-children=head csscontent=base gt
Per eliminare dal tema tutte le risorse relative agli stili ed a JavaScript e copiarle invece dallo strumento di Ploneportal_css
148 Chapter 2 Altri manuali
Documentazione di Plone Release 4
lt-- elimina gli stili in head - questi vengono aggiunti nuovamenteincludendo quelli di Plone --gt
ltdrop theme=htmlheadlink gt
ltdrop theme=htmlheadstyle gt
lt-- inserimento dei CSS di Plone --gt
ltafter theme-children=htmlhead content=htmlheadlink |htmlheadstyle gt
Per copiare le risorse JavaScript di Plone
lt-- inserimento degli script di Plone --gt
ltafter theme-children=htmlhead content=htmlheadscript gt
Per copiare la classe del tag ltbody gt (necessaria per il corretto funzionamento di alcune funzioni e di alcuni stiliJavaScript di Plone)
lt-- Body --gt
ltmerge attributes=class csstheme=body csscontent=body gt
Uso avanzato di portal_css per la gestione del proprio CSS
I ldquoregistri delle risorserdquo di Plone incluso lo strumento portal_css possono essere utilizzati per gestire i fogli di stileCSS Questa opportunitagrave offre diversi vantaggi rispetto al semplice collegamento ai propri fogli di stile nel templatecome
bull Controllo dettagliato sullrsquoordine dei fogli di stile
bull Lrsquounione dei fogli di stile per ridurre il numero di download necessari per la presentazione di una pagina
bull Compressione On-the-fly del foglio di stile (ad esempio con rimozione degli spazi bianchi)
bull La possibilitagrave di includere od escludere un foglio d stile in base ad unrsquoespressione
Ersquo spesso desiderabile (e qualche volta assolutamente necessario) lasciare intatto il file del tema ma egrave comunquepossibile utilizzare portal_css per gestire i fogli di stile Il trucco consiste in
bull Registrare i propri stili del tema con lo strumento di Plone portal_css (questo egrave normalmente meglio farlo quandosi inserisce un tema in un pacchetto di Pyton - attualmente non esiste un modo per fare questo automaticamenteper un tema importato da un file Zip o creato attraverso il web)
bull Eliminare gli stili del tema con una regola e quindi
ndash Includere tutti gli stili da Plone
Si potrebbero per esempio aggiungere le seguenti regole
ltdrop theme=htmlheadlink gt
ltdrop theme=htmlheadstyle gt
lt-- Pull in Plone CSS --gt
ltafter theme-children=htmlhead content=htmlheadlink |htmlheadstyle gt
21 Creare un tema con Diazo 149
Documentazione di Plone Release 4
Lrsquouso per il contenuto di unrsquoespressione ldquoorrdquo nella regola ltafter gt indica che viene mantenuto lrsquoordine relativo deglielementi link e style
Per registrare i fogli di stile al momento dellrsquoinstallazione del prodotto mediante GenericSetup bisogna usare il passodi importazione di cssregistryxml nella directory del proprio GenericSetup profilesdefault
ltxml version=10gt
ltobject name=portal_cssgt
lt-- Imposta le condizioni relative ai fogli di stile che non sivogliono includere --gt
ltstylesheetexpression=notrequestHTTP_X_THEME_ENABLED | nothingid=publiccss
gt
lt-- aggiunge i nuovi fogli di stile --gt
ltstylesheet title= authenticated=False cacheable=Truecompression=safe conditionalcomment= cookable=True enabled=onexpression=requestHTTP_X_THEME_ENABLED | nothingid=++theme++mythemecssstylescss media= rel=stylesheetrendering=linkapplyPrefix=True
gt
ltobjectgt
Crsquoegrave perograve una cosa importante da cui stare in guardia I propri fogli di stile possono includere dei riferimenti ad URLrelativi nella forma seguente
background-image url(imagesbgjpg)
Se il foglio di stile egrave posizionato in una directory di risorse (ad esempio egrave registrato in portal_css con lrsquoid++theme++mythemecssstylescss) questo funziona bene fino a quando il registro (e Zope) egrave in modalitagrave di debug LrsquoURL relativo saragrave tradotto dal browser in ++theme++mythemeimagesbgjpg
Tuttavia egrave possibile che lrsquoURL relativo non funzioni quando il Registro di sistema viene messo in modalitagrave di pro-duzione Questo percheacute lrsquounione delle risorse cambia anche lrsquoURL del foglio di stile in qualcosa del tipo
plone-siteportal_cssSuburst+Thememerged-cachekey-1234css
1 1Per correggere questo si deve impostare in cssregistryxml il flag applyPrefix a true quando si installano leproprie risorse CSS Esiste un flag corrispondente nellrsquointerfaccia utente di portal_css
Qualche volta egrave utile mostrare alcuni CSS di Plone nel sito Questo si puograve ottenere usando una regola Diazo ltafter gto in modo simile copiare nel tema i CSS dallrsquolthead gt generato da Plone Si puograve utilizzare lo strumento portal_cssper disattivare i fogli di stile indesiderati
Perograve se si vuole che il sito sia usabile anche in modalitagrave senza tema (per esempio in un URL separato) si potrebbe volerabilitare un insieme piugrave ampio di stili quando Diazo non viene utilizzato Per facilitare questa operazione egrave possibileutilizzare le seguenti espressioni come condizioni nello strumento portal_css (ed eventualmente in portal_javascripts)in portal_actions nei page template ed in altri posti che usano la sintassi delle espressioni TAL
requestHTTP_X_THEME_ENABLED | nothing
Lrsquoespressione restituisce True se Diazo egrave attualmente abilitato nel qual caso saragrave impostato un header HTTP ldquoX-Theme-Enabledrdquo
150 Chapter 2 Altri manuali
Documentazione di Plone Release 4
Se in seguito si distribuisce il tema ad un server Web frontale come per esempio nginx si puograve impostare ligrave lo stessoheader della request per ottenere un egual risultato anche se ploneapptheming non egrave installato
Utilizzare
not requestHTTP_X_THEME_ENABLED | nothing
per lsquonasconderersquo un foglio di stile dal sito a cui egrave applicato il tema
22 ZODB - un database nativo ad oggetti per Python
Non schiacciare i tuoi oggetti nelle tabelle memorizzali in un database ad oggetti
221 Panoramica
I programmi Python sono scritti seguendo il paradigma orientato agli oggetti Si utilizzano gli oggetti che fannoriferimento lrsquoun lrsquoaltro liberamente e possono essere di qualsiasi forma e dimension nessun oggetto deve aderire aduno schema specifico e puograve contenere informazioni arbitrarie
Memorizzare quegli oggetti nei database relazionali richiede di rinunciare alla libertagrave dei riferimenti e dello schema Ivincoli del modello relazionale riducono la capacitagrave di scrivere codice orientato agli oggetti
Lo ZODB egrave un database nativo ad oggetti che memorizza i vostri oggetti e consente di lavorare con qualsiasiparadigma che si puograve esprimere in Python In tal modo il vostro codice diventa piugrave semplice piugrave affidabile e facile dacapire
Inoltre non esiste un divario tra il database e il programma nessun codice-colla per scrivere nessuna mappatura daconfigurare Date unrsquoocchiata al tutorial per vedere come egrave facile
Alcune delle funzionalitagrave che lo ZODB ti dagrave sono
bull persistenza trasparente degli oggetti Python
bull supporto alle transazioni pienamente compatibile ACID (inclusi i savepoints)
bull abilitagrave di avere uno storico e la possibilitagrave di annullare
bull supporto efficiente per oggetti binari di grandi dimensioni (BLOB)
bull sistemi di storage innestabili
bull architettura scalabile
222 Documentazione
Tutorial
Questo tutorial ha lo scopo di guidare gli sviluppatori con unrsquointroduczione passo-passo allo sviluppo unrsquoapplicazioneche memorizza i dati nel ZODB
Introduzione
Diamo unrsquoocchiata a un semplice pezzo di codice che vogliamo modificare per poter utilizzare lo ZODB
22 ZODB - un database nativo ad oggetti per Python 151
Documentazione di Plone Release 4
class Account(object)def __init__(self)
selfbalance = 00
def deposit(self amount)selfbalance += amount
def cash(self amount)assert amount lt selfbalanceselfbalance -= amount
Questo codice definisce una semplice classe che mantiene il saldo di un conto bancario e fornisce due metodi permanipolare il saldo deposito e prelievo di contanti
Installazione
Prima di poter utilizzare lo ZODB dobbiamo installarlo usando easy_install Notare che il vero nome del pacchetto egraveldquoZODB3rdquo
$ easy_install ZODB3$ pythongtgtgt import ZODB
Ora lo ZODB egrave ora installato e puograve essere importato dalla vostra installazione Python
Se non si ha a disposizione easy_install sul proprio sistema seguire le Istruzioni per lrsquoinstallazione diEasyInstall
Ci sono altri meccanismi di installazione disponibili per gestire il lrsquoinstallazione dei pacchetti PythonQuesto tutorial assume che si stia utilizzando unrsquoinstallazione base di Python e che lo ZODB sia installatoglobalmente
Configurazione
Quando un programma vuole utilizzare lo ZODB deve stabilire una connessione come per qualsiasi altro databasePer lo ZODB abbiamo bisogno di 3 diverse parti uno storage un database e infine una connessione
gtgtgt from ZODBFileStorage import FileStoragegtgtgt from ZODBDB import DBgtgtgt storage = FileStorage(Datafs)gtgtgt db = DB(storage)gtgtgt connection = dbopen()gtgtgt root = connectionroot()
Creiamo un storage chiamato Filestorage che egrave lrsquoattuale standard di memorizzazione usato praticamente da tutti Essotiene traccia di tutti i dati in un singolo file come dichiarato dal primo parametro Da questo storage creiamo undatabase e poi apriamo una connessione Infine recuperiamo lrsquooggetto root del database attraverso la connessione cheabbiamo aperto
Memorizzare gli oggetti
Per memorizzare un oggetto nello ZODB lo colleghiamo semplicemente a qualsiasi altro oggetto che egrave giagrave presentenel database Quindi lrsquooggetto root funziona come un punto di partenza Lrsquooggetto root egrave un dizionario e si puograveiniziare a memorizzare gli oggetti direttamente da ligrave
152 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt root[account-1] = Account()gtgtgt root[account-2] = Account()
I framework come Zope creano solamente un singolo oggetto nella radice dello ZODB che rappresenta lrsquoapplicazionestessa e poi referenziano tutti gli altri oggetti da ligrave Essi scelgono nomi come lsquoapprsquo per il primo oggetto che posizionanonello ZODB
Transazioni
Ora abbiamo due oggetti posizionati nel oggetto root e nel nostro database Tuttavia essi non sono ancora memorizzatiin modo persistente Lo ZODB utilizza le transazioni e per rendere permanenti le modifiche egrave quindi necessario ilcommit della transazione
gtgtgt import transactiongtgtgt transactioncommit()gtgtgt rootkeys()[account-1 account-2]
Ora possiamo stoppare e riavviare lrsquoapplicazione e guardare di nuovo allrsquooggetto root Vedremo che le voci lsquoaccount-1rsquoe lsquoaccount-2rsquo sono ancora presenti e sono gli oggetti che abbiamo creato
Gli oggetti che non sono ancora stati memorizzati nello ZODB non vengono rimossi da un abort
Se lrsquoapplicazione apporta delle modifiche durante una transazione ma scopre che non vuole fare il commit di quellemodifiche allora si puograve annullare la transazione e le modifiche vengono annullate per noi
gtgtgt del root[account-1]gtgtgt rootkeys()[account-2]gtgtgt transactionabort()gtgtgt rootkeys()[account-1 account-2]
Oggetti persistenti
Un ultimo aspetto che dobbiamo coprire sono gli stessi oggetti persistenti Lo ZODB saragrave lieto di memorizzare quasiqualsiasi oggetto Python che gli viene passato (ma non memorizzeragrave i file per esempio) Ma per capire quali oggettisono stati modificati lo ZODB ha bisogno che quegli oggetti collaborino con il database In generale per fare ciogravebasta ereditare da persistentPersistent Quindi la nostra classe di esempio sopra andrebbe modificata cosigrave
import persistent
class Account(persistentPersistent) same code as above
Date unrsquoocchiata alla documentazione di riferimento per saperne di piugrave sulle regole di persistenza e sugli oggettispecializzati come i BTrees
Sommario
Abbiamo visto come installare lo ZODB come aprire un database nella nostra applicazione e come iniziare a mem-orizzare gli oggetti al suo interno Abbiamo anche accennato ai due semplici comandi per le transazioni commit eabort La documentazione di riferimento contiene le sezione con maggiori informazioni sugli specifici argomenti
22 ZODB - un database nativo ad oggetti per Python 153
Documentazione di Plone Release 4
Guida alla programmazione dello ZODB
Questa guida si basa in gran parte sul lavoro di AM Kuchling che scrisse la guida originale nel 2002 e che fu pubblicatasotto la GNU Free Documentation License Versione 11 Vedere lrsquoappendice intitolata ldquoGNU Free DocumentationLicenserdquo per ulteriori informazioni
Contenuti
Introduzione Questa guida spiega come scrivere programmi Python che utilizzano Z Object Database(ZODB) e Zope Enterprise Objects (ZEO) Lrsquoultima versione di questa guida egrave sempre disponibile suhttpwwwzopeorgWikisZODBguideindexhtml
Cosrsquoegrave lo ZODB Lo ZODB egrave un sistema di persistenza di oggetti Python I linguaggi di programmazione persistentiforniscono strutture che scrivono automaticamente gli oggetti sul disco e li rileggono quando sono richiesti durantelrsquoesecuzione del programma Installando lo ZODB abbiamo aggiunto queste strutture a Python
Certamente egrave possibile costruire un proprio sistema per rendere gli oggetti Python persistenti Il punto iniziale disolito egrave il modulo pickle per convertire gli oggetti in una rappresentazione di stringa e vari moduli per i databasecome i moduli gdbm o bsddb che forniscono dei modi per scrivere queste stringe sul disco e rileggerle Egrave semplicecombinare il modulo pickle e un modulo per i database per memorizzare e recuperare gli oggetti e in effetti ilmodulo shelve incluso nella libreria standard di Python fagrave proprio questo
Lo svantaggio egrave che il programmatore deve gestire in modo esplicito gli oggetti la loro lettura quando egrave necessarioe la loro scrittura su disco quando non sono piugrave richiesti Lo ZODB gestisce gli oggetti per noi scrivendoli su discoquando vengono modificati e rimuovendoli dalla cache quando non vengono utilizzati per qualche tempo
OODBs vs DB Relazionali Un altro modo di vedere le cose egrave che lo ZODB egrave un database orientato agli oggettispecifico per Python (OODB) I database ad oggetti commerciali per C++ e Java spesso richiedono di saltare attraversoalcuni cerchi come dover utilizzare uno speciale preprocessor o essere costretti ad evitare certi tipi di dati Comevedremo anche lo ZODB ha alcuni cerchi da saltare ma in confronto la naturalezza dello ZODB egrave stupefacente
I database relazionali (RDB) sono molto piugrave diffusi degli OODBs I database relazionali memorizzano le informazioniin tabelle una tabella egrave costituita da un numero qualsiasi di righe e ogni riga contiene diverse colonne di informazioni(Le righe sono piugrave formalmente chiamate relazioni che egrave dove il termine ldquodatabase relazionalerdquo ha origine)
Diamo unrsquoocchiata a un esempio concreto Lrsquoesempio viene dal mio lavoro di giorno per la Borsa MEMS in unaversione molto semplificata Il lavoro egrave quello di tracciare le esecuzioni di processi che sono liste di fasi di produzioneda eseguire in un semiconduttore fab Unrsquoesecuzione appartiene ad un particolare utente e ha un nome e un numeroID assegnato Le esecuzioni consistono in un numero di operazioni unrsquooperazione egrave un singolo passo da eseguirecome depositare qualcosa su un wafer o incidere qualcosa su di esso
Le operazioni possono avere dei parametri i quali sono le informazioni aggiuntive richieste per eseguireunrsquooperazione Per esempio se si sta depositando qualcosa su un wafer avrete bisogno di sapere due cose 1) cosasi sta depositando e 2) quanto se ne dovrebbe depositare Si potrebbe depositare 100 micron di ossido di silicio o 1micron di rame
Mappare queste strutture in un database relazionale egrave semplice
CREATE TABLE runs (int run_idvarchar ownervarchar titleint acct_numprimary key(run_id)
)
154 Chapter 2 Altri manuali
Documentazione di Plone Release 4
CREATE TABLE operations (int run_idint step_numvarchar process_idPRIMARY KEY(run_id step_num)FOREIGN KEY(run_id) REFERENCES runs(run_id)
)
CREATE TABLE parameters (int run_idint step_numvarchar param_namevarchar param_valuePRIMARY KEY(run_id step_num param_name)FOREIGN KEY(run_id step_num)
REFERENCES operations(run_id step_num))
In Python si dovrebbero scrivere tre classi denominate Run Operation e Parameter Non illustrerograve il codiceper definire queste classi poicheacute non sarebbe interessante a questo punto Ogni classe dovrebbe avere un singolometodo con cui inizializzarle un metodo __init__() che assegna i valori di default come 0 o None ad ogniattributo della classe
Non egrave difficile scrivere codice Python che crea una istanza Run e la valorizza con i dati presi dalletabelle relazionali con poco sforzo in piugrave si potrebbe costruire un semplice tool normalmente chiamatoobject-relational mapper (mappatore oggetto-relazione) per svolgere questo compito automaticamente (Vederehttpwwwamkcapythonunmaintainedordbhtml per un trucchetto veloce sui Python object-relational mapper evedere httpwwwpythonorgworkshops1997-10proceedingsshprentzhtml per lrsquoimplementazione piugrave efficace diJoel Shprentz della stessa idea A differenza del mio il sistema di Shprentz egrave stato utilizzato realmente per un lavoro)
Tuttavia egrave difficile rendere un object-relational mapper ragionevolmente veloce unrsquoimplementazione da sempliciottocome la mia egrave abbastanza lenta percheacute deve fare molte query per accedere a tutti i dati di un oggetto Gli object-relational mappers a maggiori prestazioni utilizzano delle cache di oggetti per migliorare le performance eseguendole query SQL solo quando veramente necessario
Questo egrave utile se si vuole accedere allrsquoimprovviso allrsquooperazione 123 Ma cosa succede se si vuole trovare tutte leoperazioni dove uno step ha un parametro chiamato lsquothicknessrsquo con valore uguale a 20 Nella versione relazionale sihanno due scelte poco attraenti
1 scrivere una query SQL specializzata per questo caso SELECT run_id FROM operations WHEREparam_name = rsquothicknessrsquo AND param_value = 20
Se tali query sono comuni si potrebbe finire per avere moltissime query specializzate Se le tabelle del databasedovessero venire modificate tutte queste query andrebbero riscritte
2 un object-relational mapper non aiuta molto Scansionare attraverso le operazioni significa che il mapper deveeseguire le query SQL richieste per leggere lrsquooperazione 1 e poi un semplice ciclo Python dovrebbe verificarese qualcuno dei suoi step ha il parametro che stiamo cercando Ripetere il tutto per lrsquooperazione 2 3 e cosigravevia Questo comporta un enorme numero di query SQL e quindi egrave incredibilmente lento
Un database ad oggetti come lo ZODB semplicemente memorizza dei puntatori interni da oggetto a oggetto per cuila lettura in un unico oggetto egrave molto piugrave veloce che fare un mucchio di query SQL e assemblare i risultati Quindiscansionare tutte le operazioni egrave ancora inefficiente ma non esageratamente inefficiente
Cosrsquoegrave lo ZEO Lo ZODB viene fornito con diverse classi che implementano lrsquointerfaccia Storage Tali classisono incaricate di gestire il lavoro di scrittura degli oggetti Python in un supporto fisico di archiviazione che puograveessere un file sul disco (la classe FileStorage) un file BerkeleyDB (BDBFullStorage) un database relazionale(DCOracleStorage) o qualche altro tipo di supporto ZEO aggiunge ClientStorage un nuovo Storage che
22 ZODB - un database nativo ad oggetti per Python 155
Documentazione di Plone Release 4
non scrive su un supporto fisico ma semplicemente inoltra tutte le richieste attraverso la rete ad un server Il server chesta eseguendo unrsquoistanza della classe StorageServer semplicemente si comporta come un front-end per qualcheclasse fisica Storage Lrsquoidea egrave abbastanza semplice ma come vedremo in seguito in questo documento apre moltepossibilitagrave
A proposito di questa guida Lrsquoautore principale di questa guida lavora su un progetto che utilizza lo ZODB eZEO come sua tecnologia principale di storage Usiamo il ZODB per memorizzare le esecuzioni di processi e leoperazioni un catalogo di processi disponibili informazioni sugli utenti informazioni di contabilitagrave e altri dati Partedellrsquoobbiettivo di scrivere questo documento egrave rendere la nostra esperienza piugrave ampiamente disponibile Qualche voltaabbiamo speso ore e persino giorni cercando di capire un problema e questa guida egrave un tentativo di raccogliere laconoscenza che abbiamo acquisito in modo che altri non debbano rifare gli stessi errori che abbiamo fatto noi durantelrsquoapprendimento
Il progetto ZODB dellrsquoautore egrave descritto in un articolo disponibile qui httpwwwamkcapythonwritingmx-architecture
Questo documento saragrave sempre un work in progress Se volete suggerire chiarimenti o altri argomenti si prega diinviare i commenti a ZODB- devzopeorg
Riconoscimenti Andrew Kuchling ha scritto la versione originale di questa guida che ha fornito una tra le primedocumentazioni sullo ZODB ai programmatori Python La sua versione iniziale egrave stato aggiornato nel tempo daJeremy Hylton e Tim Peters
Vorrei ringraziare le persone che hanno segnalato imprecisioni e bug che hanno offerto suggerimenti sul testo oproposto nuovi argomenti da coprire Jeff Bauer Willem Broekema Thomas Guettler Chris McDonough GeorgeRunyan
Programmazione dello ZODB
Installare lo ZODB Lo ZODB egrave pacchettizzato utilizzando gli strumenti standard distutils
Requisiti Avrete bisogno di Python 23 o superiore Dal momento che il codice egrave pacchettizzato utilizzando distutilsegrave semplicemente questione di scompattare il pacchetto rilasciato e poi lanciare il comando python setuppyinstall
Avrete bisogno di un compilatore C per compilare i pacchetti percheacute ci sono vari moduli di estensione scritti in C Pergli utenti Windows sono disponibili gli installer dei binari
Installare i pacchetti Scaricate il tarball ZODB contenente tutti i pacchetti sia per ZODB sia per ZEO dahttpwwwzopeorgProductsZODB33 Vedere il file READMEtxt nel livello superiore delle directory per i det-tagli su come compilare testare e installare
Egrave possibile trovare informazioni su ZODB e le versioni piugrave recenti dello ZODB nel Wiki suhttpwwwzopeorgWikisZODB
Come funziona lo ZODB Lo ZODB egrave concettualmente semplice Le classi Python ereditano da una classepersistentPersistent per diventare ZODB-compatibili Le istanze di oggetti persistenti vengono caricatida un supporto di memorizzazione permanente come un file su disco quando il programma ha bisogno di loro e ri-mangono nella cache in RAM Lo ZODB intercetta le modifiche agli oggetti in modo che quando uno statement comeobjsize =1 viene eseguito lrsquooggetto modificato viene segnato come ldquodirtyrdquo (sporco) A richiesta ogni oggetto
156 Chapter 2 Altri manuali
Documentazione di Plone Release 4
sporco viene scritto sullo storage permanente questo egrave chiamato committing di una transazione Le transazioni pos-sono anche essere annullate e ripristinate il che scarta tutte le modifiche e gli oggetti sporchi vengono ripristinati alloro stato iniziale prima dellrsquoinizio della transazione
Il termine ldquotransazionerdquo ha uno specifico significato tecnico nella computer science Egrave estremamente importante chei contenuti di un database non vengano corrotti da fallimenti hardware o software e la maggior parte dei databaseoffrono protezione contro tali tipi di corruzioni supportando 4 utili proprietagrave Atomicitagrave Consistenza Isolamento eDurabilitagrave Nel gergo della computer science questi quattro termini sono chiamate collettivamente proprietagrave ACIDformando un acronimo con i loro nomi
Lo ZODB fornisce tutte le proprietagrave ACID Le definizioni delle proprietagrave ACID sono
Atomicitagrave significa che qualsiasi cambiamento ai dati fatto durante una transazione segue la regola del tutto-o-nienteO vengono applicate tutte le modifiche o nessuna di esse Se un programma fa un sacco di modifiche e poi vain crash il database non rimarragrave parzialmente modificato lasciando potenzialmente i dati in uno stato inconsis-tente al contrario tutte le modifiche verranno rimosse Ovviamente questo egrave un male ma egrave meglio che averedelle modifiche parzialmente applicate che mettano il database in uno stato inconsistente
Consistenza significa che ogni transazione esegue una trasformazione valida dello stato del database Alcunidatabase ma non lo ZODB forniscono una varietagrave di controlli di consistenza nel database o nel linguaggioper esempio un database relazionale costringe le colonne ad essere di un particolare tipo e puograve forzare dellerelazioni tra le tabelle Piugrave in generale lrsquoatomicitagrave e lrsquoisolamento rendono possibile alle applicazioni di fornirela consistenza
Isolamento significa che due programmi o thread in esecuzione in due diverse transazioni non possono vedere lemodifiche dellrsquoaltro fino a che non eseguono il commit delle loro transazioni
Durabilitagrave significa che una volta che una transazione egrave stata committata un fallimento successivo non causeragravenessuna perdita o corruzione dei dati
Apriamo uno ZODB There are 3 main interfaces supplied by the ZODB Storage DB and Connectionclasses The DB and Connection interfaces both have single implementations but there are several different classesthat implement the Storage interface
bull Storage classes are the lowest layer and handle storing and retrieving objects from some form of long-termstorage A few different types of Storage have been written such as FileStorage which uses regular diskfiles and BDBFullStorage which uses Sleepycat Softwarersquos BerkeleyDB database You could write a newStorage that stored objects in a relational database for example if that would better suit your application Twoexample storages DemoStorage and MappingStorage are available to use as models if you want to writea new Storage
bull The DB class sits on top of a storage and mediates the interaction between several connections One DB instanceis created per process
bull Finally the Connection class caches objects and moves them into and out of object storage A multi-threaded program should open a separate Connection instance for each thread Different threads can thenmodify objects and commit their modifications independently
Preparing to use a ZODB requires 3 steps you have to open the Storage then create a DB instance that uses theStorage and then get a Connection from the DB instance All this is only a few lines of code
from ZODB import FileStorage DB
storage = FileStorageFileStorage(tmptest-filestoragefs)db = DB(storage)conn = dbopen()
Note that you can use a completely different data storage mechanism by changing the first line that opens a Storagethe above example uses a FileStorage In section zeo ldquoHow ZEO Worksrdquo yoursquoll see how ZEO uses this flexibility
22 ZODB - un database nativo ad oggetti per Python 157
Documentazione di Plone Release 4
to good effect
Using a ZODB Configuration File ZODB also supports configuration files written in the ZConfig format A con-figuration file can be used to separate the configuration logic from the application logic The storages classes and theDB class support a variety of keyword arguments all these options can be specified in a config file
The configuration file is simple The example in the previous section could use the following example
ltzodbgtltfilestoragegtpath tmptest-filestoragefsltfilestoragegt
ltzodbgt
The ZODBconfig module includes several functions for opening database and storages from configuration files
import ZODBconfig
db = ZODBconfigdatabaseFromURL(tmptestconf)conn = dbopen()
The ZConfig documentation included in the ZODB3 release explains the format in detail Each configuration file isdescribed by a schema by convention stored in a componentxml file ZODB ZEO zLOG and zdaemon all haveschemas
Writing a Persistent Class Making a Python class persistent is quite simple it simply needs to subclass from thePersistent class as shown in this example
from persistent import Persistent
class User(Persistent)pass
The Persistent base class is a new-style class implemented in C
For simplicity in the examples the User class will simply be used as a holder for a bunch of attributes Normallythe class would define various methods that add functionality but that has no impact on the ZODBrsquos treatment of theclass
The ZODB uses persistence by reachability starting from a set of root objects all the attributes of those objects aremade persistent whether theyrsquore simple Python data types or class instances Therersquos no method to explicitly storeobjects in a ZODB database simply assign them as an attribute of an object or store them in a mapping thatrsquos alreadyin the database This chain of containment must eventually reach back to the root object of the database
As an example wersquoll create a simple database of users that allows retrieving a User object given the userrsquos ID Firstwe retrieve the primary root object of the ZODB using the root() method of the Connection instance The rootobject behaves like a Python dictionary so you can just add a new keyvalue pair for your applicationrsquos root objectWersquoll insert an OOBTree object that will contain all the User objects (The BTree module is also included as partof Zope)
dbroot = connroot()
Ensure that a userdb key is present in the rootif not dbroothas_key(userdb)
from BTreesOOBTree import OOBTreedbroot[userdb] = OOBTree()
158 Chapter 2 Altri manuali
Documentazione di Plone Release 4
userdb = dbroot[userdb]
Inserting a new user is simple create the User object fill it with data insert it into the BTree instance and committhis transaction
Create new User instanceimport transaction
newuser = User()
Add whatever attributes you want to tracknewuserid = amknewuserfirst_name = Andrew newuserlast_name = Kuchling
Add object to the BTree keyed on the IDuserdb[newuserid] = newuser
Commit the changetransactioncommit()
The transaction module defines a few top-level functions for working with transactions commit() writes anymodified objects to disk making the changes permanent abort() rolls back any changes that have been maderestoring the original state of the objects If yoursquore familiar with database transactional semantics this is all whatyoursquod expect get() returns a Transaction object that has additional methods like note() to add a note to thetransaction metadata
More precisely the transaction module exposes an instance of the ThreadTransactionManager transac-tion manager class as transactionmanager and the transaction functions get() and begin() redirectto the same-named methods of transactionmanager The commit() and abort() functions apply themethods of the same names to the Transaction object returned by transactionmanagerget() This isfor convenience Itrsquos also possible to create your own transaction manager instances and to tell DBopen() to useyour transaction manager instead
Because the integration with Python is so complete itrsquos a lot like having transactional semantics for your programrsquosvariables and you can experiment with transactions at the Python interpreterrsquos prompt
gtgtgt newuserltUser instance at 81b1f40gtgtgtgt newuserfirst_name Print initial valueAndrewgtgtgt newuserfirst_name = Bob Change first namegtgtgt newuserfirst_name Verify the changeBobgtgtgt transactionabort() Abort transactiongtgtgt newuserfirst_name The value has changed backAndrew
Rules for Writing Persistent Classes Practically all persistent languages impose some restrictions on programmingstyle warning against constructs they canrsquot handle or adding subtle semantic changes and the ZODB is no exceptionHappily the ZODBrsquos restrictions are fairly simple to understand and in practice it isnrsquot too painful to work aroundthem
The summary of rules is as follows
bull If you modify a mutable object thatrsquos the value of an objectrsquos attribute the ZODB canrsquot catch that and wonrsquotmark the object as dirty The solution is to either set the dirty bit yourself when you modify mutable objects or
22 ZODB - un database nativo ad oggetti per Python 159
Documentazione di Plone Release 4
use a wrapper for Pythonrsquos lists and dictionaries (PersistentList PersistentMapping) that will setthe dirty bit properly
bull Recent versions of the ZODB allow writing a class with __setattr__() __getattr__() or__delattr__() methods (Older versions didnrsquot support this at all) If you write such a __setattr__()or __delattr__() method its code has to set the dirty bit manually
bull A persistent class should not have a __del__() method The database moves objects freely between memoryand storage If an object has not been used in a while it may be released and its contents loaded from storagethe next time it is used Since the Python interpreter is unaware of persistence it would call __del__() eachtime the object was freed
Letrsquos look at each of these rules in detail
Modifying Mutable Objects The ZODB uses various Python hooks to catch attribute accesses and can trap most ofthe ways of modifying an object but not all of them If you modify a User object by assigning to one of its attributesas in userobjfirst_name = rsquoAndrewrsquo the ZODB will mark the object as having been changed and itrsquoll bewritten out on the following commit()
The most common idiom that isnrsquot caught by the ZODB is mutating a list or dictionary If User objects have a attributenamed friends containing a list calling userobjfriendsappend(otherUser) doesnrsquot mark userobjas modified from the ZODBrsquos point of view userobjfriends was only read and its value which happened tobe an ordinary Python list was returned The ZODB isnrsquot aware that the object returned was subsequently modified
This is one of the few quirks yoursquoll have to remember when using the ZODB if you modify a mutable attribute of anobject in place you have to manually mark the object as having been modified by setting its dirty bit to true This isdone by setting the _p_changed attribute of the object to true
userobjfriendsappend(otherUser)userobj_p_changed = True
You can hide the implementation detail of having to mark objects as dirty by designing your classrsquos API to not usedirect attribute access instead you can use the Java-style approach of accessor methods for everything and then setthe dirty bit within the accessor method For example you might forbid accessing the friends attribute directly andadd a get_friend_list() accessor and an add_friend() modifier method to the class add_friend()would then look like this
def add_friend(self friend)selffriendsappend(otherUser)self_p_changed = True
Alternatively you could use a ZODB-aware list or mapping type that handles the dirty bit for you The ZODB comeswith a PersistentMapping class and Irsquove contributed a PersistentList class thatrsquos included in my ZODBdistribution and may make it into a future upstream release of Zope
__getattr__() __delattr__() and __setattr__() ZODB allows persistent classes to have hookmethods like __getattr__() and __setattr__() There are four special methods that control attribute ac-cess the rules for each are a little different
The __getattr__() method works pretty much the same for persistent classes as it does for other classes Nospecial handling is needed If an object is a ghost then it will be activated before __getattr__() is called
The other methods are more delicate They will override the hooks provided by Persistent so user code must callspecial methods to invoke those hooks anyway
The __getattribute__() method will be called for all attribute access it overrides the attribute access sup-port inherited from Persistent A user-defined __getattribute__() must always give the Persistentbase class a chance to handle special attribute as well as __dict__ or __class__ The user code should call
160 Chapter 2 Altri manuali
Documentazione di Plone Release 4
_p_getattr() passing the name of the attribute as the only argument If it returns True the user code should callPersistentlsquos __getattribute__() to get the value If not the custom user code can run
A __setattr__() hook will also override the Persistent __setattr__() hook User code must treat itmuch like __getattribute__() The user-defined code must call _p_setattr() first to all Persistentto handle special attributes _p_setattr() takes the attribute name and value If it returns True Persistenthandled the attribute If not the user code can run If the user code modifies the objectrsquos state it must assigned to_p_changed
A __delattr__() hooks must be implemented the same was as a the last two hooks The user code must call_p_delattr() passing the name of the attribute as an argument If the call returns True Persistent handledthe attribute if not the user code can run
__del__() methods A __del__() method is invoked just before the memory occupied by an unreferencedPython object is freed Because ZODB may materialize and dematerialize a given persistent object in memory anynumber of times there isnrsquot a meaningful relationship between when a persistent objectrsquos __del__() method getsinvoked and any natural aspect of a persistent objectrsquos life cycle For example it is emphatically not the case that apersistent objectrsquos __del__() method gets invoked only when the object is no longer referenced by other objects inthe database __del__() is only concerned with reachability from objects in memory
Worse a __del__() method can interfere with the persistence machineryrsquos goals For example some number ofpersistent objects reside in a Connectionlsquos memory cache At various times to reduce memory burden objects thathavenrsquot been referenced recently are removed from the cache If a persistent object with a __del___() method is soremoved and the cache was holding the last memory reference to the object the objectrsquos __del__() method will beinvoked If the __del__() method then references any attribute of the object ZODB needs to load the object fromthe database again in order to satisfy the attribute reference This puts the object back into the cache again such anobject is effectively immortal occupying space in the memory cache forever as every attempt to remove it from cacheputs it back into the cache In ZODB versions prior to 322 this could even cause the cache reduction code to fall intoan infinite loop The infinite loop no longer occurs but such objects continue to live in the memory cache forever
Because __del__() methods donrsquot make good sense for persistent objects and can create problems persistentclasses should not define __del__() methods
Writing Persistent Classes Now that wersquove looked at the basics of programming using the ZODB wersquoll turn tosome more subtle tasks that are likely to come up for anyone using the ZODB in a production system
Changing Instance Attributes Ideally before making a class persistent you would get its interface right the firsttime so that no attributes would ever need to be added removed or have their interpretation change over time Itrsquosa worthy goal but also an impractical one unless yoursquore gifted with perfect knowledge of the future Such unnaturalforesight canrsquot be required of any person so you therefore have to be prepared to handle such structural changesgracefully In object-oriented database terminology this is a schema update The ZODB doesnrsquot have an actualschema specification but yoursquore changing the softwarersquos expectations of the data contained by an object so yoursquoreimplicitly changing the schema
One way to handle such a change is to write a one-time conversion program that will loop over every single object inthe database and update them to match the new schema This can be easy if your network of object references is quitestructured making it easy to find all the instances of the class being modified For example if all User objects can befound inside a single dictionary or BTree then it would be a simple matter to loop over every User instance with afor statement This is more difficult if your object graph is less structured if User objects can be found as attributesof any number of different class instances then therersquos no longer any easy way to find them all short of writing ageneralized object traversal function that would walk over every single object in a ZODB checking each one to see ifitrsquos an instance of User
Some OODBs support a feature called extents which allow quickly finding all the instances of a given class no matterwhere they are in the object graph unfortunately the ZODB doesnrsquot offer extents as a feature
22 ZODB - un database nativo ad oggetti per Python 161
Documentazione di Plone Release 4
Missing parts zeorst transactionsrst modulesrst linksrst gfdlrst
Bugs
Per riportare bug generici utilizzare Launchpad bug tracker
Tuttavia lo ZODB egrave stato in giro molto piugrave a lungo e quindi ci sono alcune risorse storiche per informazioni relativeai bug
bull il collettore Zope (con lrsquoargomento database) su httpcollectorzopeorgCollectorsZope
bull il tracciatore di bug di ZODB su sourceforge (molto piugrave vecchio) suhttpsourceforgenettrackergroup_id=15628ampatid=115628
Feature requests
Le richieste di funzionalitagrave sono attualmente gestite un pograve ad-hoc Sentitevi liberi di scrivere un post sulla mailing listchiedendo di una funzionalitagrave e - se non si vuole venire dimenticati - aggiungere un blueprint in Launchpad
Inoltre in precedenza eravamo soliti gestire le proposte sul nostro vecchio wiki suhttpwikizopeorgZODBListOfProposalscontentsListOfProposals
bull Lo ZODB Book (in corso di stesura)
223 Downloads
Lo ZODB egrave distribuito come egg Python attraverso il Python Package Index
Egrave possibile installare lrsquoegg con il comando easy_install di setuptools
$ easy_install ZODB3
224 La communitagrave e i contributi
Le discussioni avvengono sulla mailing list degli sviluppatori ZODB
Le segnalazioni di bug le richieste di funzionalitagrave e i piani di rilascio sono fatti su Launchpad
Se desideri contribuire saremo lieti di accettare qualsiasi lavoro di documentazione aiuto agli altri sviluppatori e agliutenti della mailing list segnalazione di bug proposta o scrittura di codice
ZODB egrave un progetto gestito dalla Fondazione Zope in modo da poter ottenere lrsquoaccesso in scrittura per contribuiredirettamente - leggi le informazioni per gli sviluppatori della fondazione Zope
23 La guida completa alla Zope Component Architecture
Autore Baiju M
Versione 058
Libro stampato httpwwwlulucomcontent1561045
Online PDF (en) httpwwwmuthukadannetdocszcapdf
Traduttore Giacomo Spettoli ltgiacomospettoligmailcomgt
162 Chapter 2 Altri manuali
Documentazione di Plone Release 4
Copyright (C) 200720082009 Baiju M ltbaijummail AT gmailcomgt
Egrave permessa la copia la ridistribuzione eo la modifica di questo documento secondo i termini della laquoGNU Free Docu-mentation Licenceraquo versione 13 o versioni successive pubblicate dalla Free Software Foundation
Il codice presente in questo documento egrave soggetto alle condizioni della laquoZope Public Licenceraquo versione 21 (ZPL)
THE SOURCE CODE IN THIS DOCUMENT AND THE DOCUMENT ITSELF IS PROVIDED ldquoAS ISrdquo AND ANYAND ALL EXPRESS OR IMPLIED WARRANTIES ARE DISCLAIMED INCLUDING BUT NOT LIMITED TOTHE IMPLIED WARRANTIES OF TITLE MERCHANTABILITY AGAINST INFRINGEMENT AND FITNESSFOR A PARTICULAR PURPOSE
Ringraziamenti
Molte persone mi hanno aiutato nella stesura di questo libro La bozza iniziale fu revisionata dal mio collegaBrad Allen Quando annunciai questo libro attraverso il mio blog ricevetti molti commenti di incoraggia-mento a procedere con questo lavoro Kent Tenney modificograve numerose parti di questo libro e riscrisse anchelrsquoapplicazione di esempio Molti altri mi hanno inviato correzioni e commenti inclusi Lorenzo Gil SanchezMichael Haubenwallner Nando Quintana Stephane Klein Tim Cook Kamal Gill and Thomas Herve Lorenzoha tradotto questo lavoro in Spagnolo e Stephane in Francese Grazie a tutti
231 Come iniziare
Introduzione
Sviluppare un sistema software di grandi dimensioni egrave sempre molto complicato Egrave stato dimostrato che quando sitratta di grandi sistemi un buon approccio allrsquoanalisi al design e alla programmazione egrave dato dalla programmazioneorientata agli oggetti Il design basato sui componenti e la programmazione a componenti stanno diventando moltopopolari in questi giorni Lrsquoapproccio basato sui componenti aiuta a scrivere e a mantenere facilmente testabili conunit-test i sistemi software Ci sono molti framework per il supporto al design a componenti in diversi linguaggialcuni sono persino indipendenti dal linguaggio Due esempi sono il COM della Microsoft e XPCOM di Mozilla
La Zope Component Architecture (ZCA) egrave un framework Python per il supporto al design e alla programmazionebasati sui componenti Essa egrave molto adatta allo sviluppo di sistemi software di grandi dimensioni scritti in Python LaZCA non egrave specifica per il web application server Zope puograve essere utilizzata per qualsiasi applicazione Python Forsedovrebbe essere chiamata Python Component Architecture
La ZCA tratta principalmente lrsquoutilizzo efficace degli oggetti Python I componenti sono oggetti riutilizzabili coninterfacce introspezionabili Un interfaccia egrave un oggetto che descrive come interagire con un particolare componenteIn altre parole un componente fornisce un interfaccia implementata in una classe (o in qualsiasi altro oggetto chiama-bile) Non egrave tanto importante come un oggetto venga implementato lrsquoimportante egrave che esso aderisca al contratto dellasua interfaccia Utilizzando la ZCA egrave possibile suddividere la complessitagrave di un sistema su molteplici componenti checooperano tra loro Essa aiuta a creare due principali tipi di componenti gli adapter e le utility
I tre pacchetti principali che compongono la ZCA sono
bull zopeinterface viene utilizzato per definire lrsquointerfaccia di un componente
bull zopeevent fornisce un semplice sistema di eventi
bull zopecomponent si occupa della creazione della registratione e del recupero dei componenti
Notare che la ZCA non egrave un insieme di componenti ma piugrave propriamente serve a creare registrare e recuperare icomponenti Egrave bene ricordare inoltre che un adapter egrave una normale classe Python (o piugrave in generale una factory) e unautility egrave un normale oggetto chiamabile Python
23 La guida completa alla Zope Component Architecture 163
Documentazione di Plone Release 4
Il framework ZCA fu sviluppato come parte del progetto Zope3 Come giagrave anticipato egrave un framework scritto esclu-sivamente in Python cosigrave da poter essere utilizzato da qualsiasi tipo di applicazione Python Attualmente i progettiZope3 Zope2 e Grok utilizzano questo framework in maniera massiccia Ci sono molti altri progetti che la utilizzanoinclusi progetti non legati al web 1
Breve storia
Il progetto del framework ZCA iniziograve nel 2011 come parte del progetto Zope3 Venne sviluppato basandosi sullelezioni imparate durante lo sviluppo di grandi sistemi software utilizzando Zope2 Jim Fulton fu il project leaderdi questo progetto Molte persone contribuirono al design e allrsquoimplementazione inclusi ma non limitati a StephanRichter Philipp von Weitershausen Guido van Rossum (aka Python BDFL) Tres Seaver Phillip J Eby and MartijnFaassen
Inizialmente la ZCA definiva dei componenti aggiuntivi services e views ma gli sviluppatori arrivarono alla conclu-sione che le utility potevano rimpiazzare i service e i multi-adapter potevano rimpiazzare le view Oggi la ZCA ha unnumero molto ridotto di tipi di componenti principali utility adapter subscriber e handler In effetti i subscriber egli handler sono due particolari tipi di adapter
Durante il ciclo di sviluppo di Zope32 Jim Fulton propose una grande semplificazione della ZCA 2 Con questasemplificazione fu creata una nuova singola interfaccia (IComponentRegistry) per la registrazione di componenti sialocali sia globali
Il pacchetto zopecomponent ha una lunga lista di dipendenze molte delle quali non erano necessarie per appli-cazioni non basate su Zope3 Durante il PyCon2007 Jim Fulton aggiunse a setuptools la funzionalitagrave extras_requireper permettere di separare il nucleo della ZCA dalle funzionalitagrave aggiuntive 3
Nel marzo del 2009 Tres Seaver rimosse poi le dipendenze da zopedeferredimport e zopeproxy
Oggi il progetto ZCA egrave un progetto indipendente con il proprio ciclo di rilasci e il proprio repository SubversionQuesto progetto sta diventando parte del piugrave grande progetto del framework Zope 4 In ogni caso le segnalazioni e ibug sono ancora tracciati come parte del progetto Zope3 5 e la mailing list principale zope-dev viene utilizzata per lediscussioni sullo sviluppo 6 Crsquoegrave anche unrsquoaltra user-list generica per Zope3 (zope3-users) che puograve essere utilizzataper qualsiasi domanda sulla ZCA 7
Installazione
Il pacchetto zopecomponent insieme ai pacchetti zopeinterface e zopeevent costituiscono il nucleodella Zope Component architecture Essi forniscono le strutture per definire registrare e recuperare i componenti Ilpacchetto zopecomponent e le sue dipendenze sono disponibili in formato egg sul Python Package Index (PyPI)8
Egrave possibile installare zopecomponent e le sue dipendenze utilizzando easy_install 9
$ easy_install zopecomponent
Questo comando scarica zopecomponent e le sue dipendenze da PyPI e installa il tutto nel vostro Python path
1 httpwikizopeorgzope3ComponentArchitecture2 httpwikizopeorgzope3LocalComponentManagementSimplification3 httppeaktelecommunitycomDevCentersetuptoolsdeclaring-dependencies4 httpdocszopeorgzopeframework5 httpsbugslaunchpadnetzope36 httpmailzopeorgmailmanlistinfozope-dev7 httpmailzopeorgmailmanlistinfozope3-users8 Repository dei pacchetti Python httppypipythonorgpypi9 httppeaktelecommunitycomDevCenterEasyInstall
164 Chapter 2 Altri manuali
Documentazione di Plone Release 4
In alternativa egrave possibile scaricare zopecomponent e le sue dipendenze da PyPI e poi installarle Instal-lare i pacchetti nellrsquoordine indicato sotto Su sistemi Windows potrebbero essere necessari i paccheti binari dizopeinterface
1 zopeinterface
2 zopeevent
3 zopecomponent
Per installare questi pacchetti dopo averli scaricati egrave possibile usare il comando easy_install con gli eggs comeargomento (egrave possibile passare tutti gli egg come argomenti sulla stessa linea)
$ easy_install pathtozopeinterface-3xxtargz$ easy_install pathtozopeevent-3xxtargz$ easy_install pathtozopecomponent-3xxtargz
Egrave anche possibile installare questi pacchetti dopo averli estratti singolarmente Ad esempio
$ tar zxvf pathtozopeinterface-3xxtargz$ cd zopeinterface-3xx$ python setuppy build$ python setuppy install
Questi metodi installano la ZCA sul Python di sistema nella cartella site-packages ma questo potrebbe creareproblemi In un post sulla mailing list di Zope3 Jim Fulton sconsiglia lrsquoutilizzo del Python di sistema 10 In alternativasi puograve utilizzare virtualenv eo zcbuildout per installare qualsiasi pacchetto Python Questo metodo egrave adattoanche per il deploy
Come provare il codice
In Python ci sono due approcci per la configurazione di ambienti di lavoro isolati per lo sviluppo di applicazioni Ilprimo egrave virtualenv creato da Ian Biking e lrsquoaltro egrave zcbuildout creato da Jim Fulton Egrave anche possibile utilizzare questidue pacchetti insieme Con questi pacchetti egrave possibile installare zopecomponent e le altre dipendenze in unambiente di lavoro isolato Queste sono le buone pratiche per la sperimentazione di codice Python e familiarizzarecon questi strumenti torneragrave utile quando si vorragrave sviluppare e fare il deploy delle proprie applicazioni
virtualenv
Si puograve installare virtualenv utilizzando easy_install
$ easy_install virtualenv
Poi si puograve creare un nuovo ambiente in questo modo
$ virtualenv --no-site-packages myve
Questo comando crea un nuovo ambiente virtuale nella cartella myve Ora dallrsquointerno della cartella myve egrave possibileinstallare zopecomponent e le sue dipendenze utilizzando il comando easy_install che si trova dentro alla cartellamyvebin
$ cd myve$ bineasy_install zopecomponent
Ora egrave possibile importare zopeinterface e zopecomponent dal vostro nuovo interprete python disponibiledentro alla cartella myvebin
10 httparticlegmaneorggmanecompwebzopezope321045
23 La guida completa alla Zope Component Architecture 165
Documentazione di Plone Release 4
$ binpython
Questo comando fornisce un prompt Python che puograve essere utilizzato per eseguire il codice di questo libro
zcbuildout
Utilizzando zcbuildout con la ricetta zcrecipeegg egrave possibile creare un interprete Python che ha a dispo-sizione gli eggs specificati Per prima cosa installare zcbuildout utilizzando il comando easy_install (egrave possibilefarlo anche dentro allrsquoambiente virtuale) Per creare un nuovo buildout per fare esperimenti con gli egg Python perprima cosa creare una cartella e inizializzarla utilizzando il comando buildout init
$ mkdir mybuildout$ cd mybuildout$ buildout init
Ora la nuova cartella buildout egrave un buildout Il file di configurazione di default per il buildout egrave buildoutcfg Dopolrsquoinizializzazione avragrave questo contenuto
[buildout]parts =
Cambiamolo cosigrave
[buildout]parts = py
[py]recipe = zcrecipeegginterpreter = pythoneggs = zopecomponent
Ora lanciamo il comando buildout disponibile dentro alla cartella mybuildoutbin senza argomenti Questo crea unnuovo interprete Python dentro alla cartella mybuildoutbin
$ binbuildout$ binpython
Questo comando faragrave apparire un prompt Python che puograve essere utilizzato per eseguire il codice di questo libro
232 Un esempio
Introduzione
Consideriamo come esempio unrsquoapplicazione commerciale per la registrazione degli ospiti di un hotel Python puograveimplementare questa applicazione in vari modi Inizieremo dando una breve occhiata ad una possibile implemen-tazione procedurale e poi ci sposteremo verso un semplice approccio orientato agli oggetti Mentre esamineremolrsquoapproccio orientato agli oggetti vedremo come potremo trarre beneficio dai pattern di design classici adapter einterface Questo ci porteragrave nel mondo della Zope Component Architecture
Approccio procedurale
In qualsiasi applicazione commerciale una delle parti principali egrave la conservazione dei dati Per semplicitagrave in questoesempio utilizzeremo un dizionario Python come sistema di storage Creeremo degli id univoci per il dizionario e ilvalore associato ad ogni chiave saragrave a sua volta un dizionario con i dettagli della prenotazione
166 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt bookings_db = key unique Id value details in a dictionary
Unrsquoimplementazione minimale richiede una funzione che verifichi i dettagli della prenotazione e una funzione disupporto che fornisca gli id univoci per le chiavi del dizionario di storage
Possiamo generare un id univoco in questo modo
gtgtgt def get_next_id() db_keys = bookings_dbkeys() if db_keys == [] next_id = 1 else next_id = max(db_keys) + 1 return next_id
Come si puograve notare lrsquoimplementazione della funzione get_next_id egrave molto semplice La funzione prende una lista dichiavi e controlla una lista vuota Se la lista egrave vuota questa egrave la nostra prima prenotazione quindi restituiamo 1 Se lalista non egrave vuota aggiungiamo 1 al valore massimo della lista e lo restituiamo
Ora utilizzeremo la funzione sopra per inserire degli elementi nel dizionario bookings_db
gtgtgt def book_room(name place) next_id = get_next_id() bookings_db[next_id] = name name room place
Unrsquoapplicazione per la gestione delle prenotazioni di un hotel ha bisogno di dati supplementari
bull numero di telefono
bull opzioni della camera
bull metodo di pagamento
bull
e ha bisogno di codice per la gestione dei dati
bull cancellare una prenotazione
bull aggiornare una prenotazione
bull pagare una stanza
bull rendere i dati persistenti
bull assicurare la sicurezza dei dati
bull
Se dovessimo continuare con lrsquoesempio procedurale dovremmo creare molte funzioni e dovremmo passare i datiavanti e indietro tra di loro Man mano che i requisiti cambiano o aumentano il codice diventa sempre piugrave difficile damanutenere e i bug diventano piugrave difficili da correggere
Possiamo terminare qui la nostra discussione sullrsquoapproccio procedurale poichegrave saragrave molto piugrave facile fornire la persis-tenza dei dati la flessibilitagrave di design e la testabilitagrave del codice utilizzando gli oggetti
Approccio orientato agli oggetti
La nostra discussione sul design orientato agli oggetti ci porta a introdurre la classe La classe serve ad incapsulare idati e il codice per gestirli
23 La guida completa alla Zope Component Architecture 167
Documentazione di Plone Release 4
La classe principale saragrave il FrontDesk La classe FrontDesk o verso cui delegheragrave la gestione sapragrave come gestire idati dellrsquohotel Andremo a creare delle istanze di FrontDesk per applicare questa conoscenza al mestiere di gestire unhotel
Lrsquoesperienza ha mostrato che incapsulare il codice e i dati attraverso gli oggetti porta ad un design piugrave facile dacomprenderetestare e modificare
Vediamo i dettagli dellrsquoimplementazione di una classe FrontDesk
gtgtgt class FrontDesk(object) def book_room(self name place) next_id = get_next_id() bookings_db[next_id] = name name place place
In questa implementazione lrsquooggetto frontdesk (istanza della classe FrontDesk) egrave in grado di gestire le prenotazioniPossiamo usare questa classe cosigrave
gtgtgt frontdesk = FrontDesk()gtgtgt frontdeskbook_room(Jack Bangalore)
Qualsiasi progetto reale saragrave soggetto a cambiamenti nei requisiti In questo caso la gestione dellrsquohotel ha deciso cheogni ospite deve fornire anche un numero di telefono quindi siamo costretti a cambiare il codice
Possiamo raggiungere questo requisito aggiungendo un argomento al metodo book_room che verragrave aggiunto aldizionario dei valori
gtgtgt class FrontDesk(object) def book_room(self name place phone) next_id = get_next_id() bookings_db[next_id] = name name place place phone phone
Oltre a migrare i dati verso il nuovo schema ora dobbiamo anche cambiare le chiamate a FrontDesk Se perograve noiastraiamo i dettagli dellrsquoospite in un oggetto e lo usiamo per la registrazione i cambiamenti al codice vengono mini-mizzati Cosigrave possiamo applicare i cambiamenti ai dettagli dellrsquoospite e le chiamate a FrontDesk non avranno bisognodi cambiamenti
Cosigrave abbiamo
gtgtgt class FrontDesk(object) def book_room(self guest) next_id = get_next_id() bookings_db[next_id] = name guestname place guestplace phone guestphone
Dobbiamo ancora cambiare il codice per rispondere ai cambiamenti dei requisiti Sebbene questo sia inevitabile ilnostro obiettivo egrave quello di minimizzare questi cambiamenti in modo da aumentare la manutenibilitagrave
168 Chapter 2 Altri manuali
Documentazione di Plone Release 4
Note Quando si aggiunge del codice egrave importante sentirsi liberi di apportare i cambiamenti senza paura di romperelrsquoapplicazione Il modo per avere i riscontri richiesti immediatamente egrave usare i test automatizzati Con dei test benscritti (e un buon sistema di controllo di versione) egrave possibile fare cambiamenti piccoli o grandi senza conseguenzeUna buona fonte di informazioni sulla filosofia della programmazione egrave il libro Extreme Programming Explained diKent Beck
Con lrsquointroduzione dellrsquooggetto ospite abbiamo risparmiato un pograve di scrittura di codice e cosa ancora piugrave importantelrsquoastrazione fornita dallrsquooggetto ospite ha reso il sistema piugrave semplice e piugrave comprensibile Come risultato il codice egravepiugrave facile da ri-fattorizzare e da mantenere
Il pattern adapter
Nelle applicazioni reali lrsquooggetto frontdesk dovrebbe eseguire compiti come la cancellazione e lrsquoaggiornamento delleprenotazioni Nel design attuale dobbiamo passare lrsquooggetto ospite al frontdesk ogni volta che chiamiamo metodicome cancel_booking e update_booking
Possiamo evitare facilmente questo vincolo se passiamo lrsquooggetto ospite al metodo FrontDesk__init__()rendendolo cosigrave un attributo dellrsquoistanza
gtgtgt class FrontDeskNG(object) def __init__(self guest) selfguest = guest def book_room(self) guest = selfguest next_id = get_next_id() bookings_db[next_id] = name guestname place guestplace phone guestphone
In effetti la soluzione che abbiamo raggiunto egrave un pattern molto conosciuto lrsquoadapter (adattatore) In generale unadapter contiene un oggetto adattato
gtgtgt class Adapter(object) def __init__(self adaptee) selfadaptee = adaptee
Questo pattern saragrave utile quando si avragrave a che fare con i dettagli implementativi che dipendono da considerazioniriguardanti
bull il cambio dei requisiti del cliente
bull requisiti di persistenza dei dati (ZODB RDBMS XML)
bull requisiti di output (HTML PDF testo semplice)
bull il linguaggio di markup usato per il rendering (ReST Markdown Textile)
Grazie agli adapters e al component registry (registro dei componenti) la ZCA permette di cambiare i dettagli imple-mentativi del codice attraverso la configurazione
Come vedremo in questa sezione sugli adapter della ZCA la possibilitagrave di configurare i dettagli implementativi for-nisce utili abilitagrave
bull lrsquoabilitagrave di passare da una implementazione allrsquoaltra
23 La guida completa alla Zope Component Architecture 169
Documentazione di Plone Release 4
bull lrsquoabilitagrave di aggiungere implementazioni quando necessario
bull aumenta il riutilizzo sia del codice precedente sia del codice della ZCA
Queste capacitagrave portano il codice ad essere piugrave flessibile scalabile e riutilizzabile Tuttavia crsquoegrave un costo per tutto ciogravepoicheacute il mantenimento del component registry aggiunge un livello di complessitagrave allrsquoapplicazione Se egrave noto a prioriche unrsquoapplicazione non avragrave mai bisogno di queste funzionalitagrave la ZCA non egrave necessaria
Ora siamo pronti per iniziare il nostro studio della Zope Component Architecture iniziando dalle interfacce
233 Interfacce
Introduzione
Il file READMEtxt 11 nel percorso pathtozopeinterface definisce le interfacce in questo modo
Le interfacce sono oggetti che specificano (documentano) il comportamentoverso lesterno degli oggetti che le forniscono Uninterfaccia specificail suo comportamento attraverso
- la documentazione informale in una doc string
- la definizione degli attributi
- le Invariants (invarianti) sono condizioni che devono essere verificateper un oggetto che fornisce linterfaccia
Il libro classico dellrsquoingegneria del software laquoDesign Patternsraquo 12 della Gang of Four raccomanda di ldquoProgrammareper interfacce non per implementazionerdquo Definire unrsquointerfaccia formale egrave utile per la comprensione del sistema Inpiugrave le interfacce portano a tutti i benefici della ZCA
Unrsquointerfaccia specifica le caratteristiche di un oggetto il suo comportamento le sue capacitagrave Lrsquointerfaccia descrivecosa puograve fare un oggetto mentre per capire come lo fa si dovragrave guardare lrsquoimplementazione
Due metafore usate comunemente per spiegare le interfacce sono i contratti e le cianografie termini dei dizionarilegale e architetturale per indicare un insieme di specifiche
In alcuni linguaggi moderni come il Java C VBNET etc le interfacce sono un aspetto esplicito del linguaggioSiccome in Python mancano le interfacce la ZCA le implementa con delle meta-classi da cui ereditare
Di seguito un classico esempio di hello world
gtgtgt class Host(object) def goodmorning(self name) Say good morning to guests return Good morning s name
Nel classe qui sopra abbiamo definito un metodo goodmorning Se chiamiamo il metodo goodmorning su un oggettoistanza di questa classe esso resituiragrave Good morning
gtgtgt host = Host()gtgtgt hostgoodmorning(Jack)Good morning Jack
11 Lrsquoalbero del codice di Zope egrave pieno di file READMEtxt che offrono una meravigliosa documentazione12 httpenwikipediaorgwikiDesign_Patterns
170 Chapter 2 Altri manuali
Documentazione di Plone Release 4
Qui host indica lrsquooggetto attuale utilizzato dal codice Se si volesse esaminare i dettagli implementativi si dovrebbeaccedere alla classe Host o attraverso il codice sorgente o con uno strumento di documentazione delle API 13
Ora inizieremo ad utilizzare le interfacce della ZCA Per la classe sopra si puograve specificare lrsquointerfaccia cosigrave
gtgtgt from zopeinterface import Interface
gtgtgt class IHost(Interface) def goodmorning(guest) Say good morning to guest
Come si puograve notare lrsquointerfaccia eredita da zopeinterfaceInterface Questo utilizzo (abuso) dello state-ment class del Python egrave come la ZCA definisce le interfacce Il prefisso ldquoIrdquo per i nomi delle interfacce non egrave altro cheunrsquoutile convenzione
Dichiarazione delle interfacce
Abbiamo giagrave visto come dichiarare un interfaccia utilizzando zopeinterface nella sezione precedente Questasezione spiegheragrave il concetto piugrave nel dettaglio
Si consideri questa interfaccia di esempio
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import Attribute
gtgtgt class IHost(Interface) A host object name = Attribute(Name of host) def goodmorning(guest) Say good morning to guest
Lrsquointerfaccia IHost ha due attributi name e goodmorning Si ricordi che in Python i metodi sono anche attributidelle classi Lrsquoattributo name egrave definito utilizzando la classe zopeinterfaceAttribute Quando si aggiungeun attributo name allrsquointerfaccia IHost non viene impostato un valore iniziale Lo scopo di definire lrsquoattributo namequi egrave puramente per indicare che qualsiasi implementazione di questa interfaccia dovragrave fornire un attributo chiamatoname In questo caso non viene nemmeno indicato di che tipo deve essere lrsquoattributo Si puograve passare una stringa didocumentazione come primo argomento di Attribute
Lrsquoaltro attributo goodmorning egrave un metodo definito utilizzando la definizione di funzione Si noti che self non egraverichiesto nelle interfacce percheacute self egrave un dettaglio implementativo della classe Ad esempio un modulo potrebbeimplementare questa interfaccia Se un modulo implementa questa interfaccia saranno definiti al suo interno unattributo name e una funzione goodmorning e la funzione goodmorning accetteragrave un argomento
Ora vedremo come fare la connessione interfaccia-classe-oggetto Gli oggetti sono la vera parte attiva e sono istanzedelle classi Lrsquointerfaccia egrave la vera definizione dellrsquooggetto quindi la classe egrave solo un dettaglio implementativo Eccopercheacute si dovrebbe sempre programmare unrsquointerfaccia e non unrsquoimplementazione
Ora si dovrebbe prendere familiaritagrave con due ulteriori termini per comprendere altri concetti Il primo egrave provide (for-nisce) e lrsquoaltro egrave implement (implementa) Gli oggetti forniscono le interfacce e le classi implementano le interfacceIn altre parole gli oggetti forniscono le interfacce che le loro classi implementano Nel esempio sopra host (lrsquooggetto)fornisce IHost (lrsquointerfaccia) e Host (la classe) implementa IHost (lrsquointerfaccia) Un oggetto puograve fornire piugrave di una in-terfaccia e anche una classe puograve implementare piugrave di una interfaccia Gli oggetti possono anche fornire delle interfaccedirettamente in aggiunta alle interfacce implementate dalle loro classi
13 httpenwikipediaorgwikiApplication_programming_interface
23 La guida completa alla Zope Component Architecture 171
Documentazione di Plone Release 4
Note Le classi sono i dettagli implementativi degli oggetti In Python le classi sono oggetti chiamabili quindi percheacutealtri oggetti chiamabili non possono implementare unrsquointerfaccia In effetti possono Per qualsiasi oggetto chiama-bile egrave possibile dichiarare che esso produce oggetti che forniscono una qualche interfaccia dichiarando che lrsquooggettochiamabile implementa le interfacce Gli oggetti chiamabili sono generalmente chiamati factories (fabbriche) Datoche le funzioni sono oggetti chiamabili una funzione puograve essere un implementatore di una interfaccia
Implementare le interfacce
Per dichiarare che una classe implementa una particolare interfaccia si utilizza la funzionezopeinterfaceimplements nella definizione della classe
Si consideri questo esempio qui Host implementa IHost
gtgtgt from zopeinterface import implements
gtgtgt class Host(object) implements(IHost) name = u def goodmorning(self guest) Say good morning to guest return Good morning s guest
Note se ci si chiede come lavori la funzione implements si faccia riferimento al post del blog di James Henstridge(httpblogsgnomeorgjamesh20050908python-class-advisors) Nella sezione degli adapter si potragrave vedragrave la fun-zione adapts che lavora in maniera simile
Siccome Host implementa IHost le istanze di Host forniscono IHost Crsquoegrave qualche metodo di utilitagrave per introspezionarele dichiarazioni La dichiarazione puograve essere fatta anche fuori dalla classe Se si omette interfaceimplements(IHost)nel esempio sopra una volta che la classe egrave giagrave stata definita egrave possibile scrivere
gtgtgt from zopeinterface import classImplementsgtgtgt classImplements(Host IHost)
Esempio rivisitato
Ora ritorniamo allrsquoapplicazione di esempio Qui si vedragrave come definire lrsquointerfaccia dellrsquooggetto frontdesk
gtgtgt from zopeinterface import Interface
gtgtgt class IDesk(Interface) A frontdesk will register objects details def register() Register objects details
Per prima cosa abbiamo importato la classe Interface dal modulo zopeinterface Se si definisce una sottoclassedella classe Interface essa saragrave una interfaccia dal punto di vista della Zope component architecture Unrsquointerfacciapuograve essere implementata come abbiamo giagrave visto in una classe o in qualsiasi oggetto chiamabile
172 Chapter 2 Altri manuali
Documentazione di Plone Release 4
Lrsquointerfaccia frontdesk definita qui egrave IDesk La stringa di documentazione dellrsquointerfaccia fornisce unrsquoidea di unpossibile oggetto Nella definizione di un metodo in unrsquointerfaccia il primo argomento non deve essere self poicheacuteunrsquointerfaccia non verragrave mai istanziata e i suoi metodi non saranno mai chiamati Al contrario la classe interfacciadocumenta semplicemente come dovrebbero apparire i metodi e gli attributi in qualsiasi classe normale che dichiari diimplementarla e il parametro self egrave un dettaglio implementativo che non ha bisogno di essere documentato
Come sappiamo unrsquointerfaccia puograve anche specificare normali attributi
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import Attribute
gtgtgt class IGuest(Interface) name = Attribute(Name of guest) place = Attribute(Place of guest)
In questa interfaccia lrsquooggetto ospite ha due attributi specificati con la documentazione Unrsquointerfaccia puograve anchespecificare attributi e metodi insieme Unrsquointerfaccia puograve essere implementata da una classe da un modulo o qualsiasialtro oggetto Per esempio una funzione puograve creare dinamicamente un componente e restituirlo in questo caso lafunzione egrave un implementatore dellrsquointerfaccia
Ora sappiamo cosrsquoegrave unrsquointerfaccia e come definirla e usarla Nel prossimo capitolo vedremo come utilizzareunrsquointerfaccia per definire un componente adapter
Interfacce marker
Unrsquointerfaccia puograve essere utilizzata per dichiarare che un particolare oggetto appartiene ad uno speciale tipoUnrsquointerfaccia senza attributi o metodi egrave chiamata interfaccia marker
Ecco un esempio di interfaccia marker
gtgtgt from zopeinterface import Interface
gtgtgt class ISpecialGuest(Interface) A special guest
Questa interfaccia puograve essere utilizzata per indicare che un oggetto egrave uno speciale tipo di ospite
Invarianti
A volte crsquoegrave la necessitagrave di utilizzare alcune regole per un componente che coinvolgono uno o piugrave normali attributiQuesto tipo di regole sono chiamate invariants (invarianti) Si puograve utilizzare zopeinterfaceinvariant perimpostare delle invarianti sulle interfacce degli oggetti
Si consideri un semplice esempio crsquoegrave un oggetto persona con gli attributi namelsquoemaillsquo e phone Come si potrebbeimplementare una regola di validazione che imponga che almeno uno fra gli attributi email e phone debba esistere manon necessariamente entrambi
Per prima cosa bisogna costruire un oggetto chiamabile o una semplice funzione o una istanza chiamabile di unaclasse come questa
gtgtgt def contacts_invariant(obj) if not (objemail or objphone) raise Exception( At least one contact info is required)
23 La guida completa alla Zope Component Architecture 173
Documentazione di Plone Release 4
Poi si deve definire lrsquointerfaccia dell oggetto person in questo modo Utilizzare la funzionezopeinterfaceinvariant per definire lrsquoinvariante
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import invariant
gtgtgt class IPerson(Interface) name = Attribute(Name) email = Attribute(Email Address) phone = Attribute(Phone Number) invariant(contacts_invariant)
Ora utilizzare il metodo validateInvariants dellrsquointerfaccia per la validazione
gtgtgt from zopeinterface import implements
gtgtgt class Person(object) implements(IPerson) name = None email = None phone = None
gtgtgt jack = Person()gtgtgt jackemail = ujacksomeaddresscomgtgtgt IPersonvalidateInvariants(jack)gtgtgt jill = Person()gtgtgt IPersonvalidateInvariants(jill)Traceback (most recent call last)Exception At least one contact info is required
Come si puograve vedere lrsquooggetto jack egrave validato senza alcuna eccezione mentre lrsquooggetto jill non egrave stato validato dalvincolo invariante cosigrave viene sollevata unrsquoeccezione
234 Adapters
Implementazione
In questa sezione verranno descritti gli adapter in dettaglio La Zope Component Architecture come abbiamo giagravevisto aiuta ad utilizzare efficacemente gli oggetti Python I componenti adapter sono uno dei componenti di baseutilizzati dalla ZCA Gli adapter sono oggetti Python ma con interfacce ben definite
Per dichiarare che una classe egrave un adapter si utilizza la funzione adapts definita nel pacchetto zopecomponentEcco il nuovo adattatore FrontDeskNG con una dichiarazione esplicita di interfaccia
gtgtgt from zopeinterface import implementsgtgtgt from zopecomponent import adapts
gtgtgt class FrontDeskNG(object) implements(IDesk) adapts(IGuest) def __init__(self guest)
174 Chapter 2 Altri manuali
Documentazione di Plone Release 4
selfguest = guest
def register(self)
guest = selfguest
next_id = get_next_id()
bookings_db[next_id] =
name guestname
place guestplace
phone guestphone
Quello che abbiamo definito qui egrave un adapter per IDesk che adatta gli oggetti IGuest Lrsquointerfaccia IDesk egrave imple-mentata dalla classe FrontDeskNG Quindi unrsquoistanza di questa classe forniragrave lrsquointerfaccia IDesk
gtgtgt class Guest(object) implements(IGuest) def __init__(self name place) selfname = name selfplace = place
gtgtgt jack = Guest(Jack Bangalore)gtgtgt jack_frontdesk = FrontDeskNG(jack)
gtgtgt IDeskprovidedBy(jack_frontdesk)True
Il FrontDeskNG egrave solo uno dei possibili adattatori Egrave possibile creare anche altri adapter che permettano di gestire leregistrazioni degli ospiti diversamente
Registration
Per utilizzare questo componente adapter bisogna registrarlo nel component registry anche conosciuto come sitemanager Un site manager normalmente risiede in un sito Il sito e il suo site manager saranno piugrave importantiquando si svilupperanno applicazioni Zope3 Per ora ci interesseremo solo del global site e del global site manager (ocomponent registry) Il global site manager risiede in memoria mentre un local site manager egrave persistente
Per registrare il nostro componente per prima cosa recuperiamo il global site manager
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()gtgtgt gsmregisterAdapter(FrontDeskNG (IGuest) IDesk ng)
Per recuperare il global site manager bisogna chiamare la funzione getGlobalSiteManager disponibile nelpacchetto zopecomponent In effetti il global site manager egrave disponibile anche come un attributo (glob-alSiteManager) del pacchetto zopecomponent Quindi egrave anche possibile utilizzare direttamente lrsquoattributozopecomponentglobalSiteManager Per registrare lrsquoadapter nei componenti come si puograve vedere sopra siutilizza il metodo registerAdapter del component registry Il primo argomento deve essere un classefactory adapterIl secondo argomento egrave una tupla di oggetti adattati ad esempio lrsquooggetto che stiamo adattando In questo esempiostiamo adattando solo lrsquooggetto IGuest Il terzo argomento egrave lrsquointerfaccia implementata dal componente adater Ilquarto argomento egrave opzionale ed egrave il nome di quel particolare adapter Dato che abbiamo dato un nome a questoadapter questo egrave un named adapter Se non viene passato alcun nome allora questo saragrave automaticamente una stringavuota (lsquorsquo)
Nella registrazione sopra abbiamo passato lrsquointerfaccia adattata e lrsquointerfaccia fornita dallrsquoadapter Dato che questi
23 La guida completa alla Zope Component Architecture 175
Documentazione di Plone Release 4
dettagli sono giagrave stati specificati nella implementazione dellrsquoadapter non egrave necessario specificarli ancora Infattiavremmo potuto fare la registrazione cosigrave
gtgtgt gsmregisterAdapter(FrontDeskNG name=ng)
Ci sono alcune vecchie API per fare la registrazione che perograve andrebbero evitate Le funzioni delle vecchie APIiniziano con provide ad es provideAdapter provideUtilityetc Durante lo sviluppo di unrsquoapplicazione Zope3 egravepossibile utilizzare lo Zope configuration markup language (ZCML) per la registrazione dei componenti In Zope3 ilocal component (o componenti persistenti) possono essere registrati dalla Zope Management Interface (ZMI) o anchein maniera programmatica
Note I local component sono componenti persistenti mentre i global component risiedono in memoria I globalcomponent saranno registrati in base alla configurazione dellrsquoapplicazione I local component sono caricati in memoriadal database allrsquoavvio dellrsquoapplicazione
Recuperare un adapter
Il recupero dei componenti registrati dal component registry puograve essere effettuato con due funzioni disponibili nelpacchetto zopecomponent Una di esse egrave getAdapter e lrsquoaltra egrave queryAdapter Entrambe le funzioni accettano glistessi parametri Il metodo getAdapter solleveragrave ComponentLookupError se la ricerca del componente fallisce mentrequeryAdapter restituiragrave None
Si possono importare i due metodi in questo modo
gtgtgt from zopecomponent import getAdaptergtgtgt from zopecomponent import queryAdapter
Nella sezione precedente abbiamo registrato un componente per lrsquooggetto ospite (lrsquooggetto adattato) che forniscelrsquointerfaccia IDesk con nome lsquongrsquo Nella prima sezione di questo capitolo abbiamo creato un oggetto ospite di nomejack
Ecco come recuperare un componente che adatta lrsquointerfaccia dellrsquooggetto jack (IGuest) e fornisce lrsquointerfaccia IDeske con il nome lsquongrsquo Qui sia getAdapter sia queryAdapter lavorano in maniera simile
gtgtgt getAdapter(jack IDesk ng)ltFrontDeskNG object at gtgtgtgt queryAdapter(jack IDesk ng)ltFrontDeskNG object at gt
Come si puograve vedere il primo argomento egrave lrsquooggetto da adattare poi lrsquointerfaccia che dovrebbe essere fornita dalcomponente e per ultimo il nome del componente adapter
Se si prova a cercare un componente con un nome non registrato ma per lo stesso oggetto adattato e la stessa interfacciala ricerca falliragrave Ecco come si comportano i due metodi in questo caso
Come si puograve vedere sopra getAdapter ha sollevato unrsquoeccezione ComponentLookupError mentre queryAdapter harestituito None quando la ricerca egrave fallita
Il terzo argomento il nome di registrazione egrave opzionale e se non viene passato il suo valore predefinito saragrave unastringa vuota (lsquorsquo) Dal momento che non ci sono componenti registrati con una stringa vuota getAdapter solleveragraveComponentLookupError elsquoqueryAdapterlsquo restituiragrave None
gtgtgt getAdapter(jack IDesk)Traceback (most recent call last)ComponentLookupError gtgtgt reg = queryAdapter(jack IDesk)
176 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt reg is NoneTrue
In questa sezione abbiamo imparato come registrare un semplice adapter e come recuperarlo dal component registryQuesto tipo di adapter sono chiamati single adapter (adattatore singolo) percheacute adattano solo un oggetto Se un adapteradatta piugrave di un oggetto allora si chiama multi-adapter (multi-adattatore)
Recuperare gli adapter tramite le interfacce
Gli adapter possono essere recuperati direttamente utilizzando le interfacce ma questo funziona solo per gli adaptersenza nome Il primo argomento egrave lrsquooggetto adattato e il secondo egrave un argomento keyword Se la ricerca dellrsquoadapterfallisce viene restituito il secondo argomento
gtgtgt IDesk(jack alternate=default-output)default-output
Il nome della keyword puograve anche essere ommesso
gtgtgt IDesk(jack default-output)default-output
Se il secondo argomento non viene passato allora viene sollevata TypeError
gtgtgt IDesk(jack)Traceback (most recent call last)TypeError (Could not adapt
ltGuest object at gtltInterfaceClass __builtin__IDeskgt)
Qui FrontDeskNG viene registrato senza nome
gtgtgt gsmregisterAdapter(FrontDeskNG)
Ora la ricerca dellrsquoadapter dovrebbe andare a buon fine
gtgtgt IDesk(jack default-output)ltFrontDeskNG object at gt
Quindi per casi semplici si puograve utilizzare lrsquointerfaccia per recuperare il componente adapter
Il pattern adapter
Il concetto di adapter nella Zope Component Architecture egrave molto simile al classico pattern adapter che viene descrittonel libro laquoDesign Patternraquo Lrsquointento degli adapter della ZCA egrave perograve piugrave ampio di quello del pattern adapter Lrsquointentodel pattern adapter egrave quello di convertire lrsquointerfaccia di una classe in unrsquoaltra interfaccia che il client si aspetta Questopermette di poter far lavorare insieme le classi che altrimenti sarebbero incompatibili a causa delle loro interfacce Manella sezione Motivation del libro laquoDesign Patternraquo GoF dice ldquoSpesso lrsquoadapter fornisce delle funzionalitagrave che leclassi adattate non fornisconordquo Lrsquoadapter della ZCA egrave piugrave incentrato sullrsquoaggiunta di funzionalitagrave che sulla creazionedi una nuova interfaccia per un oggetto adattato Lrsquoadapter della ZCA permette alle classi adapter di estendere lefunzionalitagrave aggiungendo nuovi metodi (sarebbe interessante notare che lrsquoAdapter era conosciuto come Feature nelleprime fasi del design della ZCA) 14
Nel paragrafo sopra crsquoegrave una citazione dal libro della ldquoGang of Fourrdquo che finisce cosigrave rdquoche le classi adattate nonfornisconordquo Ma nella frase successiva io ho utilizzato ldquooggetto adattatordquo invece di ldquoclasse adattatardquo poicheacute Gof de-scrive due varianti di adapter basati sullrsquoimplementazione La prima egrave chiamata class adapter e lrsquoaltra object adapter
14 Discussione sulla rinomina delle Feature in Adapter httpmailzopeorgpipermailzope3-dev2001-December000008html
23 La guida completa alla Zope Component Architecture 177
Documentazione di Plone Release 4
Un class adapter utilizza lrsquoereditarietagrave multipla per adattare unrsquointerfaccia allrsquoaltra mentre un object adapter fa affi-damento sulla composizione degli oggetti Lrsquoadapter della ZCA segue il pattern object adapter il quale usa la delegacome meccanismo di composizione Il secondo principio di GoF a proposito del design orientato agli oggetti diceldquoFavorite la composizione degli oggetti rispetto allrsquoereditarietagrave di classerdquo Per maggiori dettagli su questo argomentovi invito a leggere il libro laquoDesign Patternraquo
La cosa piugrave interessante degli adapter della ZCA sono le interfacce esplicite per i componenti e il component registryI componenti adapter della ZCA vengono registrati nel component registry e recuperati dagli oggetti client utilizzandole interfacce e il nome quando richiesto
235 Utility
Introduzione
Ora conosciamo i concetti di interfaccia adapter e component registry A volte perograve sarebbe utile poter registrare unoggetto che non adatta nulla Connessioni a database parse XML oggetti che restituiscono Id univoci etc sono tuttiesempi di questo tipo di oggetti Questo tipo di componenti forniti dalla ZCA sono chiamati utility
Le utility sono solo oggetti che forniscono unrsquointerfaccia e che vengono ricercati per interfaccia e per nome Questoapproccio crea un global registry attraverso il quale le interfacce possono essere registrate e accedute da diverse partidella nostra applicazione senza bisogno di passare le istanze avanti e indietro come parametri
Non egrave perograve consigliabile registrare tutte le istanze di componenti in questo modo Si dovrebbero registrare solo icomponenti che si vuole rendere rimpiazzabili
Semplici utility
Una utility puograve essere registrata con un nome o senza nome Una utility registrata con un nome egrave chiamata namedutility e la vedremo nella prossima sezione Prima di implementare lrsquoutility come solito definiamo la sua interfacciaEcco unrsquointerfaccia IGreeter (ldquosalutatorerdquo)
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
gtgtgt class IGreeter(Interface) def greet(name) Say hello
Come anche un adapter una utility puograve avere piugrave di una implementazione Ecco una possibile implementazione dellainterfaccia sopra
gtgtgt class Greeter(object) implements(IGreeter) def greet(self name) return Hello + name
La vera utility saragrave unrsquoistanza di questa classe Per utilizzare questa utility dobbiamo registrarla per poterlarichiedere in seguito utilizzando lrsquoAPI della ZCA Possiamo registrare unrsquoistanza di questa classe (utility) utilizzandoregisterUtility
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
178 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt greet = Greeter()gtgtgt gsmregisterUtility(greet IGreeter)
In questo esempio abbiamo registrato lrsquoutility che fornisce lrsquointerfaccia IGreeter Si puograve ricercare lrsquointerfaccia siacon queryUtility sia con getUtility
gtgtgt from zopecomponent import queryUtilitygtgtgt from zopecomponent import getUtility
gtgtgt queryUtility(IGreeter)greet(Jack)Hello Jack
gtgtgt getUtility(IGreeter)greet(Jack)Hello Jack
Come si puograve vedere gli adapter normalmente sono delle classi mentre le utility normalmente sono istanze di classiLrsquoistanza della classe utility viene creata solo una volta mentre le istanze dellrsquoadapter vengono create dinamicamentequando vengono richieste
Named utility
Quando si registra un componente come ad esempio un adapter egrave possibile assegnargli un nome Come detto nellaprecedente sezione una utility registrata con un particolare nome egrave chiamata named utility
Ecco come registrare lrsquoutility greeter con un nome
gtgtgt greet = Greeter()gtgtgt gsmregisterUtility(greet IGreeter new)
In questo esempio abbiamo registrato lrsquoutility con un nome fornendo lrsquointerfaccia IGreeter Ecco come ricercarelrsquointerfaccia con queryUtility o con getUtility
gtgtgt from zopecomponent import queryUtilitygtgtgt from zopecomponent import getUtility
gtgtgt queryUtility(IGreeter new)greet(Jill)Hello Jill
gtgtgt getUtility(IGreeter new)greet(Jill)Hello Jill
Come si puograve vedere qui quando si fa unrsquointerrogazione egrave necessario utilizzare il name come secondo argomento
Chiamare la funzione getUtility senza un nome (come secondo argomento) egrave uguale a chiamare a chiamarla conuna stringa vuota come nome poichegrave il valore predefinito del secondo argomento (keyword) egrave una stringa vuotaPoi il meccanismo di ricerca dei componenti proveragrave a trovare il componente il nome uguale alla stringa vuotae falliragrave Quando la ricerca del componente fallisce solleva lrsquoeccezione ComponentLookupError Si ricordiche non ritorneragrave un componente a caso con unrsquoaltro nome Le funzioni di ricerca degli adapter getAdapter equeryAdapter lavorano in maniera simile
Factory
Una factory egrave un componente utility che fornisce lrsquointerfaccia IFactory
Per creare una factory per prima cosa definiamo lrsquointerfaccia dellrsquooggetto
23 La guida completa alla Zope Component Architecture 179
Documentazione di Plone Release 4
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
gtgtgt class IDatabase(Interface) def getConnection() Return connection object
Ecco una finta implementazione dellrsquointerfaccia IDatabase
gtgtgt class FakeDb(object) implements(IDatabase) def getConnection(self) return connection
Possiamo creare una factory utilizzando zopecomponentfactoryFactory
gtgtgt from zopecomponentfactory import Factory
gtgtgt factory = Factory(FakeDb FakeDb)
Ora possiamo registrarla in questo modo
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt from zopecomponentinterfaces import IFactorygtgtgt gsmregisterUtility(factory IFactory fakedb)
Per utilizzare la factory possiamo fare cosigrave
gtgtgt from zopecomponent import queryUtilitygtgtgt queryUtility(IFactory fakedb)()ltFakeDb object at gt
Crsquoegrave una scorciatoia per utilizzare una factory
gtgtgt from zopecomponent import createObjectgtgtgt createObject(fakedb)ltFakeDb object at gt
236 Adapter avanzati
In questo capitolo discuteremo di adapter avanzati come i multi-adapter i subscription adapter e gli handler
Multi adapter
Un semplice adapter normalmente adatta solo un oggetto ma un adapter puograve adattare piugrave di un oggetto Se un adapteradatta piugrave di un oggetto egrave chiamato multi-adapter
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implementsgtgtgt from zopecomponent import adapts
180 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt class IAdapteeOne(Interface) pass
gtgtgt class IAdapteeTwo(Interface) pass
gtgtgt class IFunctionality(Interface) pass
gtgtgt class MyFunctionality(object) implements(IFunctionality) adapts(IAdapteeOne IAdapteeTwo) def __init__(self one two) selfone = one selftwo = two
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt gsmregisterAdapter(MyFunctionality)
gtgtgt class One(object) implements(IAdapteeOne)
gtgtgt class Two(object) implements(IAdapteeTwo)
gtgtgt one = One()gtgtgt two = Two()
gtgtgt from zopecomponent import getMultiAdapter
gtgtgt getMultiAdapter((onetwo) IFunctionality)ltMyFunctionality object at gt
gtgtgt myfunctionality = getMultiAdapter((onetwo) IFunctionality)gtgtgt myfunctionalityoneltOne object at gtgtgtgt myfunctionalitytwoltTwo object at gt
Subscription adapter
A differenza dei normali adapter i subscription adapter vengono utilizzati quando vogliamo recuperare tutti gli adapterche adattano un oggetto a una particolare interfaccia Un subscription adapter egrave anche conosciuto come subscriber
Consideriamo un problema di validazione Abbiamo degli oggetti e vogliamo verificare se essi aderiscono a qualchetipo di standard Si definisce unrsquointerfaccia di validazione
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import implements
gtgtgt class IValidate(Interface) def validate(ob)
23 La guida completa alla Zope Component Architecture 181
Documentazione di Plone Release 4
Determine whether the object is valid
Return a string describing a validation problem
An empty string is returned to indicate that the
object is valid
Magari abbiamo dei documenti
gtgtgt class IDocument(Interface) summary = Attribute(Document summary) body = Attribute(Document text)
gtgtgt class Document(object) implements(IDocument) def __init__(self summary body) selfsummary selfbody = summary body
Ora potremmo voler specificare diverse regole di validazione per questi documenti Per esempio potremmo richiedereche la descrizione sia una linea singola
gtgtgt from zopecomponent import adapts
gtgtgt class SingleLineSummary adapts(IDocument) implements(IValidate) def __init__(self doc) selfdoc = doc def validate(self) if n in selfdocsummary return Summary should only have one line else return
Oppure potremmo richiedere che il corpo del testo sia lungo al massimo 1000 caratteri
gtgtgt class AdequateLength(object) adapts(IDocument) implements(IValidate) def __init__(self doc) selfdoc = doc def validate(self) if len(selfdocbody) lt 1000 return too short else return
Possiamo registrare queste regole come subscription adapter
182 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt gsmregisterSubscriptionAdapter(SingleLineSummary)gtgtgt gsmregisterSubscriptionAdapter(AdequateLength)
In seguito possiamo utilizzare i subscriber per validare gli oggetti
gtgtgt from zopecomponent import subscribers
gtgtgt doc = Document(AnDocument blah)gtgtgt [adaptervalidate() for adapter in subscribers([doc] IValidate) if adaptervalidate()][Summary should only have one line too short]
gtgtgt doc = Document(AnDocument blah 1000)gtgtgt [adaptervalidate() for adapter in subscribers([doc] IValidate) if adaptervalidate()][Summary should only have one line]
gtgtgt doc = Document(A Document blah)gtgtgt [adaptervalidate() for adapter in subscribers([doc] IValidate) if adaptervalidate()][too short]
Handler
Gli handler sono delle fabbriche di subscription adapter che non restituiscono nulla Essi infatti eseguono tutto il lorolavoro quando vengono chiamati Gli handler tipicamente sono utilizzati per la gestione degli eventi e sono ancheconosciuti come event subscribers o event subscription adapter
Gli event subscriber sono diversi dagli altri subscription adapter per il fatto che il chiamante dellrsquoevent subscribernon si aspetta di interagire con loro in nessun modo diretto Per esempio un generatore di eventi non si aspetta diricevere alcun valore di ritorno Poicheacute i subscribers non hanno bisogno di fornire alcuna API ai loro chiamanti egrave piugravenaturale definirli con delle funzioni piuttosto che con delle classi Per esempio in un sistema di gestione documentalepotremmo voler registrare le date di creazione dei documenti
gtgtgt import datetime
gtgtgt def documentCreated(event) eventdoccreated = datetimedatetimeutcnow()
In questo esempio abbiamo una funzione che prende un evento e svolge qualche operazione e in effetti non restituiscenulla Questo egrave un caso speciale di subscription adapter che adatta un evento verso nulla Tutto il lavoro egrave svoltoquando la ldquofactoryrdquo dellrsquoadapter viene chiamata I subscriber che non restituiscono niente sono chiamati ldquohandlerrdquo eper registrarli ci sono delle API specifiche
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import implements
gtgtgt class IDocumentCreated(Interface) doc = Attribute(The document that was created)
23 La guida completa alla Zope Component Architecture 183
Documentazione di Plone Release 4
gtgtgt class DocumentCreated(object) implements(IDocumentCreated) def __init__(self doc) selfdoc = doc
Dovremo anche cambiare la definizione del nostro handler
Questo identifica lrsquohandler come un adapter di eventi di tipo IDocumentCreated
Andiamo a registrare lrsquohandler
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt gsmregisterHandler(documentCreated)
Ora possiamo creare un evento e utilizzare la funzione handle per chiamare gli handler registrati per lrsquoevento
gtgtgt from zopecomponent import handle
gtgtgt handle(DocumentCreated(doc))gtgtgt doccreated__class____name__datetime
237 Utilizzo della ZCA in Zope
La Zope Component Architecture viene utilizzata sia in Zope3 sia in Zope2 Questo capitolo tratteragrave lrsquoutilizzo dellaZCA in Zope
ZCML
Lo Zope Configuration Markup Language (ZCML) egrave un sistema di configurazione basato su XML per la regis-trazione dei componenti Cosigrave invece di utilizzare le API Python per la registrazione egrave possibile utilizzare lo ZCMLSfortunatamente perograve lrsquoutilizzo dello ZCML richiederagrave lrsquoinstallazione di piugrave pacchetti di dipendenze
Per installare questi pacchetti lanciare
$ easy_install zopecomponent [zcml]
Ecco come registrare un componente
ltconfigure xmlns=httpnamespaceszopeorgzopegt
ltadapterfactory=companyEmployeeSalaryprovides=interfacesISalaryfor=interfacesIEmployeegt
Gli attributi provides e for sono opzionali a patto che siano giagrave stati dichiarati nellrsquoimplementazione del componente
ltconfigure xmlns=httpnamespaceszopeorgzopegt
ltadapterfactory=companyEmployeeSalarygt
184 Chapter 2 Altri manuali
Documentazione di Plone Release 4
Se si vuole registrare il componente come un named adapter si puograve fornire un attributo name
ltconfigure xmlns=httpnamespaceszopeorgzopegt
ltadapterfactory=companyEmployeeSalaryname=salarygt
Anche le utility sono registrate in maniera simile
ltconfigure xmlns=httpnamespaceszopeorgzopegt
ltutilitycomponent=databaseconnectionprovides=interfacesIConnectiongt
lrsquoattributo provides egrave opzionale a patto che sia stato dichiarato nellrsquoimplementazione
ltconfigure xmlns=httpnamespaceszopeorgzopegt
ltutilitycomponent=databaseconnectiongt
Se si vuole registrare il componente come named utility si puograve fornire lrsquoattributo name
ltconfigure xmlns=httpnamespaceszopeorgzopegt
ltutilitycomponent=databaseconnectionname=Database Connectiongt
Invece di utilizzare direttamente il componente egrave possibile anche fornire la factory
ltconfigure xmlns=httpnamespaceszopeorgzopegt
ltutilityfactory=databaseConnectiongt
Overrides
Quando registriamo un componente utilizzando le API Python (i metodi register) lrsquoultimo componente registratorimpiazzeragrave il componente registrato in precedenza se entrambi sono registrati con gli stessi componenti Per esempioconsideriamo lrsquoesempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interface
gtgtgt class IA(Interface) pass
gtgtgt class IP(Interface) pass
gtgtgt from zopeinterface import implements
23 La guida completa alla Zope Component Architecture 185
Documentazione di Plone Release 4
gtgtgt from zopecomponent import adapts
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt class AP(object) implements(IP) adapts(IA) def __init__(self context) selfcontext = context
gtgtgt class AP2(object) implements(IP) adapts(IA) def __init__(self context) selfcontext = context
gtgtgt class A(object) implements(IA)
gtgtgt a = A()gtgtgt ap = AP(a)
gtgtgt gsmregisterAdapter(AP)
gtgtgt getAdapter(a IP)ltAP object at gt
Se registriamo unrsquoaltro adapter quello esistente viene rimpiazzato
gtgtgt gsmregisterAdapter(AP2)
gtgtgt getAdapter(a IP)ltAP2 object at gt
Ma quando si registrano i componenti utilizzando ZCML la seconda registrazione solleva un errore di conflittoQuesto egrave un suggerimento per noi altrimenti ci sarebbe la possibilitagrave di sovrascrivere le registrazioni per sbaglio equesto potrebbe portare a una maggiore difficoltagrave nel tracciare i bug nel sistema Quindi lrsquoutilizzo dello ZCML egrave unabuona cosa per lrsquoapplicazione
A volte avremo la necessitagrave di sovrascrivere una registrazione esistente Per questa evenienza lo ZCML fornisce ladirettiva includeOverrides Con questa direttiva possiamo scrivere le nostre sostituzioni in un file separato
ltincludeOverrides file=overrideszcml gt
NameChooser
Posizione zopeappcontainercontainedNameChooser
Questo egrave un adapter che permette di scegliere un nome univoco per un oggetto allrsquointerno di un contenitore
La registrazione dellrsquoadapter egrave simile a questa
186 Chapter 2 Altri manuali
Documentazione di Plone Release 4
ltadapterprovides=interfacesINameChooserfor=zopeappcontainerinterfacesIWriteContainerfactory=containedNameChoosergt
Dalla registrazione possiamo vedere che lrsquooggetto adattato egrave un IWriteContainer e che lrsquoadapter fornisce IName-Chooser
Questo adapter fornisce una funzionalitagrave molto comoda per i programmatori Zope La principale implementazionedi IWriteContainer in Zope3 sono zopeappcontainerBTreeContainer e zopeappfolderFolder Normalmente ered-iteremo da queste implementazioni per creare le nostre classi contenitori Se che non ci fosse nessuna interfacciachiamata INameChooser e il relativo adapter allora dovremmo implementare questa funzionalitagrave per ogni implemen-tazione separatamente
LocationPhysicallyLocatable
Posizione zopelocationtraversingLocationPhysicallyLocatable
Questo adapter viene utilizzato frequentemente nelle applicazioni Zope3 ma normalmente viene chiamato attraversoun API in zopetraversingapi (Qualche vecchio codice utilizza le funzioni di zopeappzapi che egrave solo unaredirezione aggiuntiva)
La registrazione dellrsquoadapter egrave simile a questa
ltadapterfactory=zopelocationtraversingLocationPhysicallyLocatablegt
Lrsquointerfaccia fornita e lrsquointerfaccia adattata sono specificate nellrsquoimplementazione
Ecco qui lrsquoinizio dellrsquoimplementazione
class LocationPhysicallyLocatable(object)Provide location information for location objectszopecomponentadapts(ILocation)zopeinterfaceimplements(IPhysicallyLocatable)
Normalmente quasi tutti gli oggetti persistenti nellrsquoapplicazione Zope3 forniranno lrsquointerfaccia ILocation Questainterfaccia ha solo due attributi __parent__ e __name__ Il __parent__ egrave il contenitore nella gerarchia deglioggetti e __name__ egrave il nome dellrsquooggetto allrsquointerno del contenitore
Lrsquointerfaccia IPhysicallyLocatable ha 4 metodi getRoot getPath getName e getNearestSite
bull getRoot restituisce lrsquooggetto radice fisica
bull getPath restituisce il percorso fisico verso lrsquooggetto in formato stringa
bull getName restituisce lrsquoultimo segmento del percorso fisico
bull getNearestSite restituisce il sito in cui egrave contenuto lrsquooggetto Se lrsquooggetto egrave un sito viene restituitolrsquooggetto stesso
Quando si studia Zope3 si capisce che queste sono le cose importanti e quelle che vengono richieste piugrave spesso Percomprendere la bellezza di questo sistema bisogna vedere come Zope2 recupera lrsquooggetto radice fisica e come questoegrave implementato Esiste un metodo chiamato getPhysicalRoot virtualmente per ogni oggetto contenitore
23 La guida completa alla Zope Component Architecture 187
Documentazione di Plone Release 4
DefaultSized
Posizione zopesizeDefaultSized
Questo adapter non egrave che lrsquoimplementazione di default dellrsquointerfaccia ISized Esso egrave registrato per tutti i tipi dioggetti Se si vuole registrare questo adapter per una particolare interfaccia si dovragrave sovrascrivere questa registrazionenella propria implementazione
La registrazione dellrsquoadapter egrave simile a questa
ltadapterfor=factory=zopesizeDefaultSizedprovides=zopesizeinterfacesISizedpermission=zopeViewgt
Come si puograve vedere lrsquointerfaccia adattata egrave ldquordquo quindi puograve adattare qualsiasi tipo di oggetto
ISized egrave una semplice interfaccia con due contratti di metodi
class ISized(Interface)
def sizeForSorting()Returns a tuple (basic_unit amount)
Used for sorting among different kinds of sized objectsamount need only be sortable among things that share thesame basic unit
def sizeForDisplay()Returns a string giving the size
Si puograve trovare unrsquoaltro adapter ISized registrato per IZPTPage nel pacchetto zopeappzptpage
ZopeVersionUtility
Posizione zopeappapplicationcontrolZopeVersionUtility
La registrazione egrave questa
ltutilitycomponent=zopeversionZopeVersionUtilityprovides=interfacesIZopeVersion gt
Lrsquointerfaccia fornita IZopeVersion ha solo un metodo chiamato getZopeVersion Questo metodo restituisceuna stringa contenente la versione di Zope (con eventualmente le informazione di SVN) Lrsquoimplementazione di defaultZopeVersionUtility prende le informazioni sull versione da un file versiontxt nella cartella zopeapp SeZope egrave in esecuzione a partire da un checkout di Subversion esso mostra lrsquoultimo numero di revisione Se nessunodei metodi sopra funziona allora restituisce DevelopmentUnknown
238 Caso di studio
Note Questo capitolo non egrave ancora completo Ogni suggerimento egrave benvenuto
188 Chapter 2 Altri manuali
Documentazione di Plone Release 4
Introduzione
Questo capitolo egrave un esempio di creazione di unrsquoapplicazione desktop utilizzando la libreria PyGTK per le GUI ela ZCA Questrsquoapplicazione utilizza anche due diversi tipi di meccanismi per la persistenza dei dati un database adoggetti (ZODB) e un altro database relazionale (SQLite) In ogni caso nella pratica solo uno storage puograve essere utiliz-zato per una particolare installazione La ragione di utilizzare due diversi meccanismi di persistenza egrave la dimostrazionedi come usare la ZCA per incollare tra loro i componenti La maggior parte del codice di questa applicazione egrave legatoa PyGTK
Man mano che lrsquoapplicazione crescie si potranno utilizzare i componenti ZCA dovunque si desideri avere modularitagravee estensibilitagrave Si utilizzino invece direttamente oggetti Python dove non sono richieste queste due proprietagrave
Non crsquoegrave differenza nellrsquoutilizzo della ZCA per il web o per il desktop o per qualsiasi altro tipo di applicazione o frame-work Egrave preferibile seguire una convenzione per posizione dalla quale registrare i componenti Questa applicazioneutilizza una convenzione che permette di essere estesa posizionando delle registrazioni di componenti simili in moduliseparati e in seguito importarli dal modulo di registrazione principale In questa applicazione il modulo principale perla registrazione dei componenti egrave registerpy
Il codice sorgente di questa applicazione puograve essere scaricato su httpwwwmuthukadannetdownloadszcalibtarbz2
Casi drsquouso
Lrsquoapplicazione che ora andiamo a discutere egrave un sistema per la gestione di una biblioteca con funzionalitagrave minimali Irequisiti possono essere riassunti cosigrave
bull aggiunta dei membri con un numero univoco e un nome
bull aggiunta dei libri con il codice a barre autore e titolo
bull prestito dei libri
bull restituzione dei libri
Lrsquoapplicazione puograve essere disegnata in modo che le funzionalitagrave principali possano essere utilizzate da una singolafinestra La finestra principale per accedere a tutte queste funzionalitagrave potrebbe avere questo aspetto
Dalla finestra Member lrsquoutente dovrebbe poter gestire i membri Quindi dovrebbe essere possibile aggiungere modi-ficare e eliminare i membri come in figura sotto
23 La guida completa alla Zope Component Architecture 189
Documentazione di Plone Release 4
Simile alla finestra dei membri la finestra del catalogo permette allrsquoutente di aggiungere modificare e eliminare i libri
La finestra dei movimenti dovrebbe gestire i prestiti e le restituzioni dei libri
Panoramica del codice PyGTK
Come si puograve vedere dal codice la maggior parte del codice egrave legato a PyGTK e la sua struttura egrave molto simile perle diverse finestre Le finestre di questa applicazione sono disegnate utilizzando il costruttore di GUI Glade Sidovrebbero assegnare nomi sensati ai widget che si andragrave ad utilizzare nel codice Nella finestra principale tutte levoci del menu hanno nomi come circulation catalog member quit e about
La classe gtkgladeXML egrave utilizzata analizzare il file Glade e quindi creare gli oggetti widget dellrsquointerfacciagrafica Ecco come analizzare e accedere agli oggetti
import gtkgladexmlobj = gtkgladeXML(pathtofileglade)widget = xmlobjget_widget(widget_name)
Nel file mainwindowpy si puograve vedere il codice
curdir = ospathabspath(ospathdirname(__file__))xml = ospathjoin(curdir glade mainwindowglade)
190 Chapter 2 Altri manuali
Documentazione di Plone Release 4
xmlobj = gtkgladeXML(xml)
selfmainwindow = xmlobjget_widget(mainwindow)
Il nome del widget della finestra principale egrave mainwindow In maniera simile gli altri widget vengono recuperaticosigrave
circulation = xmlobjget_widget(circulation)member = xmlobjget_widget(member)quit = xmlobjget_widget(quit)catalog = xmlobjget_widget(catalog)about = xmlobjget_widget(about)
Poi questi widget vengono connessi a certi eventi
selfmainwindowconnect(delete_event selfdelete_event)quitconnect(activate selfdelete_event)circulationconnect(activate selfon_circulation_activate)memberconnect(activate selfon_member_activate)catalogconnect(activate selfon_catalog_activate)aboutconnect(activate selfon_about_activate)
Il delete_event egrave lrsquoevento scatenato durante la chiusura della finestra utilizzando lrsquoapposito bottone Lrsquoeventoactivate egrave lanciato quando il menu viene selezionato I widget sono connessi a certe funzioni di callback per certieventi
Possiamo vedere dal codice sopra che la finestra principale egrave connessa al metodo on_delete_event per ildelete_event Il widget quit egrave anche connesso allo stesso metodo per lrsquoevento activate
def on_delete_event(self args)gtkmain_quit()
La funzione di callback chiama semplicemente la funzione main_quit
Il codice
Ecco il file zcalibpy
import registryimport mainwindow
if __name__ == __main__registryinitialize()try
mainwindowmain()except KeyboardInterrupt
import syssysexit(1)
Qui vengono importati due moduli registry e mainwindow Poi il registro viene analizzato e viene chiamata lafunzione main di mainwindow Se lrsquoutente sta cercando di uscire dallrsquoapplicazione usando Ctrl+C il sistema usciragravenormalmente poicheacute abbiamo intercettato lrsquoeccezione KeyboardInterrupt
Questo egrave il modulo registrypy
import sysfrom zopecomponent import getGlobalSiteManager
from interfaces import IMember
23 La guida completa alla Zope Component Architecture 191
Documentazione di Plone Release 4
from interfaces import IBookfrom interfaces import ICirculationfrom interfaces import IDbOperation
def initialize_rdb()from interfaces import IRelationalDatabasefrom relationaldatabase import RelationalDatabasefrom member import MemberRDbOperationfrom catalog import BookRDbOperationfrom circulation import CirculationRDbOperation
gsm = getGlobalSiteManager()db = RelationalDatabase()gsmregisterUtility(db IRelationalDatabase)
gsmregisterAdapter(MemberRDbOperation(IMember)IDbOperation)
gsmregisterAdapter(BookRDbOperation(IBook)IDbOperation)
gsmregisterAdapter(CirculationRDbOperation(ICirculation)IDbOperation)
def initialize_odb()from interfaces import IObjectDatabasefrom objectdatabase import ObjectDatabasefrom member import MemberODbOperationfrom catalog import BookODbOperationfrom circulation import CirculationODbOperation
gsm = getGlobalSiteManager()db = ObjectDatabase()gsmregisterUtility(db IObjectDatabase)
gsmregisterAdapter(MemberODbOperation(IMember)IDbOperation)
gsmregisterAdapter(BookODbOperation(IBook)IDbOperation)
gsmregisterAdapter(CirculationODbOperation(ICirculation)IDbOperation)
def check_use_relational_db()use_rdb = Falsetry
arg = sysargv[1]if arg == -r
return Trueexcept IndexError
192 Chapter 2 Altri manuali
Documentazione di Plone Release 4
passreturn use_rdb
def initialize()use_rdb = check_use_relational_db()if use_rdb
initialize_rdb()else
initialize_odb()
Diamo uno sguardo alla funzione initialize che stiamo chiamando dal modulo principale zcalibpy Lafunzione initialize per prima cosa controlla quale db egrave in uso il database relazionale (RDB) o il database adoggetti (ODB) e questo controllo egrave fatto nella funzione check_use_relational_db Se egrave stata passata dallalinea di comando lrsquoopzione -r la funzione chiameragrave initialize_rdb altrimenti initialize_odb Se la fun-zione RDB viene chiamata essa configureragrave tutti i componenti legati a RDB altrimenti se viene chiamata la funzioneODB verranno configurati tutti i componenti legati a ODB
Ecco il file mainwindowpy
import osimport gtkimport gtkglade
from circulationwindow import circulationwindowfrom catalogwindow import catalogwindowfrom memberwindow import memberwindow
class MainWindow(object)
def __init__(self)curdir = ospathabspath(ospathdirname(__file__))xml = ospathjoin(curdir glade mainwindowglade)xmlobj = gtkgladeXML(xml)
selfmainwindow = xmlobjget_widget(mainwindow)circulation = xmlobjget_widget(circulation)member = xmlobjget_widget(member)quit = xmlobjget_widget(quit)catalog = xmlobjget_widget(catalog)about = xmlobjget_widget(about)
selfmainwindowconnect(delete_event selfdelete_event)quitconnect(activate selfdelete_event)
circulationconnect(activate selfon_circulation_activate)memberconnect(activate selfon_member_activate)catalogconnect(activate selfon_catalog_activate)aboutconnect(activate selfon_about_activate)
def delete_event(self args)gtkmain_quit()
def on_circulation_activate(self args)circulationwindowshow_all()
def on_member_activate(self args)memberwindowshow_all()
def on_catalog_activate(self args)
23 La guida completa alla Zope Component Architecture 193
Documentazione di Plone Release 4
catalogwindowshow_all()
def on_about_activate(self args)pass
def run(self)selfmainwindowshow_all()
def main()mainwindow = MainWindow()mainwindowrun()gtkmain()
La funzione main crea unrsquoistanza della classe MainWindow che inizializza tutti i widget
Ecco qui memberwindowpy
import osimport gtkimport gtkglade
from zopecomponent import getAdapter
from components import Memberfrom interfaces import IDbOperation
class MemberWindow(object)
def __init__(self)curdir = ospathabspath(ospathdirname(__file__))xml = ospathjoin(curdir glade memberwindowglade)xmlobj = gtkgladeXML(xml)
selfmemberwindow = xmlobjget_widget(memberwindow)selfnumber = xmlobjget_widget(number)selfname = xmlobjget_widget(name)add = xmlobjget_widget(add)update = xmlobjget_widget(update)delete = xmlobjget_widget(delete)close = xmlobjget_widget(close)selftreeview = xmlobjget_widget(treeview)
selfmemberwindowconnect(delete_event selfon_delete_event)addconnect(clicked selfon_add_clicked)updateconnect(clicked selfon_update_clicked)deleteconnect(clicked selfon_delete_clicked)closeconnect(clicked selfon_delete_event)
selfinitialize_list()
def show_all(self)selfpopulate_list_store()selfmemberwindowshow_all()
def populate_list_store(self)selflist_storeclear()member = Member()memberdboperation = getAdapter(member IDbOperation)
194 Chapter 2 Altri manuali
Documentazione di Plone Release 4
members = memberdboperationget()for member in members
number = membernumbername = membernameselflist_storeappend((member number name))
def on_delete_event(self args)selfmemberwindowhide()return True
def initialize_list(self)selflist_store = gtkListStore(object str str)selftreeviewset_model(selflist_store)tvcolumn = gtkTreeViewColumn(Member Number)selftreeviewappend_column(tvcolumn)
cell = gtkCellRendererText()tvcolumnpack_start(cell True)tvcolumnadd_attribute(cell text 1)
tvcolumn = gtkTreeViewColumn(Member Name)selftreeviewappend_column(tvcolumn)
cell = gtkCellRendererText()tvcolumnpack_start(cell True)tvcolumnadd_attribute(cell text 2)
def on_add_clicked(self args)number = selfnumberget_text()name = selfnameget_text()member = Member()membernumber = numbermembername = nameselfadd(member)selflist_storeappend((member number name))
def add(self member)memberdboperation = getAdapter(member IDbOperation)memberdboperationadd()
def on_update_clicked(self args)number = selfnumberget_text()name = selfnameget_text()treeselection = selftreeviewget_selection()model iter = treeselectionget_selected()if not iter
returnmember = selflist_storeget_value(iter 0)membernumber = numbermembername = nameselfupdate(member)selflist_storeset(iter 1 number 2 name)
def update(self member)memberdboperation = getAdapter(member IDbOperation)memberdboperationupdate()
def on_delete_clicked(self args)
23 La guida completa alla Zope Component Architecture 195
Documentazione di Plone Release 4
treeselection = selftreeviewget_selection()model iter = treeselectionget_selected()if not iter
returnmember = selflist_storeget_value(iter 0)selfdelete(member)selflist_storeremove(iter)
def delete(self member)memberdboperation = getAdapter(member IDbOperation)memberdboperationdelete()
memberwindow = MemberWindow()
Ecco qui componentspy
from zopeinterface import implements
from interfaces import IBookfrom interfaces import IMemberfrom interfaces import ICirculation
class Book(object)
implements(IBook)
barcode = title = author =
class Member(object)
implements(IMember)
number = name =
class Circulation(object)
implements(ICirculation)
book = Book()member = Member()
Ecco qui interfacespy
from zopeinterface import Interfacefrom zopeinterface import Attribute
class IBook(Interface)
barcode = Attribute(Barcode)author = Attribute(Author of book)title = Attribute(Title of book)
class IMember(Interface)
196 Chapter 2 Altri manuali
Documentazione di Plone Release 4
number = Attribute(ID number)name = Attribute(Name of member)
class ICirculation(Interface)
book = Attribute(A book)member = Attribute(A member)
class IRelationalDatabase(Interface)
def commit()pass
def rollback()pass
def cursor()pass
def get_next_id()pass
class IObjectDatabase(Interface)
def commit()pass
def rollback()pass
def container()pass
def get_next_id()pass
class IDbOperation(Interface)
def get()pass
def add()pass
def update()pass
def delete()pass
Ecco qui memberpy
from zopeinterface import implementsfrom zopecomponent import getUtility
23 La guida completa alla Zope Component Architecture 197
Documentazione di Plone Release 4
from zopecomponent import adapts
from components import Member
from interfaces import IRelationalDatabasefrom interfaces import IObjectDatabasefrom interfaces import IMemberfrom interfaces import IDbOperation
class MemberRDbOperation(object)
implements(IDbOperation)adapts(IMember)
def __init__(self member)selfmember = member
def get(self)db = getUtility(IRelationalDatabase)cr = dbcursor()number = selfmembernumberif number
crexecute(SELECTidnumbername
FROM membersWHERE number =
(number))else
crexecute(SELECTidnumbername
FROM members)rst = crfetchall()crclose()members = []for record in rst
id = record[id]number = record[number]name = record[name]member = Member()memberid = idmembernumber = numbermembername = namemembersappend(member)
return members
def add(self)db = getUtility(IRelationalDatabase)cr = dbcursor()next_id = dbget_next_id(members)number = selfmembernumbername = selfmembernamecrexecute(INSERT INTO members
(id number name)
198 Chapter 2 Altri manuali
Documentazione di Plone Release 4
VALUES ( )(next_id number name))
crclose()dbcommit()selfmemberid = next_id
def update(self)db = getUtility(IRelationalDatabase)cr = dbcursor()number = selfmembernumbername = selfmembernameid = selfmemberidcrexecute(UPDATE members
SETnumber = name =
WHERE id = (number name id))
crclose()dbcommit()
def delete(self)db = getUtility(IRelationalDatabase)cr = dbcursor()id = selfmemberidcrexecute(DELETE FROM members
WHERE id = (id))
crclose()dbcommit()
class MemberODbOperation(object)
implements(IDbOperation)adapts(IMember)
def __init__(self member)selfmember = member
def get(self)db = getUtility(IObjectDatabase)zcalibdb = dbcontainer()members = zcalibdb[members]return membersvalues()
def add(self)db = getUtility(IObjectDatabase)zcalibdb = dbcontainer()members = zcalibdb[members]number = selfmembernumberif number in [xnumber for x in membersvalues()]
dbrollback()raise Exception(Duplicate key)
next_id = dbget_next_id(members)selfmemberid = next_idmembers[next_id] = selfmemberdbcommit()
23 La guida completa alla Zope Component Architecture 199
Documentazione di Plone Release 4
def update(self)db = getUtility(IObjectDatabase)zcalibdb = dbcontainer()members = zcalibdb[members]id = selfmemberidmembers[id] = selfmemberdbcommit()
def delete(self)db = getUtility(IObjectDatabase)zcalibdb = dbcontainer()members = zcalibdb[members]id = selfmemberiddel members[id]dbcommit()
PySQLite
ZODB
Conclusions
239 Riferimenti
adaptedBy
Questa funzione permette di trovare le interfacce adattate
bull Posizione zopecomponent
bull Firma adaptedBy(object)
Esempio
gtgtgt from zopeinterface import implementsgtgtgt from zopecomponent import adaptsgtgtgt from zopecomponent import adaptedBy
gtgtgt class FrontDeskNG(object) implements(IDesk) adapts(IGuest) def __init__(self guest) selfguest = guest
gtgtgt adaptedBy(FrontDeskNG)(ltInterfaceClass __builtin__IGuestgt)
adapter
Qualsiasi tipo di oggetto puograve essere un adattatore egrave possibile utilizzare il decoratore adapter per dichiarare che unoggetto chiamabile adatta qualche interfaccia (o classe)
bull Posizione zopecomponent
200 Chapter 2 Altri manuali
Documentazione di Plone Release 4
bull Firma adapter(interfaces)
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implementergtgtgt from zopecomponent import adaptergtgtgt from zopeinterface import implements
gtgtgt class IJob(Interface) A job
gtgtgt class Job(object) implements(IJob)
gtgtgt class IPerson(Interface) name = Attribute(Name) job = Attribute(Job)
gtgtgt class Person(object) implements(IPerson) name = None job = None
gtgtgt implementer(IJob) adapter(IPerson) def personJob(person) return personjob
gtgtgt jack = Person()gtgtgt jackname = Jackgtgtgt jackjob = Job()gtgtgt personJob(jack)ltJob object at gt
adapts
Questa funzione permette di dichiarare le interfacce adattate dallrsquoadapter
bull Posizione zopecomponent
bull Firma adapts(interfaces)
Esempio
gtgtgt from zopeinterface import implementsgtgtgt from zopecomponent import adapts
gtgtgt class FrontDeskNG(object) implements(IDesk) adapts(IGuest) def __init__(self guest) selfguest = guest
23 La guida completa alla Zope Component Architecture 201
Documentazione di Plone Release 4
def register(self)
next_id = get_next_id()
bookings_db[next_id] =
name guestname
place guestplace
phone guestphone
alsoProvides
Dichiara le interfacce fornite direttamente da un oggetto Gli argomenti dopo lrsquooggetto sono una o piugrave interfacce Leinterfacce fornite vengono aggiunte alle interfacce giagrave dichiarate per lrsquooggetto
bull Posizione zopeinterface
bull Firma alsoProvides(object interfaces)
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implementsgtgtgt from zopeinterface import alsoProvides
gtgtgt class IPerson(Interface) name = Attribute(Name of person)
gtgtgt class IStudent(Interface) college = Attribute(Name of college)
gtgtgt class Person(object) implements(IDesk) name = u
gtgtgt jack = Person()gtgtgt jackname = Jackgtgtgt jackcollege = New Collegegtgtgt alsoProvides(jack IStudent)
Si puograve testare cosigrave
gtgtgt from zopeinterface import providedBygtgtgt IStudent in providedBy(jack)True
Attribute
Con questa classe egrave possibile definire i normali attributi di una interfaccia
bull Posizione zopeinterface
bull Firma Attribute(name doc=rsquolsquo)
bull Vedi anche Interface
202 Chapter 2 Altri manuali
Documentazione di Plone Release 4
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interface
gtgtgt class IPerson(Interface) name = Attribute(Name of person) email = Attribute(Email Address)
classImplements
Dichiara le interfacce aggiuntive implementate dalle istanze di una classe Gli argomenti dopo la classe sono una opiugrave interfacce Le interfacce fornite vengono aggiunte alle interfacce giagrave dichiarate
bull Posizione zopeinterface
bull Firma classImplements(cls interfaces)
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implementsgtgtgt from zopeinterface import classImplements
gtgtgt class IPerson(Interface) name = Attribute(Name of person)
gtgtgt class IStudent(Interface) college = Attribute(Name of college)
gtgtgt class Person(object) implements(IDesk) name = u college = u
gtgtgt classImplements(Person IStudent)gtgtgt jack = Person()gtgtgt jackname = Jackgtgtgt jackcollege = New College
Si puograve testare cosigrave
gtgtgt from zopeinterface import providedBygtgtgt IStudent in providedBy(jack)True
classImplementsOnly
Dichiara le sole interfacce implementate dalle istanze di una classe Gli argomenti dopo la classe sono una o piugraveinterfacce Le interfacce fornite rimpiazzano le dichiarazioni precedenti
bull Posizione zopeinterface
23 La guida completa alla Zope Component Architecture 203
Documentazione di Plone Release 4
bull Firma classImplementsOnly(cls interfaces)
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implementsgtgtgt from zopeinterface import classImplementsOnly
gtgtgt class IPerson(Interface) name = Attribute(Name of person)
gtgtgt class IStudent(Interface) college = Attribute(Name of college)
gtgtgt class Person(object) implements(IPerson) college = u
gtgtgt classImplementsOnly(Person IStudent)gtgtgt jack = Person()gtgtgt jackcollege = New College
Si puograve testare cosigrave
gtgtgt from zopeinterface import providedBygtgtgt IPerson in providedBy(jack)Falsegtgtgt IStudent in providedBy(jack)True
classProvides
Normalmente se una classe implementa una particolare interfaccia lrsquoistanza di questa classe forniragrave lrsquointerfaccia im-plementata da questa classe Se perograve si vuole che la classe stessa fornisca unrsquointerfaccia si puograve utilizzare questafunzione
bull Posizione zopeinterface
bull Firma classProvides(interfaces)
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import classProvides
gtgtgt class IPerson(Interface) name = Attribute(Name of person)
gtgtgt class Person(object) classProvides(IPerson) name = uJack
204 Chapter 2 Altri manuali
Documentazione di Plone Release 4
Si puograve testare cosigrave
gtgtgt from zopeinterface import providedBygtgtgt IPerson in providedBy(Person)True
ComponentLookupError
Questa egrave lrsquoeccezione che viene sollevata quando una ricerca di un componente fallisce
Esempio
gtgtgt class IPerson(Interface) name = Attribute(Name of person)
gtgtgt person = object()gtgtgt getAdapter(person IPerson not-exists)Traceback (most recent call last)ComponentLookupError
createObject
Crea un oggetto usando una factory
Cerca la named factory nel sito corrente e la chiama con i parametri forniti Se non puograve essere trovata alcuna factoryviene sollevata lrsquoeccezione ComponentLookupError altrimenti restituisce lrsquooggetto creato
Puograve essere fornito come argomento keyword un context per forzare la ricerca della factory in una posizione diversadal sito corrente Ovviamente questo significa che egrave impossibile passare un argomento keyword alla factory chiamatoldquocontextrdquo
bull Posizione zopecomponent
bull Firma createObject(factory_name args kwargs)
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
gtgtgt class IDatabase(Interface) def getConnection() Return connection object
gtgtgt class FakeDb(object) implements(IDatabase) def getConnection(self) return connection
gtgtgt from zopecomponentfactory import Factory
gtgtgt factory = Factory(FakeDb FakeDb)
23 La guida completa alla Zope Component Architecture 205
Documentazione di Plone Release 4
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt from zopecomponentinterfaces import IFactorygtgtgt gsmregisterUtility(factory IFactory fakedb)
gtgtgt from zopecomponent import createObjectgtgtgt createObject(fakedb)ltFakeDb object at gt
Declaration
Non deve essere usata direttamente
directlyProvidedBy
Questa funzione restituiragrave le interfacce fornite direttamente dallrsquooggetto passato come argomento
bull Posizione zopeinterface
bull Firma directlyProvidedBy(object)
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interface
gtgtgt class IPerson(Interface) name = Attribute(Name of person)
gtgtgt class IStudent(Interface) college = Attribute(Name of college)
gtgtgt class ISmartPerson(Interface) pass
gtgtgt class Person(object) implements(IPerson) name = u
gtgtgt jack = Person()gtgtgt jackname = uJackgtgtgt jackcollege = New Collegegtgtgt alsoProvides(jack ISmartPerson IStudent)
gtgtgt from zopeinterface import directlyProvidedBy
gtgtgt jack_dp = directlyProvidedBy(jack)gtgtgt IPerson in jack_dpinterfaces()Falsegtgtgt IStudent in jack_dpinterfaces()Truegtgtgt ISmartPerson in jack_dpinterfaces()True
206 Chapter 2 Altri manuali
Documentazione di Plone Release 4
directlyProvides
Dichiara le interfacce fornite direttamente da un oggetto Gli argomenti dopo lrsquooggetto sono una o piugrave interfacce Leinterfacce fornite rimpiazzano le interfacce giagrave dichiarate in precedenza dallrsquooggetto
bull Posizione zopeinterface
bull Firma directlyProvides(object interfaces)
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interface
gtgtgt class IPerson(Interface) name = Attribute(Name of person)
gtgtgt class IStudent(Interface) college = Attribute(Name of college)
gtgtgt class ISmartPerson(Interface) pass
gtgtgt class Person(object) implements(IPerson) name = u
gtgtgt jack = Person()gtgtgt jackname = uJackgtgtgt jackcollege = New Collegegtgtgt alsoProvides(jack ISmartPerson IStudent)
gtgtgt from zopeinterface import directlyProvidedBy
gtgtgt jack_dp = directlyProvidedBy(jack)gtgtgt ISmartPerson in jack_dpinterfaces()Truegtgtgt IPerson in jack_dpinterfaces()Falsegtgtgt IStudent in jack_dpinterfaces()Truegtgtgt from zopeinterface import providedBy
gtgtgt ISmartPerson in providedBy(jack)True
gtgtgt from zopeinterface import directlyProvidesgtgtgt directlyProvides(jack IStudent)
gtgtgt jack_dp = directlyProvidedBy(jack)gtgtgt ISmartPerson in jack_dpinterfaces()Falsegtgtgt IPerson in jack_dpinterfaces()Falsegtgtgt IStudent in jack_dpinterfaces()True
23 La guida completa alla Zope Component Architecture 207
Documentazione di Plone Release 4
gtgtgt ISmartPerson in providedBy(jack)False
getAdapter
Recupera un adapter per un oggetto verso una specifica interfaccia Restituisce un adapter che puograve adattare lrsquooggettoallrsquointerfaccia Se non puograve essere trovato alcun adapter solleva ComponentLookupError
bull Posizione zopeinterface
bull Firma getAdapter(object interface=Interface name=ursquolsquo context=None)
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interface
gtgtgt class IDesk(Interface) A frontdesk will register objects details def register() Register objects details
gtgtgt from zopeinterface import implementsgtgtgt from zopecomponent import adapts
gtgtgt class FrontDeskNG(object) implements(IDesk) adapts(IGuest) def __init__(self guest) selfguest = guest def register(self) next_id = get_next_id() bookings_db[next_id] = name guestname place guestplace phone guestphone
gtgtgt class Guest(object) implements(IGuest) def __init__(self name place) selfname = name selfplace = place
gtgtgt jack = Guest(Jack Bangalore)gtgtgt jack_frontdesk = FrontDeskNG(jack)
gtgtgt IDeskprovidedBy(jack_frontdesk)True
gtgtgt from zopecomponent import getGlobalSiteManager
208 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt gsm = getGlobalSiteManager()gtgtgt gsmregisterAdapter(FrontDeskNG (IGuest) IDesk ng)
gtgtgt getAdapter(jack IDesk ng)ltFrontDeskNG object at gt
getAdapterInContext
Al posto di questa funzione utilizzare lrsquoargomento context della funzione getAdapter
bull Posizione zopecomponent
bull Firma getAdapterInContext(object interface context)
bull Vedi anche queryAdapterInContext
Esempio
gtgtgt from zopecomponentglobalregistry import BaseGlobalComponentsgtgtgt from zopecomponent import IComponentLookupgtgtgt sm = BaseGlobalComponents()
gtgtgt class Context(object) def __init__(self sm) selfsm = sm def __conform__(self interface) if interfaceisOrExtends(IComponentLookup) return selfsm
gtgtgt context = Context(sm)
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interface
gtgtgt class IDesk(Interface) A frontdesk will register objects details def register() Register objects details
gtgtgt from zopeinterface import implementsgtgtgt from zopecomponent import adapts
gtgtgt class FrontDeskNG(object) implements(IDesk) adapts(IGuest) def __init__(self guest) selfguest = guest def register(self) next_id = get_next_id() bookings_db[next_id] = name guestname place guestplace
23 La guida completa alla Zope Component Architecture 209
Documentazione di Plone Release 4
phone guestphone
gtgtgt class Guest(object) implements(IGuest) def __init__(self name place) selfname = name selfplace = place
gtgtgt jack = Guest(Jack Bangalore)gtgtgt jack_frontdesk = FrontDeskNG(jack)
gtgtgt IDeskprovidedBy(jack_frontdesk)True
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()gtgtgt smregisterAdapter(FrontDeskNG (IGuest) IDesk)
gtgtgt from zopecomponent import getAdapterInContext
gtgtgt getAdapterInContext(jack IDesk sm)ltFrontDeskNG object at gt
getAdapters
Cerca tutti gli adapter corrispondenti per degli oggetti e per una interfaccia fornita Restituisce una lista di adapter checorrispondono Se un adapter ha un nome viene restituito solo lrsquoadapter piugrave specifico
bull Posizione zopecomponent
bull Firma getAdapters(objects provided context=None)
Esempio
gtgtgt from zopeinterface import implementsgtgtgt from zopecomponent import adapts
gtgtgt class FrontDeskNG(object) implements(IDesk) adapts(IGuest) def __init__(self guest) selfguest = guest def register(self) next_id = get_next_id() bookings_db[next_id] = name guestname place guestplace phone guestphone
gtgtgt jack = Guest(Jack Bangalore)
210 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt jack_frontdesk = FrontDeskNG(jack)
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt gsmregisterAdapter(FrontDeskNG name=ng)
gtgtgt from zopecomponent import getAdaptersgtgtgt list(getAdapters((jack) IDesk))[(ung ltFrontDeskNG object at gt)]
getAllUtilitiesRegisteredFor
Restituisce tutte le utility registrate per unrsquointerfaccia Questo include anche le utility sovrascritte Il valore di ritornoegrave un iterabile di istanze di utility
bull Posizione zopecomponent
bull Firma getAllUtilitiesRegisteredFor(interface)
Esempio
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
gtgtgt class IGreeter(Interface) def greet(name) say hello
gtgtgt class Greeter(object) implements(IGreeter) def greet(self name) print Hello name
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt greet = Greeter()gtgtgt gsmregisterUtility(greet IGreeter)
gtgtgt from zopecomponent import getAllUtilitiesRegisteredFor
gtgtgt getAllUtilitiesRegisteredFor(IGreeter)[ltGreeter object at gt]
getFactoriesFor
Restituisce una tupla (nome factory) delle factory registrate che creano oggetti che implementano lrsquointerfaccia fornita
bull Posizione zopecomponent
bull Firma getFactoriesFor(interface context=None)
Esempio
23 La guida completa alla Zope Component Architecture 211
Documentazione di Plone Release 4
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
gtgtgt class IDatabase(Interface) def getConnection() Return connection object
gtgtgt class FakeDb(object) implements(IDatabase) def getConnection(self) return connection
gtgtgt from zopecomponentfactory import Factory
gtgtgt factory = Factory(FakeDb FakeDb)
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt from zopecomponentinterfaces import IFactorygtgtgt gsmregisterUtility(factory IFactory fakedb)
gtgtgt from zopecomponent import getFactoriesFor
gtgtgt list(getFactoriesFor(IDatabase))[(ufakedb ltFactory for ltclass FakeDbgtgt)]
getFactoryInterfaces
Trova le interfacce implementate da una factory Trova la factory piugrave vicina al contesto con il nome specificato erestituisce lrsquointerfaccia o la tupla dellrsquointerfaccia che gli oggetti istanza creati forniranno
bull Posizione zopecomponent
bull Firma getFactoryInterfaces(name context=None)
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
gtgtgt class IDatabase(Interface) def getConnection() Return connection object
gtgtgt class FakeDb(object) implements(IDatabase) def getConnection(self) return connection
212 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt from zopecomponentfactory import Factory
gtgtgt factory = Factory(FakeDb FakeDb)
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt from zopecomponentinterfaces import IFactorygtgtgt gsmregisterUtility(factory IFactory fakedb)
gtgtgt from zopecomponent import getFactoryInterfaces
gtgtgt getFactoryInterfaces(fakedb)ltimplementedBy __builtin__FakeDbgt
getGlobalSiteManager
Restituisce il global site manager Questa funzione non dovrebbe mai fallire e dovrebbe sempre restituire un oggettoche fornisce IGlobalSiteManager
bull Posizione zopecomponent
bull Firma getGlobalSiteManager()
Esempio
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt from zopecomponent import globalSiteManagergtgtgt gsm = getGlobalSiteManager()gtgtgt gsm is globalSiteManagerTrue
getMultiAdapter
Cerca e restituisce un multi-adapter che puograve adattare degli oggetti ad una certa interfaccia Se non puograve essere trovatoalcun adapter solleva ComponentLookupError La stringa vuota come nome egrave riservata per gli adapter senzanome I metodi per gli adapter senza nome spesso chiamano i metodi per i named adapter con una stringa vuota comenome
bull Posizione zopecomponent
bull Firma getMultiAdapter(objects interface=Interface name=rsquolsquo context=None)
bull Vedi anche queryMultiAdapter
Esempio
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implementsgtgtgt from zopecomponent import adapts
gtgtgt class IAdapteeOne(Interface) pass
gtgtgt class IAdapteeTwo(Interface) pass
gtgtgt class IFunctionality(Interface)
23 La guida completa alla Zope Component Architecture 213
Documentazione di Plone Release 4
pass
gtgtgt class MyFunctionality(object) implements(IFunctionality) adapts(IAdapteeOne IAdapteeTwo) def __init__(self one two) selfone = one selftwo = two
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt gsmregisterAdapter(MyFunctionality)
gtgtgt class One(object) implements(IAdapteeOne)
gtgtgt class Two(object) implements(IAdapteeTwo)
gtgtgt one = One()gtgtgt two = Two()
gtgtgt from zopecomponent import getMultiAdapter
gtgtgt getMultiAdapter((onetwo) IFunctionality)ltMyFunctionality object at gt
gtgtgt myfunctionality = getMultiAdapter((onetwo) IFunctionality)gtgtgt myfunctionalityoneltOne object at gtgtgtgt myfunctionalitytwoltTwo object at gt
getSiteManager
Prende il site manager piugrave vicino al contesto dato Se il context egrave None restituisce il global site manager Se il contextnon egrave None ci si aspetta di poter trovare un adapter dal context a IComponentLookup Se non viene trovato alcunadapter viene sollevato ComponentLookupError
bull Posizione zopecomponent
bull Firma getSiteManager(context=None)
Esempio 1
gtgtgt from zopecomponentglobalregistry import BaseGlobalComponentsgtgtgt from zopecomponent import IComponentLookupgtgtgt sm = BaseGlobalComponents()
gtgtgt class Context(object) def __init__(self sm) selfsm = sm def __conform__(self interface) if interfaceisOrExtends(IComponentLookup) return selfsm
214 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt context = Context(sm)
gtgtgt from zopecomponent import getSiteManager
gtgtgt lsm = getSiteManager(context)gtgtgt lsm is smTrue
Esempio 2
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt sm = getSiteManager()gtgtgt gsm is smTrue
getUtilitiesFor
Ricerca le utility registrate che forniscono unrsquointerfaccia Restituisce un iterabile delle coppie nome-utility
bull Posizione zopecomponent
bull Firma getUtilitiesFor(interface)
Esempio
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
gtgtgt class IGreeter(Interface) def greet(name) say hello
gtgtgt class Greeter(object) implements(IGreeter) def greet(self name) print Hello name
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt greet = Greeter()gtgtgt gsmregisterUtility(greet IGreeter)
gtgtgt from zopecomponent import getUtilitiesFor
gtgtgt list(getUtilitiesFor(IGreeter))[(u ltGreeter object at gt)]
getUtility
Recupera lrsquoutility che fornisce lrsquointerfaccia Restituisce lrsquoutility piugrave vicina al contesto e che implementa una unaspecifica interfaccia Se non negrave vengono trovate viene sollevata ComponentLookupError
bull Posizione zopecomponent
23 La guida completa alla Zope Component Architecture 215
Documentazione di Plone Release 4
bull Firma getUtility(interface name=rsquolsquo context=None)
Esempio
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
gtgtgt class IGreeter(Interface) def greet(name) say hello
gtgtgt class Greeter(object) implements(IGreeter) def greet(self name) return Hello + name
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt greet = Greeter()gtgtgt gsmregisterUtility(greet IGreeter)
gtgtgt from zopecomponent import getUtility
gtgtgt getUtility(IGreeter)greet(Jack)Hello Jack
handle
Chiama tutti gli handler per gli oggetti dati Gli handler sono fabbriche di subscription adapter che non restituiscononulla Essi fanno tutto il loro lavoro quando vengono chiamati Gli handler sono tipicamente utilizzati per gestire glieventi
bull Posizione zopecomponent
bull Firma handle(objects)
Esempio
gtgtgt import datetime
gtgtgt def documentCreated(event) eventdoccreated = datetimedatetimeutcnow()
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import implements
gtgtgt class IDocumentCreated(Interface) doc = Attribute(The document that was created)
gtgtgt class DocumentCreated(object) implements(IDocumentCreated) def __init__(self doc) selfdoc = doc
216 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt def documentCreated(event) eventdoccreated = datetimedatetimeutcnow()
gtgtgt from zopecomponent import adapter
gtgtgt adapter(IDocumentCreated) def documentCreated(event) eventdoccreated = datetimedatetimeutcnow()
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt gsmregisterHandler(documentCreated)
gtgtgt from zopecomponent import handle
gtgtgt handle(DocumentCreated(doc))gtgtgt doccreated__class____name__datetime
implementedBy
Restituisce le interfacce implementate dalle istanze di una certa classe
bull Posizione zopeinterface
bull Firma implementedBy(class_)
Esempio 1
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
gtgtgt class IGreeter(Interface) def greet(name) say hello
gtgtgt class Greeter(object) implements(IGreeter) def greet(self name) print Hello name
gtgtgt from zopeinterface import implementedBygtgtgt implementedBy(Greeter)ltimplementedBy __builtin__Greetergt
Esempio 2
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
gtgtgt class IPerson(Interface) name = Attribute(Name of person)
23 La guida completa alla Zope Component Architecture 217
Documentazione di Plone Release 4
gtgtgt class ISpecial(Interface) pass
gtgtgt class Person(object) implements(IPerson) name = u
gtgtgt from zopeinterface import classImplementsgtgtgt classImplements(Person ISpecial)
gtgtgt from zopeinterface import implementedBy
To get a list of all interfaces implemented by that class
gtgtgt [x__name__ for x in implementedBy(Person)][IPerson ISpecial]
implementer
Crea un decoratore per dichiarare le interfacce implementate da una factory Viene restituito un oggetto chiamabileche fa una dichiarazione di implementazione sugli oggetti che gli vengono passati
bull Posizione zopeinterface
bull Firma implementer(interfaces)
Esempio
gtgtgt from zopeinterface import implementergtgtgt class IFoo(Interface) passgtgtgt class Foo(object) implements(IFoo)
gtgtgt implementer(IFoo) def foocreator() foo = Foo() return foogtgtgt list(implementedBy(foocreator))[ltInterfaceClass __builtin__IFoogt]
implements
Dichiara le interfacce implementate dalle istanze di una classe Questa funzione egrave chiamata allrsquointerno di unadefinizione di una classe Gli argomenti sono una o piugrave interfacce Le interfacce fornite sono aggiunte a quelle giagravedichiarate in precedenza Le dichiarazioni precedenti incluse le dichiarazioni delle classi base vengono preservate ameno che non sia stata utilizzata implementsOnly
bull Posizione zopeinterface
bull Firma implements(interfaces)
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
218 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt class IPerson(Interface) name = Attribute(Name of person)
gtgtgt class Person(object) implements(IPerson) name = u
gtgtgt jack = Person()gtgtgt jackname = Jack
Si puograve testare cosigrave
gtgtgt from zopeinterface import providedBygtgtgt IPerson in providedBy(jack)True
implementsOnly
Dichiara le sole interfacce implementate dalle istanze di una classe Questa funzione egrave chiamata allrsquointerno di unadefinizione di classe Gli argomenti sono una o piugrave interfacce Le dichiarazioni precedenti incluse le dichiarazionidelle classi base vengono sovrascritte
bull Posizione zopeinterface
bull Firma implementsOnly(interfaces)
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implementsgtgtgt from zopeinterface import implementsOnly
gtgtgt class IPerson(Interface) name = Attribute(Name of person)
gtgtgt class IStudent(Interface) college = Attribute(Name of college)
gtgtgt class Person(object) implements(IPerson) name = u
gtgtgt class NewPerson(Person) implementsOnly(IStudent) college = u
gtgtgt jack = NewPerson()gtgtgt jackcollege = New College
Si puograve testare cosigrave
gtgtgt from zopeinterface import providedBy
23 La guida completa alla Zope Component Architecture 219
Documentazione di Plone Release 4
gtgtgt IPerson in providedBy(jack)Falsegtgtgt IStudent in providedBy(jack)True
Interface
Con questa classe si possono definire le interfacce Per definire unrsquointerfaccia basta ereditare dalla classeInterface
bull Posizione zopeinterface
bull Firma Interface(name doc=rsquolsquo)
Esempio 1
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interface
gtgtgt class IPerson(Interface) name = Attribute(Name of person) email = Attribute(Email Address)
Esempio 2
gtgtgt from zopeinterface import Interface
gtgtgt class IHost(Interface) def goodmorning(guest) Say good morning to guest
moduleProvides
Dichiara le interfacce fornite da un modulo Questa funzione egrave utilizzata nella definizione di un modulo Gli argomentisono una o piugrave interfacce Le interfacce fornite vengono utilizzate per creare la definizione di interfaccia degli oggettidiretti del modulo Verragrave sollevato un errore se il modulo ha giagrave una dichiarazione di interfaccia In altre parole egrave unerrore chiamare questa funzione piugrave di una volta nella definizione di un modulo
Questa funzione egrave fornita per comoditagrave Essa fornisce un modo piugrave conveniente per chiamare directlyProvidessu un modulo
bull Posizione zopeinterface
bull Firma moduleProvides(interfaces)
bull Vedi anche directlyProvides
You can see an example usage in zopecomponent source itself The __init__py file has a statement like this
moduleProvides(IComponentArchitectureIComponentRegistrationConvenience)
So the zopecomponent provides two interfaces IComponentArchitecture and IComponentRegistrationConvenience
220 Chapter 2 Altri manuali
Documentazione di Plone Release 4
noLongerProvides
Rimuove unrsquointerfaccia dalla lista delle interfacce fornite direttamente da un oggetto
bull Posizione zopeinterface
bull Firma noLongerProvides(object interface)
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implementsgtgtgt from zopeinterface import classImplements
gtgtgt class IPerson(Interface) name = Attribute(Name of person)
gtgtgt class IStudent(Interface) college = Attribute(Name of college)
gtgtgt class Person(object) implements(IPerson) name = u
gtgtgt jack = Person()gtgtgt jackname = Jackgtgtgt jackcollege = New Collegegtgtgt directlyProvides(jack IStudent)
Si puograve testare cosigrave
gtgtgt from zopeinterface import providedBygtgtgt IPerson in providedBy(jack)Truegtgtgt IStudent in providedBy(jack)Truegtgtgt from zopeinterface import noLongerProvidesgtgtgt noLongerProvides(jack IStudent)gtgtgt IPerson in providedBy(jack)Truegtgtgt IStudent in providedBy(jack)False
provideAdapter
Si raccomanda di utilizzare registerAdapter al posto di questa funzione
provideHandler
Si raccomanda di utilizzare registerHandler al posto di questa funzione
23 La guida completa alla Zope Component Architecture 221
Documentazione di Plone Release 4
provideSubscriptionAdapter
Si raccomanda di utilizzare registerSubscriptionAdapter al posto di questa funzione
provideUtility
Si raccomanda di utilizzare registerUtility al posto di questa funzione
providedBy
Verifica se lrsquointerfaccia egrave fornita dallrsquooggetto dato Restituisce true se lrsquooggetto dichiara di fornire lrsquointerfaccia anchese dichiara di fornire unrsquointerfaccia che estende lrsquointerfaccia data
bull Posizione zopeinterface
bull Firma providedBy(object)
Esempio 1
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
gtgtgt class IPerson(Interface) name = Attribute(Name of person)
gtgtgt class Person(object) implements(IPerson) name = u
gtgtgt jack = Person()gtgtgt jackname = Jack
Si puograve testare cosigrave
gtgtgt from zopeinterface import providedBygtgtgt IPerson in providedBy(jack)True
Esempio 2
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
gtgtgt class IPerson(Interface) name = Attribute(Name of person)
gtgtgt class ISpecial(Interface) pass
gtgtgt class Person(object) implements(IPerson) name = u
gtgtgt from zopeinterface import classImplements
222 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt classImplements(Person ISpecial)gtgtgt from zopeinterface import providedBygtgtgt jack = Person()gtgtgt jackname = Jack
Ecco come vere la lista di tutte le interfacce fornite da questo oggetto
gtgtgt [x__name__ for x in providedBy(jack)][IPerson ISpecial]
queryAdapter
Cerca e restituisce un named adapter che puograve adattare un oggetto ad unrsquointerfaccia Se non puograve essere trovato alcunadapter restituisce il default
bull Posizione zopecomponent
bull Firma queryAdapter(object interface=Interface name=ursquolsquo default=None context=None)
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interface
gtgtgt class IDesk(Interface) A frontdesk will register objects details def register() Register objects details
gtgtgt from zopeinterface import implementsgtgtgt from zopecomponent import adapts
gtgtgt class FrontDeskNG(object) implements(IDesk) adapts(IGuest) def __init__(self guest) selfguest = guest def register(self) next_id = get_next_id() bookings_db[next_id] = name guestname place guestplace phone guestphone
gtgtgt class Guest(object) implements(IGuest) def __init__(self name place) selfname = name selfplace = place
23 La guida completa alla Zope Component Architecture 223
Documentazione di Plone Release 4
gtgtgt jack = Guest(Jack Bangalore)gtgtgt jack_frontdesk = FrontDeskNG(jack)
gtgtgt IDeskprovidedBy(jack_frontdesk)True
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()gtgtgt gsmregisterAdapter(FrontDeskNG (IGuest) IDesk ng)
gtgtgt queryAdapter(jack IDesk ng)ltFrontDeskNG object at gt
queryAdapterInContext
Cerca uno speciale adapter per adattare un oggetto a unrsquointerfaccia
Nota Questo metodo dovrebbe essere utilizzato solo se egrave necessario fornire un context personalizzato per fornire unaricerca personalizzata Altrimenti chiamare lrsquointerfaccia come in
interface(object default)
Restituisce un adapter che puograve adattare un oggetto a unrsquointerfaccia Se non puograve essere trovato alcun adapter restituisceil default
Il context viene adattato a IServiceService e viene utilizzato il servizio lsquoAdaptersrsquo di questo adapter
Se lrsquooggetto ha un metodo __conform__ questo metodo viene chiamato con lrsquointerfaccia richiesta Se il metodo resti-tuisce un valore diverso da None questo valore viene restituito Altrimenti se lrsquooggetto implementa giagrave lrsquointerfacciaviene restituito lrsquooggetto
bull Posizione zopecomponent
bull Firma queryAdapterInContext(object interface context default=None)
bull Vedi anche getAdapterInContext
Esempio
gtgtgt from zopecomponentglobalregistry import BaseGlobalComponentsgtgtgt from zopecomponent import IComponentLookupgtgtgt sm = BaseGlobalComponents()
gtgtgt class Context(object) def __init__(self sm) selfsm = sm def __conform__(self interface) if interfaceisOrExtends(IComponentLookup) return selfsm
gtgtgt context = Context(sm)
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interface
gtgtgt class IDesk(Interface) A frontdesk will register objects details
224 Chapter 2 Altri manuali
Documentazione di Plone Release 4
def register()
Register objects details
gtgtgt from zopeinterface import implementsgtgtgt from zopecomponent import adapts
gtgtgt class FrontDeskNG(object) implements(IDesk) adapts(IGuest) def __init__(self guest) selfguest = guest def register(self) next_id = get_next_id() bookings_db[next_id] = name guestname place guestplace phone guestphone
gtgtgt class Guest(object) implements(IGuest) def __init__(self name place) selfname = name selfplace = place
gtgtgt jack = Guest(Jack Bangalore)gtgtgt jack_frontdesk = FrontDeskNG(jack)
gtgtgt IDeskprovidedBy(jack_frontdesk)True
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()gtgtgt smregisterAdapter(FrontDeskNG (IGuest) IDesk)
gtgtgt from zopecomponent import queryAdapterInContext
gtgtgt queryAdapterInContext(jack IDesk sm)ltFrontDeskNG object at gt
queryMultiAdapter
Cerca e restituisce un multi-adapter per adattare degli oggetti a unrsquointerfaccia Se non puograve essere trovato alcun adapterrestituisce il default Il nome costituito dalla stringa vuota egrave riservato per gli adapters senza nome I metodi per gliunnamed adapter spesso chiamano i metodi per i named adapter con una stringa vuota come nome
bull Posizione zopecomponent
bull Firma queryMultiAdapter(objects interface=Interface name=ursquolsquo default=None context=None)
bull Vedi anche getMultiAdapter
23 La guida completa alla Zope Component Architecture 225
Documentazione di Plone Release 4
Esempio
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implementsgtgtgt from zopecomponent import adapts
gtgtgt class IAdapteeOne(Interface) pass
gtgtgt class IAdapteeTwo(Interface) pass
gtgtgt class IFunctionality(Interface) pass
gtgtgt class MyFunctionality(object) implements(IFunctionality) adapts(IAdapteeOne IAdapteeTwo) def __init__(self one two) selfone = one selftwo = two
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt gsmregisterAdapter(MyFunctionality)
gtgtgt class One(object) implements(IAdapteeOne)
gtgtgt class Two(object) implements(IAdapteeTwo)
gtgtgt one = One()gtgtgt two = Two()
gtgtgt from zopecomponent import queryMultiAdapter
gtgtgt getMultiAdapter((onetwo) IFunctionality)ltMyFunctionality object at gt
gtgtgt myfunctionality = queryMultiAdapter((onetwo) IFunctionality)gtgtgt myfunctionalityoneltOne object at gtgtgtgt myfunctionalitytwoltTwo object at gt
queryUtility
Questa funzione egrave utilizzata per cercare una utility che fornisce una certa interfaccia Se non trova alcuna utilityrestituisce il default
bull Posizione zopecomponent
bull Firma queryUtility(interface name=rsquolsquo default=None)
Esempio
226 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
gtgtgt class IGreeter(Interface) def greet(name) say hello
gtgtgt class Greeter(object) implements(IGreeter) def greet(self name) return Hello + name
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt greet = Greeter()gtgtgt gsmregisterUtility(greet IGreeter)
gtgtgt from zopecomponent import queryUtility
gtgtgt queryUtility(IGreeter)greet(Jack)Hello Jack
registerAdapter
Questa funzione registra una factory di adapter
bull Posizione zopecomponent - IComponentRegistry
bull Firma registerAdapter(factory required=None provided=None name=ursquolsquo info=ursquolsquo)
bull Vedi anche unregisterAdapter
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interface
gtgtgt class IDesk(Interface) A frontdesk will register objects details def register() Register objects details
gtgtgt from zopeinterface import implementsgtgtgt from zopecomponent import adapts
gtgtgt class FrontDeskNG(object) implements(IDesk) adapts(IGuest) def __init__(self guest) selfguest = guest def register(self)
23 La guida completa alla Zope Component Architecture 227
Documentazione di Plone Release 4
next_id = get_next_id()
bookings_db[next_id] =
name guestname
place guestplace
phone guestphone
gtgtgt class Guest(object) implements(IGuest) def __init__(self name place) selfname = name selfplace = place
gtgtgt jack = Guest(Jack Bangalore)gtgtgt jack_frontdesk = FrontDeskNG(jack)
gtgtgt IDeskprovidedBy(jack_frontdesk)True
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()gtgtgt gsmregisterAdapter(FrontDeskNG (IGuest) IDesk ng)
Si puograve testare cosigrave
gtgtgt queryAdapter(jack IDesk ng)ltFrontDeskNG object at gt
registeredAdapters
Restituisce un iterabile di IAdapterRegistrations Queste registrazioni descrivono le attuali registrazioni degli adapterper lrsquooggetto
bull Posizione zopecomponent - IComponentRegistry
bull Firma registeredAdapters()
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interface
gtgtgt class IDesk(Interface) A frontdesk will register objects details def register() Register objects details
gtgtgt from zopeinterface import implementsgtgtgt from zopecomponent import adapts
gtgtgt class FrontDeskNG(object) implements(IDesk)
228 Chapter 2 Altri manuali
Documentazione di Plone Release 4
adapts(IGuest)
def __init__(self guest)
selfguest = guest
def register(self)
next_id = get_next_id()
bookings_db[next_id] =
name guestname
place guestplace
phone guestphone
gtgtgt class Guest(object) implements(IGuest) def __init__(self name place) selfname = name selfplace = place
gtgtgt jack = Guest(Jack Bangalore)gtgtgt jack_frontdesk = FrontDeskNG(jack)
gtgtgt IDeskprovidedBy(jack_frontdesk)True
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()gtgtgt gsmregisterAdapter(FrontDeskNG (IGuest) IDesk ng2)
gtgtgt reg_adapter = list(gsmregisteredAdapters())gtgtgt ng2 in [xname for x in reg_adapter]True
registeredHandlers
Restituisce un iterabile di IHandlerRegistrations Queste registrazioni descrivono le attuali registrazioni degli handlerper lrsquooggetto
bull Posizione zopecomponent - IComponentRegistry
bull Firma registeredHandlers()
Esempio
gtgtgt import datetime
gtgtgt def documentCreated(event) eventdoccreated = datetimedatetimeutcnow()
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import implements
gtgtgt class IDocumentCreated(Interface)
23 La guida completa alla Zope Component Architecture 229
Documentazione di Plone Release 4
doc = Attribute(The document that was created)
gtgtgt class DocumentCreated(object) implements(IDocumentCreated) def __init__(self doc) selfdoc = doc
gtgtgt def documentCreated(event) eventdoccreated = datetimedatetimeutcnow()
gtgtgt from zopecomponent import adapter
gtgtgt adapter(IDocumentCreated) def documentCreated(event) eventdoccreated = datetimedatetimeutcnow()
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt gsmregisterHandler(documentCreated info=ng3)
gtgtgt reg_adapter = list(gsmregisteredHandlers())gtgtgt ng3 in [xinfo for x in reg_adapter]True
gtgtgt gsmregisterHandler(documentCreated name=ng4)Traceback (most recent call last)TypeError Named handlers are not yet supported
registeredSubscriptionAdapters
Restituisce un iterabile di ISubscriptionAdapterRegistrations Queste registrazioni descrivono le attuali registrazionidei subscription adapter per lrsquooggetto
bull Posizione zopecomponent - IComponentRegistry
bull Firma registeredSubscriptionAdapters()
Esempio
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import implements
gtgtgt class IValidate(Interface) def validate(ob) Determine whether the object is valid Return a string describing a validation problem An empty string is returned to indicate that the object is valid
gtgtgt class IDocument(Interface)
230 Chapter 2 Altri manuali
Documentazione di Plone Release 4
summary = Attribute(Document summary)
body = Attribute(Document text)
gtgtgt class Document(object) implements(IDocument) def __init__(self summary body) selfsummary selfbody = summary body
gtgtgt from zopecomponent import adapts
gtgtgt class AdequateLength(object) adapts(IDocument) implements(IValidate) def __init__(self doc) selfdoc = doc def validate(self) if len(selfdocbody) lt 1000 return too short else return
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt gsmregisterSubscriptionAdapter(AdequateLength info=ng4)
gtgtgt reg_adapter = list(gsmregisteredSubscriptionAdapters())gtgtgt ng4 in [xinfo for x in reg_adapter]True
registeredUtilities
Restituisce un iterabile di IUtilityRegistrations Queste registrazioni descrivono le attuali registrazioni delle utility perlrsquooggetto
bull Posizione zopecomponent - IComponentRegistry
bull Firma registeredUtilities()
Esempio
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
gtgtgt class IGreeter(Interface) def greet(name) say hello
gtgtgt class Greeter(object) implements(IGreeter) def greet(self name) print Hello name
23 La guida completa alla Zope Component Architecture 231
Documentazione di Plone Release 4
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt greet = Greeter()gtgtgt gsmregisterUtility(greet info=ng5)
gtgtgt reg_adapter = list(gsmregisteredUtilities())gtgtgt ng5 in [xinfo for x in reg_adapter]True
registerHandler
Questa funzione registra un handler Un handler egrave un subscriber che non calcola un adapter ma svolge qualche funzionequando viene chiamato
bull Posizione zopecomponent - IComponentRegistry
bull Firma registerHandler(handler required=None name=ursquolsquo info=rsquolsquo)
bull Vedi anche unregisterHandler
Note In the current implementation of zopecomponent doesnrsquot support name attribute
Esempio
gtgtgt import datetime
gtgtgt def documentCreated(event) eventdoccreated = datetimedatetimeutcnow()
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import implements
gtgtgt class IDocumentCreated(Interface) doc = Attribute(The document that was created)
gtgtgt class DocumentCreated(object) implements(IDocumentCreated) def __init__(self doc) selfdoc = doc
gtgtgt def documentCreated(event) eventdoccreated = datetimedatetimeutcnow()
gtgtgt from zopecomponent import adapter
gtgtgt adapter(IDocumentCreated) def documentCreated(event) eventdoccreated = datetimedatetimeutcnow()
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt gsmregisterHandler(documentCreated)
232 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt from zopecomponent import handle
gtgtgt handle(DocumentCreated(doc))gtgtgt doccreated__class____name__datetime
registerSubscriptionAdapter
Questa funzione serve a registrare una factory di subscribers
bull Posizione zopecomponent - IComponentRegistry
bull Firma registerSubscriptionAdapter(factory required=None provides=None name=ursquolsquo info=rsquolsquo)
bull Vedi anche unregisterSubscriptionAdapter
Esempio
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import implements
gtgtgt class IValidate(Interface) def validate(ob) Determine whether the object is valid Return a string describing a validation problem An empty string is returned to indicate that the object is valid
gtgtgt class IDocument(Interface) summary = Attribute(Document summary) body = Attribute(Document text)
gtgtgt class Document(object) implements(IDocument) def __init__(self summary body) selfsummary selfbody = summary body
gtgtgt from zopecomponent import adapts
gtgtgt class AdequateLength(object) adapts(IDocument) implements(IValidate) def __init__(self doc) selfdoc = doc def validate(self) if len(selfdocbody) lt 1000 return too short else return
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
23 La guida completa alla Zope Component Architecture 233
Documentazione di Plone Release 4
gtgtgt gsmregisterSubscriptionAdapter(AdequateLength)
registerUtility
Questa funzione serve a registrare una utility
bull Posizione zopecomponent - IComponentRegistry
bull Firma registerUtility(component provided=None name=ursquolsquo info=ursquolsquo)
bull Vedi anche unregisterUtility
Esempio
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
gtgtgt class IGreeter(Interface) def greet(name) say hello
gtgtgt class Greeter(object) implements(IGreeter) def greet(self name) print Hello name
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt greet = Greeter()gtgtgt gsmregisterUtility(greet)
subscribers
Questa funzione serve a recuperare i subscribers Vengono restituiti i subscribers che forniscono lrsquointerfaccia passatae che dipendono e sono calcolati dalla sequenza di oggetti richiesti
bull Posizione zopecomponent - IComponentRegistry
bull Firma subscribers(required provided context=None)
Esempio
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import implements
gtgtgt class IValidate(Interface) def validate(ob) Determine whether the object is valid Return a string describing a validation problem An empty string is returned to indicate that the object is valid
234 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt class IDocument(Interface) summary = Attribute(Document summary) body = Attribute(Document text)
gtgtgt class Document(object) implements(IDocument) def __init__(self summary body) selfsummary selfbody = summary body
gtgtgt from zopecomponent import adapts
gtgtgt class SingleLineSummary adapts(IDocument) implements(IValidate) def __init__(self doc) selfdoc = doc def validate(self) if n in selfdocsummary return Summary should only have one line else return
gtgtgt class AdequateLength(object) adapts(IDocument) implements(IValidate) def __init__(self doc) selfdoc = doc def validate(self) if len(selfdocbody) lt 1000 return too short else return
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt gsmregisterSubscriptionAdapter(SingleLineSummary)gtgtgt gsmregisterSubscriptionAdapter(AdequateLength)
gtgtgt from zopecomponent import subscribers
gtgtgt doc = Document(AnDocument blah)gtgtgt [adaptervalidate() for adapter in subscribers([doc] IValidate) if adaptervalidate()][Summary should only have one line too short]
gtgtgt doc = Document(AnDocument blah 1000)gtgtgt [adaptervalidate() for adapter in subscribers([doc] IValidate) if adaptervalidate()][Summary should only have one line]
gtgtgt doc = Document(A Document blah)
23 La guida completa alla Zope Component Architecture 235
Documentazione di Plone Release 4
gtgtgt [adaptervalidate() for adapter in subscribers([doc] IValidate) if adaptervalidate()][too short]
unregisterAdapter
Questa funzione serve a de-registrare una factory di adapter Viene restituito un booleano che indica se il registroegrave stato modificato o meno La funzione restituisce False se il componente dato egrave None e non ci sono componentiregistrati o se il componente dato non egrave None e non egrave registrato altrimenti restituisce True
bull Posizione zopecomponent - IComponentRegistry
bull Firma unregisterAdapter(factory=None required=None provided=None name=ursquolsquo)
bull Vedi anche registerAdapter
Esempio
gtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import Interface
gtgtgt class IDesk(Interface) A frontdesk will register objects details def register() Register objects details
gtgtgt from zopeinterface import implementsgtgtgt from zopecomponent import adapts
gtgtgt class FrontDeskNG(object) implements(IDesk) adapts(IGuest) def __init__(self guest) selfguest = guest def register(self) next_id = get_next_id() bookings_db[next_id] = name guestname place guestplace phone guestphone
gtgtgt class Guest(object) implements(IGuest) def __init__(self name place) selfname = name selfplace = place
gtgtgt jack = Guest(Jack Bangalore)gtgtgt jack_frontdesk = FrontDeskNG(jack)
236 Chapter 2 Altri manuali
Documentazione di Plone Release 4
gtgtgt IDeskprovidedBy(jack_frontdesk)True
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()gtgtgt gsmregisterAdapter(FrontDeskNG (IGuest) IDesk ng6)
Si puograve testare cosigrave
gtgtgt queryAdapter(jack IDesk ng6)ltFrontDeskNG object at gt
Ora de-registriamo ladapter
gtgtgt gsmunregisterAdapter(FrontDeskNG name=ng6)True
Dopo la de-registrazione si ha che
gtgtgt print queryAdapter(jack IDesk ng6)None
unregisterHandler
Questa funzione serve a de-registrare un handler Un handler egrave un subscriber che non calcola un adapter ma svolgequalche funzione quando viene chiamato Viene restituito un booleano che indica se il registro egrave stato modificato omeno
bull Posizione zopecomponent - IComponentRegistry
bull Firma unregisterHandler(handler=None required=None name=ursquolsquo)
bull Vedi anche registerHandler
Esempio
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import implements
gtgtgt class IDocument(Interface) summary = Attribute(Document summary) body = Attribute(Document text)
gtgtgt class Document(object) implements(IDocument) def __init__(self summary body) selfsummary selfbody = summary body
gtgtgt doc = Document(AnDocument blah)
gtgtgt class IDocumentAccessed(Interface) doc = Attribute(The document that was accessed)
gtgtgt class DocumentAccessed(object)
23 La guida completa alla Zope Component Architecture 237
Documentazione di Plone Release 4
implements(IDocumentAccessed)
def __init__(self doc)
selfdoc = doc
selfdoccount = 0
gtgtgt from zopecomponent import adapter
gtgtgt adapter(IDocumentAccessed) def documentAccessed(event) eventdoccount = eventdoccount + 1
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt gsmregisterHandler(documentAccessed)
gtgtgt from zopecomponent import handle
gtgtgt handle(DocumentAccessed(doc))gtgtgt doccount1
Ora de-registriamo lhandler
gtgtgt gsmunregisterHandler(documentAccessed)True
Dopo la de-registrazione si ha
gtgtgt handle(DocumentAccessed(doc))gtgtgt doccount0
unregisterSubscriptionAdapter
Questa funzione serve a de-registrare una factory di subscriber Viene restituito un booleano che indica se il registroegrave stato modificato o meno La funzione restituisce False se il componente dato egrave None e non ci sono componentiregistrati o se il componente dato non egrave None e non egrave registrato altrimenti restituisce True
bull Posizione zopecomponent - IComponentRegistry
bull Firma unregisterSubscriptionAdapter(factory=None required=None provides=None name=ursquolsquo)
bull Vedi anche registerSubscriptionAdapter
Esempio
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import Attributegtgtgt from zopeinterface import implements
gtgtgt class IValidate(Interface) def validate(ob) Determine whether the object is valid Return a string describing a validation problem An empty string is returned to indicate that the
238 Chapter 2 Altri manuali
Documentazione di Plone Release 4
object is valid
gtgtgt class IDocument(Interface) summary = Attribute(Document summary) body = Attribute(Document text)
gtgtgt class Document(object) implements(IDocument) def __init__(self summary body) selfsummary selfbody = summary body
gtgtgt from zopecomponent import adapts
gtgtgt class AdequateLength(object) adapts(IDocument) implements(IValidate) def __init__(self doc) selfdoc = doc def validate(self) if len(selfdocbody) lt 1000 return too short else return
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt gsmregisterSubscriptionAdapter(AdequateLength)
gtgtgt from zopecomponent import subscribers
gtgtgt doc = Document(AnDocument blah)gtgtgt [adaptervalidate() for adapter in subscribers([doc] IValidate) if adaptervalidate()][too short]
Ora de-registriamo il componente
gtgtgt gsmunregisterSubscriptionAdapter(AdequateLength)True
Dopo la de-registrazione si ha
gtgtgt [adaptervalidate() for adapter in subscribers([doc] IValidate) if adaptervalidate()][]
unregisterUtility
Questa funzione serve a de-registrare una utility Viene restituito un booleano che indica se il registro egrave stato modificatoo meno La funzione restituisce False se il componente dato egrave None e non ci sono componenti registrati o se il
23 La guida completa alla Zope Component Architecture 239
Documentazione di Plone Release 4
componente dato non egrave None e non egrave registrato altrimenti restituisce True
bull Posizione zopecomponent - IComponentRegistry
bull Firma unregisterUtility(component=None provided=None name=ursquolsquo)
bull Vedi anche registerUtility
Esempio
gtgtgt from zopeinterface import Interfacegtgtgt from zopeinterface import implements
gtgtgt class IGreeter(Interface) def greet(name) say hello
gtgtgt class Greeter(object) implements(IGreeter) def greet(self name) return Hello + name
gtgtgt from zopecomponent import getGlobalSiteManagergtgtgt gsm = getGlobalSiteManager()
gtgtgt greet = Greeter()gtgtgt gsmregisterUtility(greet)
gtgtgt queryUtility(IGreeter)greet(Jack)Hello Jack
Now unregister
gtgtgt gsmunregisterUtility(greet)True
After unregistration
gtgtgt print queryUtility(IGreeter)None
240 Chapter 2 Altri manuali
CHAPTER 3
Credits e ringraziamenti
Si ringraziano per il loro contributo a questa documentazione
bull Giacomo Spettoli (coordinatoretraduttoremotivatore)
bull Maurizio Delmonte (ideatoremotivatore)
bull Massimo Azzolini (motivatoretraduttore)
bull Federica DrsquoElia (traduttore)
bull Giovanni Giangiobbe (traduttorerevisore)
bull Giampiero Lago
bull Alex Sani
bull Luciano Naldesi
bull Giorgio Borelli
241