Personal tools

Archetypes

Mar 20, 2013

rt.atmigrator: pensioniamo i vecchi tipi con un click

Come dare un degno congedo a dei valorosi archetype

rt.atmigrator: pensioniamo i vecchi tipi con un click

Filed Under:

Archetype che non servono più e contenuti da migrare in un altro tipo? Un prodotto ci può aiutare a concedere loro il meritato riposo in modo facile ed intuitivo

Di cosa potrei parlare? Cosa ho fatto ultimamente di interessante da poter condividere?

Quando sto per scrivere un nuovo post per il blog, il problema è sempre il solito: trovare un argomento interessante da proporre.

Sfortunatamente per voi, la risposta è sempre la stessa: migrazioni!

read more

Mar 12, 2013

Quando la sicurezza in Plone è importante: reindexObjectSecurity

Plone e la sicurezza via catalogo

Quando la sicurezza in Plone è importante: reindexObjectSecurity

Quando gli indici introdotti da prodotti aggiuntivi hanno a che fare con la sicurezza del sito, è meglio prendere alcune precauzioni per evitare problemi

Per chiunque sviluppi con Plone, diventa presto chiara l'importanza del catalogo e, contemporaneamente, la necessità di mantenere il catalogo del sito aggiornato.

L'API principale a cui si fa riferimento per aggiornare lo stato di un contenuto nel catalogo Plone è la chiamata a reindexObject:

>>> context.setTitle('Nuovo titolo')
>>> context.reindexObject()
>>> context.title()
'Nuovo titolo'

Fin qui, nulla di nuovo.

read more

Nov 05, 2012

Trasformiamo i nostri content-type in modo semplice con Products.contentmigration

Cambiare forma non è mai stato così facile

Trasformiamo i nostri content-type in modo semplice con Products.contentmigration

Breve guida pratica su come utilizzare Products.contentmigration per migrare i contenuti di un sito da un content-type a un altro senza diventare matti

Negli ultimi mesi abbiamo dovuto migrare una serie di portali dal vecchio Plone 3.3.5 alla nuova release 4.2.
Questa operazione è anche stata l'occasione per fare un po' di rifattorizzazione dei prodotti (necessaria in alcuni casi, per farli funzionare anche su Plone 4) e di pulizia generale dei contenuti.

"Quei content-type sono vecchi... cambiamoli!"

Su alcuni portali avevamo una serie di content-type creati ad hoc per esigenze passate, poi diventati obsoleti o perché le funzionalità sono state implementate (meglio) in altri prodotti, o perché non abbiamo più bisogno di loro.
Per esempio, avevamo creato diversi content-type che aggiungevano funzionalità a quelli base di Plone (al tempo non conoscevamo ancora la potenza di archetypes.schemaextender) sovrascrivendoli, e ora dovevamo tornare indietro per poter ricominciare a utilizzare le versioni base.

shape boxTornare a utilizzare le versioni standard è semplice, basta disinstallare il nostro prodotto.
Cosa fare però con i contenuti già creati? Come torniamo a una situazione "standard" senza rompere niente?
E' come avere tra le mani una serie di cubi avendo a disposizione solo buchi tondi: non funzioneranno più, ma non li possiamo perdere. Vanno sostituiti.

La soluzione è facile: li migriamo!

 

read more

Sep 27, 2012

Te lo do io il DB! (aka "Come pubblicare query SQL su Plone")

Vi hanno mai chiesto di pubblicare dati da un database relazionale su Plone? E di modificare al volo le query? Con redturtle.sqlcontents diventa semplice!

Non di rado capita che mi venga richiesto di pubblicare su un sito Plone dati provenienti da un database relazionale o di fornire uno strumento che consenta questa operazione.

La richiesta tipica è quella di pubblicare con Plone il risultato di una query SQL che il cliente desidera gestire in autonomia.

Per questo scopo nasce redturtle.sqlcontents, un prodotto per Plone 3 e Plone 4 che aggiunge due nuovi tipi di contenuto (archetype) per la gestione di questo caso d'uso.

read more

Feb 29, 2012

Analisi della validazione dei campi Plone

Filed Under:

La validazione dei vari campi dei contenuti Plone è cosa nota e ben documentata, ma l'introduzione massiva dell'uso di archetypes.schemaextender ha cambiato l'approccio con cui affronto il problema

La validazione dei campi: oggi

Stiamo tutti aspettando il giorno in cui Plone darà l'estremo saluto al framework Archetypes, che dai tempi di Plone 2.1 ci fornisce non solo un ambiente di sviluppo per creare nuovi contenuti, ma anche i contenuti base con cui Plone viene distribuito.

Tutte le caratteristiche di Archetypes, compresa la validazione dei campi (field validation) sono ben chiare e documentate.

...
atapi.StringField('codice',
   validators=('isInt', 'isChissaCheCosa', ...),
   widget = atapi.StringWidget(
            label = "Il codice del prodotto",
            )
),
...

 

ErroreNella mia esperienza di sviluppo con questo framework, non ho mai apprezzato particolarmente il meccanismo di validazione... o meglio: l'ho apprezzato talmente tanto da usarlo così come viene fornito, usando tutta quella serie di validatori predefiniti che Plone fornisce, ma senza sentire mai un vero bisogno di crearne di nuovi.

