+ All Categories
Home > Documents > Documentazione di Plone - Home | Read the Docs

Documentazione di Plone - Home | Read the Docs

Date post: 16-Oct-2021
Category:
Upload: others
View: 1 times
Download: 0 times
Share this document with a friend
245
Documentazione di Plone Release 4 La comunità Italiana di Plone July 31, 2015
Transcript
Page 1: Documentazione di Plone - Home | Read the Docs

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

  • Plone 4 Manuale utente
    • Introduzione
    • Aggiungere contenuti
    • Gestione dei contenuti
    • Usare TinyMCE come visual editor
    • Usare Kupu come visual editor
    • Collaborazione e flusso di lavoro
    • Utilizzo delle collezioni
    • Gestione delle Portlet
      • Altri manuali
        • Creare un tema con Diazo
        • ZODB - un database nativo ad oggetti per Python
        • La guida completa alla Zope Component Architecture
          • Credits e ringraziamenti
Page 2: Documentazione di Plone - Home | Read the Docs

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

  • Plone 4 Manuale utente
    • Introduzione
    • Aggiungere contenuti
    • Gestione dei contenuti
    • Usare TinyMCE come visual editor
    • Usare Kupu come visual editor
    • Collaborazione e flusso di lavoro
    • Utilizzo delle collezioni
    • Gestione delle Portlet
      • Altri manuali
        • Creare un tema con Diazo
        • ZODB - un database nativo ad oggetti per Python
        • La guida completa alla Zope Component Architecture
          • Credits e ringraziamenti
Page 3: Documentazione di Plone - Home | Read the Docs

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

  • Plone 4 Manuale utente
    • Introduzione
    • Aggiungere contenuti
    • Gestione dei contenuti
    • Usare TinyMCE come visual editor
    • Usare Kupu come visual editor
    • Collaborazione e flusso di lavoro
    • Utilizzo delle collezioni
    • Gestione delle Portlet
      • Altri manuali
        • Creare un tema con Diazo
        • ZODB - un database nativo ad oggetti per Python
        • La guida completa alla Zope Component Architecture
          • Credits e ringraziamenti
Page 4: Documentazione di Plone - Home | Read the Docs

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

  • Plone 4 Manuale utente
    • Introduzione
    • Aggiungere contenuti
    • Gestione dei contenuti
    • Usare TinyMCE come visual editor
    • Usare Kupu come visual editor
    • Collaborazione e flusso di lavoro
    • Utilizzo delle collezioni
    • Gestione delle Portlet
      • Altri manuali
        • Creare un tema con Diazo
        • ZODB - un database nativo ad oggetti per Python
        • La guida completa alla Zope Component Architecture
          • Credits e ringraziamenti
Page 5: Documentazione di Plone - Home | Read the Docs

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

  • Plone 4 Manuale utente
    • Introduzione
    • Aggiungere contenuti
    • Gestione dei contenuti
    • Usare TinyMCE come visual editor
    • Usare Kupu come visual editor
    • Collaborazione e flusso di lavoro
    • Utilizzo delle collezioni
    • Gestione delle Portlet
      • Altri manuali
        • Creare un tema con Diazo
        • ZODB - un database nativo ad oggetti per Python
        • La guida completa alla Zope Component Architecture
          • Credits e ringraziamenti
Page 6: Documentazione di Plone - Home | Read the Docs
Page 7: Documentazione di Plone - Home | Read the Docs
Page 8: Documentazione di Plone - Home | Read the Docs
Page 9: Documentazione di Plone - Home | Read the Docs
Page 10: Documentazione di Plone - Home | Read the Docs
Page 11: Documentazione di Plone - Home | Read the Docs
Page 12: Documentazione di Plone - Home | Read the Docs
Page 13: Documentazione di Plone - Home | Read the Docs
Page 14: Documentazione di Plone - Home | Read the Docs
Page 15: Documentazione di Plone - Home | Read the Docs
Page 16: Documentazione di Plone - Home | Read the Docs
Page 17: Documentazione di Plone - Home | Read the Docs
Page 18: Documentazione di Plone - Home | Read the Docs
Page 19: Documentazione di Plone - Home | Read the Docs
Page 20: Documentazione di Plone - Home | Read the Docs
Page 21: Documentazione di Plone - Home | Read the Docs
Page 22: Documentazione di Plone - Home | Read the Docs
Page 23: Documentazione di Plone - Home | Read the Docs
Page 24: Documentazione di Plone - Home | Read the Docs
Page 25: Documentazione di Plone - Home | Read the Docs
Page 26: Documentazione di Plone - Home | Read the Docs
Page 27: Documentazione di Plone - Home | Read the Docs
Page 28: Documentazione di Plone - Home | Read the Docs
Page 29: Documentazione di Plone - Home | Read the Docs
Page 30: Documentazione di Plone - Home | Read the Docs
Page 31: Documentazione di Plone - Home | Read the Docs
Page 32: Documentazione di Plone - Home | Read the Docs
Page 33: Documentazione di Plone - Home | Read the Docs
Page 34: Documentazione di Plone - Home | Read the Docs
Page 35: Documentazione di Plone - Home | Read the Docs
Page 36: Documentazione di Plone - Home | Read the Docs
Page 37: Documentazione di Plone - Home | Read the Docs
Page 38: Documentazione di Plone - Home | Read the Docs
Page 39: Documentazione di Plone - Home | Read the Docs
Page 40: Documentazione di Plone - Home | Read the Docs
Page 41: Documentazione di Plone - Home | Read the Docs
Page 42: Documentazione di Plone - Home | Read the Docs
Page 43: Documentazione di Plone - Home | Read the Docs
Page 44: Documentazione di Plone - Home | Read the Docs
Page 45: Documentazione di Plone - Home | Read the Docs
Page 46: Documentazione di Plone - Home | Read the Docs
Page 47: Documentazione di Plone - Home | Read the Docs
Page 48: Documentazione di Plone - Home | Read the Docs
Page 49: Documentazione di Plone - Home | Read the Docs
Page 50: Documentazione di Plone - Home | Read the Docs
Page 51: Documentazione di Plone - Home | Read the Docs
Page 52: Documentazione di Plone - Home | Read the Docs
Page 53: Documentazione di Plone - Home | Read the Docs
Page 54: Documentazione di Plone - Home | Read the Docs
Page 55: Documentazione di Plone - Home | Read the Docs
Page 56: Documentazione di Plone - Home | Read the Docs
Page 57: Documentazione di Plone - Home | Read the Docs
Page 58: Documentazione di Plone - Home | Read the Docs
Page 59: Documentazione di Plone - Home | Read the Docs
Page 60: Documentazione di Plone - Home | Read the Docs
Page 61: Documentazione di Plone - Home | Read the Docs
Page 62: Documentazione di Plone - Home | Read the Docs
Page 63: Documentazione di Plone - Home | Read the Docs
Page 64: Documentazione di Plone - Home | Read the Docs
Page 65: Documentazione di Plone - Home | Read the Docs
Page 66: Documentazione di Plone - Home | Read the Docs
Page 67: Documentazione di Plone - Home | Read the Docs
Page 68: Documentazione di Plone - Home | Read the Docs
Page 69: Documentazione di Plone - Home | Read the Docs
Page 70: Documentazione di Plone - Home | Read the Docs
Page 71: Documentazione di Plone - Home | Read the Docs
Page 72: Documentazione di Plone - Home | Read the Docs
Page 73: Documentazione di Plone - Home | Read the Docs
Page 74: Documentazione di Plone - Home | Read the Docs
Page 75: Documentazione di Plone - Home | Read the Docs
Page 76: Documentazione di Plone - Home | Read the Docs
Page 77: Documentazione di Plone - Home | Read the Docs
Page 78: Documentazione di Plone - Home | Read the Docs
Page 79: Documentazione di Plone - Home | Read the Docs
Page 80: Documentazione di Plone - Home | Read the Docs
Page 81: Documentazione di Plone - Home | Read the Docs
Page 82: Documentazione di Plone - Home | Read the Docs
Page 83: Documentazione di Plone - Home | Read the Docs
Page 84: Documentazione di Plone - Home | Read the Docs
Page 85: Documentazione di Plone - Home | Read the Docs
Page 86: Documentazione di Plone - Home | Read the Docs
Page 87: Documentazione di Plone - Home | Read the Docs
Page 88: Documentazione di Plone - Home | Read the Docs
Page 89: Documentazione di Plone - Home | Read the Docs
Page 90: Documentazione di Plone - Home | Read the Docs
Page 91: Documentazione di Plone - Home | Read the Docs
Page 92: Documentazione di Plone - Home | Read the Docs
Page 93: Documentazione di Plone - Home | Read the Docs
Page 94: Documentazione di Plone - Home | Read the Docs
Page 95: Documentazione di Plone - Home | Read the Docs
Page 96: Documentazione di Plone - Home | Read the Docs
Page 97: Documentazione di Plone - Home | Read the Docs
Page 98: Documentazione di Plone - Home | Read the Docs
Page 99: Documentazione di Plone - Home | Read the Docs
Page 100: Documentazione di Plone - Home | Read the Docs
Page 101: Documentazione di Plone - Home | Read the Docs
Page 102: Documentazione di Plone - Home | Read the Docs
Page 103: Documentazione di Plone - Home | Read the Docs
Page 104: Documentazione di Plone - Home | Read the Docs
Page 105: Documentazione di Plone - Home | Read the Docs
Page 106: Documentazione di Plone - Home | Read the Docs
Page 107: Documentazione di Plone - Home | Read the Docs
Page 108: Documentazione di Plone - Home | Read the Docs
Page 109: Documentazione di Plone - Home | Read the Docs
Page 110: Documentazione di Plone - Home | Read the Docs
Page 111: Documentazione di Plone - Home | Read the Docs
Page 112: Documentazione di Plone - Home | Read the Docs
Page 113: Documentazione di Plone - Home | Read the Docs
Page 114: Documentazione di Plone - Home | Read the Docs
Page 115: Documentazione di Plone - Home | Read the Docs
Page 116: Documentazione di Plone - Home | Read the Docs
Page 117: Documentazione di Plone - Home | Read the Docs
Page 118: Documentazione di Plone - Home | Read the Docs
Page 119: Documentazione di Plone - Home | Read the Docs
Page 120: Documentazione di Plone - Home | Read the Docs
Page 121: Documentazione di Plone - Home | Read the Docs
Page 122: Documentazione di Plone - Home | Read the Docs
Page 123: Documentazione di Plone - Home | Read the Docs
Page 124: Documentazione di Plone - Home | Read the Docs
Page 125: Documentazione di Plone - Home | Read the Docs
Page 126: Documentazione di Plone - Home | Read the Docs
Page 127: Documentazione di Plone - Home | Read the Docs
Page 128: Documentazione di Plone - Home | Read the Docs
Page 129: Documentazione di Plone - Home | Read the Docs
Page 130: Documentazione di Plone - Home | Read the Docs
Page 131: Documentazione di Plone - Home | Read the Docs
Page 132: Documentazione di Plone - Home | Read the Docs
Page 133: Documentazione di Plone - Home | Read the Docs
Page 134: Documentazione di Plone - Home | Read the Docs
Page 135: Documentazione di Plone - Home | Read the Docs
Page 136: Documentazione di Plone - Home | Read the Docs
Page 137: Documentazione di Plone - Home | Read the Docs
Page 138: Documentazione di Plone - Home | Read the Docs
Page 139: Documentazione di Plone - Home | Read the Docs
Page 140: Documentazione di Plone - Home | Read the Docs
Page 141: Documentazione di Plone - Home | Read the Docs
Page 142: Documentazione di Plone - Home | Read the Docs
Page 143: Documentazione di Plone - Home | Read the Docs
Page 144: Documentazione di Plone - Home | Read the Docs
Page 145: Documentazione di Plone - Home | Read the Docs
Page 146: Documentazione di Plone - Home | Read the Docs
Page 147: Documentazione di Plone - Home | Read the Docs
Page 148: Documentazione di Plone - Home | Read the Docs
Page 149: Documentazione di Plone - Home | Read the Docs
Page 150: Documentazione di Plone - Home | Read the Docs
Page 151: Documentazione di Plone - Home | Read the Docs
Page 152: Documentazione di Plone - Home | Read the Docs
Page 153: Documentazione di Plone - Home | Read the Docs
Page 154: Documentazione di Plone - Home | Read the Docs
Page 155: Documentazione di Plone - Home | Read the Docs
Page 156: Documentazione di Plone - Home | Read the Docs
Page 157: Documentazione di Plone - Home | Read the Docs
Page 158: Documentazione di Plone - Home | Read the Docs
Page 159: Documentazione di Plone - Home | Read the Docs
Page 160: Documentazione di Plone - Home | Read the Docs
Page 161: Documentazione di Plone - Home | Read the Docs
Page 162: Documentazione di Plone - Home | Read the Docs
Page 163: Documentazione di Plone - Home | Read the Docs
Page 164: Documentazione di Plone - Home | Read the Docs
Page 165: Documentazione di Plone - Home | Read the Docs
Page 166: Documentazione di Plone - Home | Read the Docs
Page 167: Documentazione di Plone - Home | Read the Docs
Page 168: Documentazione di Plone - Home | Read the Docs
Page 169: Documentazione di Plone - Home | Read the Docs
Page 170: Documentazione di Plone - Home | Read the Docs
Page 171: Documentazione di Plone - Home | Read the Docs
Page 172: Documentazione di Plone - Home | Read the Docs
Page 173: Documentazione di Plone - Home | Read the Docs
Page 174: Documentazione di Plone - Home | Read the Docs
Page 175: Documentazione di Plone - Home | Read the Docs
Page 176: Documentazione di Plone - Home | Read the Docs
Page 177: Documentazione di Plone - Home | Read the Docs
Page 178: Documentazione di Plone - Home | Read the Docs
Page 179: Documentazione di Plone - Home | Read the Docs
Page 180: Documentazione di Plone - Home | Read the Docs
Page 181: Documentazione di Plone - Home | Read the Docs
Page 182: Documentazione di Plone - Home | Read the Docs
Page 183: Documentazione di Plone - Home | Read the Docs
Page 184: Documentazione di Plone - Home | Read the Docs
Page 185: Documentazione di Plone - Home | Read the Docs
Page 186: Documentazione di Plone - Home | Read the Docs
Page 187: Documentazione di Plone - Home | Read the Docs
Page 188: Documentazione di Plone - Home | Read the Docs
Page 189: Documentazione di Plone - Home | Read the Docs
Page 190: Documentazione di Plone - Home | Read the Docs
Page 191: Documentazione di Plone - Home | Read the Docs
Page 192: Documentazione di Plone - Home | Read the Docs
Page 193: Documentazione di Plone - Home | Read the Docs
Page 194: Documentazione di Plone - Home | Read the Docs
Page 195: Documentazione di Plone - Home | Read the Docs
Page 196: Documentazione di Plone - Home | Read the Docs
Page 197: Documentazione di Plone - Home | Read the Docs
Page 198: Documentazione di Plone - Home | Read the Docs
Page 199: Documentazione di Plone - Home | Read the Docs
Page 200: Documentazione di Plone - Home | Read the Docs
Page 201: Documentazione di Plone - Home | Read the Docs
Page 202: Documentazione di Plone - Home | Read the Docs
Page 203: Documentazione di Plone - Home | Read the Docs
Page 204: Documentazione di Plone - Home | Read the Docs
Page 205: Documentazione di Plone - Home | Read the Docs
Page 206: Documentazione di Plone - Home | Read the Docs
Page 207: Documentazione di Plone - Home | Read the Docs
Page 208: Documentazione di Plone - Home | Read the Docs
Page 209: Documentazione di Plone - Home | Read the Docs
Page 210: Documentazione di Plone - Home | Read the Docs
Page 211: Documentazione di Plone - Home | Read the Docs
Page 212: Documentazione di Plone - Home | Read the Docs
Page 213: Documentazione di Plone - Home | Read the Docs
Page 214: Documentazione di Plone - Home | Read the Docs
Page 215: Documentazione di Plone - Home | Read the Docs
Page 216: Documentazione di Plone - Home | Read the Docs
Page 217: Documentazione di Plone - Home | Read the Docs
Page 218: Documentazione di Plone - Home | Read the Docs
Page 219: Documentazione di Plone - Home | Read the Docs
Page 220: Documentazione di Plone - Home | Read the Docs
Page 221: Documentazione di Plone - Home | Read the Docs
Page 222: Documentazione di Plone - Home | Read the Docs
Page 223: Documentazione di Plone - Home | Read the Docs
Page 224: Documentazione di Plone - Home | Read the Docs
Page 225: Documentazione di Plone - Home | Read the Docs
Page 226: Documentazione di Plone - Home | Read the Docs
Page 227: Documentazione di Plone - Home | Read the Docs
Page 228: Documentazione di Plone - Home | Read the Docs
Page 229: Documentazione di Plone - Home | Read the Docs
Page 230: Documentazione di Plone - Home | Read the Docs
Page 231: Documentazione di Plone - Home | Read the Docs
Page 232: Documentazione di Plone - Home | Read the Docs
Page 233: Documentazione di Plone - Home | Read the Docs
Page 234: Documentazione di Plone - Home | Read the Docs
Page 235: Documentazione di Plone - Home | Read the Docs
Page 236: Documentazione di Plone - Home | Read the Docs
Page 237: Documentazione di Plone - Home | Read the Docs
Page 238: Documentazione di Plone - Home | Read the Docs
Page 239: Documentazione di Plone - Home | Read the Docs
Page 240: Documentazione di Plone - Home | Read the Docs
Page 241: Documentazione di Plone - Home | Read the Docs
Page 242: Documentazione di Plone - Home | Read the Docs
Page 243: Documentazione di Plone - Home | Read the Docs
Page 244: Documentazione di Plone - Home | Read the Docs

Recommended