I motivi sono due:

  • Plone ha già tutti i validatori che nel 90% dei casi bastano (capire se un campo è nel formato e-mail, se è un numero, ...)
  • Tipi di validazioni aggiuntive che possono essere richieste dalle specifiche di un progetto, sono risultate sempre un po' troppo specifiche, tanto da non giustificare lo sviluppo di nuovi validatori "general-purpose.

Sul secondo punto, meglio fare un esempio.

Ammettiamo di avere un campo "codice" (numerico) e per questo si abbia necessità di verificare che il campo abbia un certo valore:

  • Se la logica di validazione è semplice (e.g: "che il valore sia maggiore di 5", al 90% uno dei validatori base di Plone basterà (non sapete quante cose di possono fare usando ExpressionValidator e RangeValidator).
  • Se la logica è molto complessa (e.g: "il numero deve essere maggiore di 5, ma solo se è martedì, se c'è la luna piena ma non se l'utente corrente è nel gruppo dei revisori"), probabilmente non sarà riutilizzabile in un altro contesto.

Per di più: scrivere un nuovo validatore è semplice (anche se forse un po' noioso), ma validare uno specifico campo di un vostro tipo Archetypes è ancora più semplice.

Una delle funzionalità nascoste di Archetypes è che per validare un singolo campo è sempre possibile usare un "validation hook".

Ricordate? Il campo si chiamava "codice".

def validate_codice(self, value):
    ...
    if not ok:
        return "Validazione fallita"

 

Con questo semplice metodo aggiunto alla classe del contenuto, il campo viene validato in modo molto semplice e diretto.

  • Se il metodo ritorna qualcosa, quel qualcosa è il messaggio di errore (validazione fallita).
  • Se non ritorna nulla, la validazione ha avuto successo.

Un altro approccio (più pulito) è usare un adapter per IObjectPostValidation.

<subscriber provides="Products.Archetypes.interfaces.IObjectPostValidation"
            factory=".validators.MyPostValidation"
            />

 

Anche in questo caso: è più semplice questa strada che non sviluppare un validatore da usare una sola volta nella vita. Il bello dell'approccio qui sopra sta nel non dover modificare la classe del contenuto. Questo conta poco quando il codice è vostro, ma cosa ne dite della necessità di introdurre un processo di validazione per un campo di un tipo non sviluppato da voi (e.g: il tipo Evento base di Plone)?

Ma anche questo approccio è difficilmente riutilizzabile in più di un progetto; per di più è un metodo per validare l'intero contenuto al suo salvataggio, non un singolo campo.

Quando scrivere un validatore?

Una regola generale della programmazione: il riutilizzo del codice.

Se hai fatto lo stesso pezzo di codice in due diversi momenti, in diversi ambienti/prodotti e nel secondo caso hai ricopiato il codice dal primo, hai probabilmente sbagliato qualcosa la prima volta

Affermazione draconiana ma fondamentalmente vera... molto spesso durante la prima scrittura di un codice non si ha (e nemmeno si può avere) la lungimiranza da prevederne un utilizzo al di fuori del prodotto che si sta sviluppando.

Così si arriva alla seconda volta. Il codice è già fatto, ma non importabile nel nuovo progetto con semplicità, quindi si cede al Lato Oscuro del Copia/Incolla... Dopo la terza quarta volta probabilmente avrete capito che forse vale la pena sistemare le cose, e creare un modulo riutilizzabile!

Dopo la 18esima volta che mi sono ritrovato a scrivere una validazione per il CAP italiano e quando un secondo cliente mi ha chiesto di poter verificare la lunghezza minima di battute di un testo, ho messo tutto queste cose insieme in un prodotto: collective.itvalidators (ammetto che la scelta del nome fu quantomai infelice, quasi quanto Plone4Artists e Windows Millenium™).

Lo scopo di quel prodotto è raccogliere i nostri validatori più comuni per non doverli riscrivere da zero tutte le volte e per mantenerli in un unico punto. A dire la verità non avrei nemmeno raccolto tutti questi pezzi di codice in un insieme di validatori, se non fosse diventato così comune l'uso di schemaextender.

Validazioni Archetypes con schemaextender

Per tutti quelli che non lo conoscono, archetypes.schemaextender è un utilissimo prodotto Plone che ha cambiato completamente l'approccio di personalizzazione dei tipi Archetypes esistenti (siano essi i tipi base di Plone o altri prodotti di terze parti).

In pratica, vengono aggiunti nuovi campi a run-time allo schema (l'insieme dei campi che caratterizzano tipo) di un contenuto senza toccare il codice originale... wow! Uno dei limiti dell'approccio è che, per quanto si possa manipolare facilmente lo schema non si ha modo di manipolare anche la classe e il codice.

Quindi il semplice utilizzo dell'approccio "validation hook" mostrato sopra non può funzionare (al contrario, l'approccio tramite adapter per IObjectPostValidation continua a essere valido).

I validatori Archetypes, al contrario, sono definiti direttamente nello schema, quindi sono ancora utilizzabili usando schemaextender. Avere quindi la logica di validazione racchiusa in un modulo riutilizzabile in questo caso paga.