Personal tools

Luca Fabbri

May 08, 2012

Slow Plone site? Let's use haufe.requestmonitoring

Slow Plone Site?

Slow Plone site? Let's use haufe.requestmonitoring

Your Plone site suddently become slow, or maybe sometimes it gets slack. How to investigate it (and prevent future problems)

One of the worst times for a web programmer or administrator comes when he gets an e-mail like this one: "Hi! The site (you are in charge of) is very slow today! I really cannot work!"

Rabbia

But it can get even worst if you read the mail later, when the problem has already disappeared on his own. So you'll never know if it was a problem of huge (unexpected) traffic or if it's something you'll face again somedays.

If this will arise again soon, you will surely get another e-mail from the same guy, less polite... probably.

Let's examine the problem in depth. This is what you have to do for a Plone site.

 

 

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.

Aug 01, 2011

Sottositi in Plone: la nostra soluzione

Approfittando della migrazione a Plone 4, ci siamo presi il tempo di rilasciare finalmente, nella consueta ottica del riuso in stile PloneGov, il prodotto Plone per gestire sottositi in uso da qualche anno nel Comune di Modena

La priorità: capire cosa è un sottosito

Prima di addentrarsi nella scelta di una delle soluzioni Plone per gestire sottositi, è bene iniziare il tutto con un'esame della propria organizzazione (o di quella del Cliente che vi ha richiesto "Plone e sottositi") per capire che cosa è un sottosito agli occhi dell'utilizzatore finale.

Può sembrare un passo inutile e dal risultato ovvio in quanto ogniuno di voi avrà in questo momento un'idea ben precisa ma posso assicurarvi che in questi anni abbiamo potuto vedere come questo concetto possa essere percepito in modo molto diverso.

Diamo innanzi tutto una definizione abbastanza generica da poter essere corretta in ogni caso (che dite, la scrivo anche su Wikipedia?).

Un sottosito è una porzione di un sito più grande ma che risente di un certo grado di indipendenza, pur mantenendo un legame col sito principale o con eventuali sottositi fratelli.

Fin qui tutto ok ma in seguito inizieranno ad emergere dettagli e molto spesso le similitudini tra le differenti richieste finiranno qui.

Le variabili in gioco sono le seguenti: indipendenza e legame col sito principale. Tutti vedono queste due caratteristiche in modo molto diverso.

Il nostro lavoro in questi casi è sempre stato analizzare innanzi tutto che cosa l'utente vuole ottenere.

Non ci siamo sorpresi quando alle volte il concetto di sottosito si è fermato alla richiesta di avere un dominio diverso col quale poter navigare una parte del il sito principale (e.g: sottosito.ente.it) oppure alla semplice applicazione di un tema differente. Non c'è nulla di male: un logo differente, o poco più, alle volte è tutto quello che i vostri utenti si aspettano e basta ai visitatori del sito per dare il giusto messaggio.

Gradi di indipendenza dal sito madre

Vediamo i vari scenari che si possono presentare.

Indipendenza 0%, legame col principale 100%

E' l'esempio fatto poco fa. Stiamo quindi parlando di siti dove l'indipendenza è nulla mentre il legale col sito principale è completo. L'utente ha solo bisogno di un richiamo visuale che identifichi l'entrata in un dipartimento diverso, una sottosezione dell'ente o della compagnia, etc.

Indipendenza 100%, legame col sito principale 0%

Altro non infrequente esempio è lo sviluppo di tanti piccoli sottositi, potenzialmente diversi tra loro in tutto.

Al termine dell'analisi di queste situazioni ci vede essere da parte vostra la lecita domanda "Ma perché dite che vi serve un sottosito? Quale è il legame col sito principale?".
Anche in questo caso non stupitevi se la risposta a volte è "Nessun legame!".

Molto spesso l'utente ha davvero bisogno di siti Plone completamente separati che condividono semplicemente:

  • i prodotti installati
  • una base dati utente comune (ma non è detto)
  • l'uso di un dominio principale condiviso (ente.it/sottosito oppure sottosito.ente.it)

In questi casi Plone risolve da solo brillantemente la necessità, permettendovi di creare siti Plone separati nella stessa istanza Zope. Non vi serve altro!

La verità sta nel mezzo

Ovviamente nella maggior parte dei casi si ha "la sana via di mezzo".

In questa zona grigia molto spesso non vi serve chissà quale prodotto installato, ma qualche piccolo accorgimento.

Un esempio reale:

"i sottositi dovranno essere completamente indipendenti ma il link "Home" delle briciole di pane deve puntare al sito principale".

Quindi la Home del sottosito parte in realtà dalla seconda voce. Come otteniamo una cosa simile? Una semplice modifica che personalizzi la viewlet che genera questo elemento, per inserire un link assoluto al sito base. Per il resto: siamo ancora in presenza di un ambiente altamente indipendente. Il vostro "Plonista di fiducia" può farvi ottenere questo comportamento con poche ore di lavoro!

Da qui possiamo incontrare casi dove l'indipendenza cala piano piano e i prodotti da personalizzare ed installare crescono e si complicano...

Quando arrivate a questo, vale la pensa guardarvi attorno a capire che cosa vi serve davvero, e verificare che cosa Plone vi offre.

Altri prodotti che SI OCCUPANO DI sottositi

La necessità di ottenere sottositi è largamente sentita in Italia (forse anche legata alle recenti norme di razionalizzazione dei siti esistenti per gli Enti Pubblici) ma assai meno all'estero.

Al termine della Plone Conference di Budapest ho partecipato ad un Open Space dove si è parlato di sottositi, ma per il resto abbiamo dovuto faticare, inviare segnalazioni, discutere ed aspettare perché Plone ci facilitasse questo comportamento. Anche le discussioni a riguardo non sono poi tante (vale la pena leggere "Subsites in Plone: Review of info and call for sharing products, experiences, and best practices").
Ad oggi l'unico prodotto che sembra abbastanza mantenuto e aggiornato che si occupa di questa necessità è Lineage.

... almeno fino al rilascio del nostro prodotto! :-)

Ad ogni modo con la release 4 il nostro CMS preferito è diventato un ottimo ambiente per avere sottositi.

Fare sottositi in Plone senza usare Plone: redturtle.subsite

La natura di redturtle.subsites si riassume in questo. Spostare al di fuori di Plone (Apache) tutta una serie di problematiche che, grazie a funzionalità native di Plone (anche se poco conosciute) è possibile gestire senza codice aggiuntivo.

Il prodotto nasce da alcuni esperimenti di RedTurtle ma viene portato poi avanti grazie alle esplicite richieste del Comune di Modena, che ha sentito da molti anni questa necessità in alcune installazioni ed è quindi un precursore dell'esplorazione dei sottositi in Plone.

Siamo in presenza di sottositi dove il rapporto "indipendenza/legame col principale" è variabile, ma comunque molto spostata verso un livello di bassa indipendenza ed altra integrazione: i sottositi fanno tutti parte della Rete Civica e questo non viene mai completamente nascosto.

Descriviamo nel dettaglio le richieste originali.

Back-end

I redattori dei sottositi devono poter accedere ad un indirizzo di back-end (anche detto "back-office") riservato, e si autenticano da quell'indirizzo (qualcosa come redazione.ente.it).

La caratteristica del back-end è quella di nascondere completamente tutto ciò che identifica i sottositi e mostrare il sito Plone principale. I sottositi risultano quindi semplici cartelle all'interno del portale visitato.

Anche il tema grafico può essere personalizzato fino ai limiti dello spartano, eliminando tutto quello che occupa spazio visivo nello schermo del redattore (o perché no, aggiungendovi elementi che abbiano il solo scopo di facilitare la redazione).
Il tema diventa quindi un vero e proprio tema riservato al back-end (ma non è obbligatorio).

Il redattore può quindi facilmente eseguire link interni (usando l'editor di Plone) tra documenti di sottositi diversi, creare collezioni che catturino informazioni da più sottositi, ...

Front-end

Questo comportamento deve cambiare nel front-end. Quando il visitatore accedere ad un sottosito deve ovviamente vedere il tema applicato a questo, ma deve avere un livello di integrazione col sito principale molto più basso.

I link alla home del sito, dal logo e dalle briciole di pane, devono riferirsi al sottosito corrente, non a quello principale.

Se non fosse per le ricerche effettuate nel sito o per la presenza di collezioni che qua e là possono mostrare contenuti proveniente dagli altri sottositi fratelli, potrebbe quasi sembrare di trovarsi all'interno si un sito Plone separato.

Con Plone è estremamente semplice (leggasi "senza installare nulla") isolare una cartella perché questa funzioni come un sito indipendente, ma questo influenzerebbe sia il back-end che il front-end (livello di indipendenza troppo elevato).

La nostra soluzione

Il nostro prodotto offre un modo estremamente semplice e poco invasivo di avere:

  • un back-end che nasconda completamente i sottositi
  • un front-end che mostri alcune cartelle come sottositi
  • una metodologia semplice per creare temi aggiuntivi per questi sottositi

Creare uno di questi temi per i sottositi, o personalizzare un tema esistente, è estremamente semplice.

Il prodotto offre già alcune piccole personalizzazioni di Plone (modificandolo il meno possibile) per non dover sviluppare nessun codice aggiuntivo. Abbiamo anche fornito un tema di esempio per un sottosito Plone.

Le altre caratteristiche fornite sono:

  • la navigazione di front-end interna al sottosito è altamente limitata al sottosito stesso (briciole di pane, link alla radice, ...)
  • le ricerche sono eseguite a livello globale
  • le collezioni comprendono tutto il sito (viene lasciato quindi al redattore il compito di limitarle, se lo desidera)
  • ipotetici redattori di front-end (utenti esterni alla redazione) sono fortemente limitati, come se stessero lavorando in un sito Plone indipendente

Conclusioni

Il prodotto redturtle.subsite è semplicemente un aggregatore di tutta la splendida tecnologia sottostante e la pagina ufficiale del prodotto può essere vista come un manuale dei sottositi in Plone, per chiunque volesse intraprendere la strada (anche senza voler per forza usare redturtle.subsite potreste trovare informazioni interessanti).

La sua limitata dimensione dimostra come Plone sia di per se uno strumento estremamente maturo e, lasciatemelo dire, ancora una volta pieno di belle sorprese!

 

Jul 21, 2010

Migliorare l'usabilità dei link interni in TinyMCE

Analisi di collective.tinymceplugins.advfilelinks, un'alternativa al plugin di TinyMCE per i link interni a Plone che permette di gestire in modo differente i link a file del sito.

La Regione Emilia Romagna sta lavorando alacremente al miglioramento dell'accessibilità e dell'usabilità di Plone.

Dato che il futuro dell'editor WYSIWYG in Plone non è più Kupu (difficilmente personalizzabile e non troppo supportato) ma TinyMCE, già da tempo la scelta è stata di passare a TinyMCE anche nella versione 3 di Plone, usata in vari siti regionali.

Migliorare TinyMCE è più semplice che Kupu e lo dimostra come è stato possibile da parte nostra aumentarne le funzionalità per venire incontro ad alcune delle richieste della Legge Stanca (modifiche di cui si è discusso in un altro post, e ora integrate nella release ufficiale già dalla versione 1.1rc9); Altro particolare: trovo importante che questo editor esista anche come progetto indipendente.

Altre novità: la gestione dei link

Una richiesta recente per aumentare l'usabilità dei documenti è stata la seguente:

Modificare Plone in modo che i link interni, se fatti a contenuto di tipo File, mostrino l'icona del tipo di contenuto e la dimensione del file stesso

Una simile modifica aumenta l'usabilità generale della pagina, nonché impatta col Requisito 19 della Legge Stanca.
Dopo una prima analisi è risultato chiaro come fosse necessario scrivere un nuovo plugin per TinyMCE.

Come funziona collective.tinymceplugins.advfilelinks?

Il prodotto rilasciato fornisce il minimo delle modifiche possibili a TinyMCE (ma non minime quanto avrei voluto... ne parliamo dopo). Si tratta di un un plugin aggiuntivo (e per fortuna la presenza di plugin è prevista non solo dall'editor ma anche dalla sua configurazione di Plone) che sostituisce quello predefinito di Plone per i link interni (dal nome autoesplicativo plonelink).

Dopo un'analisi attenta di come poter ottenere le funzionalità richieste e della flessibilità delle API di TinyMCE, su indicazione della Regione stessa abbiamo preso la seguente strada, forse un po' limitata ma di minimo impatto sullo sviluppo e con una resa eccezionale se il browser è aggiornato:

  • I link a file acquisiscono un nuovo attributo type (previsto dallo standard HTML anche se poco conosciuto) ed viene fornito un CSS aggiuntivo contenente varie regole per fornire l'icona.
    Esempio:
    a[type='application/pdf'] {
        background: url(pdf.png) no-repeat 0 50%;
        padding-left: 20px;
    }
    Questo tipo di regola CSS ha un buon supporto (da Internet Explorer 7 in poi).
  • La dimensione del file è prima di tutto inserita nel title del link (che normalmente il plugin originale non fornisce) ma un buon effetto è ottenuto associando una ulteriore regola CSS:
    a.internal-link-tofile:after {
    	content: " ("attr(title)")";
    }
    Questa magica regola CSS (fa parte dello standard CSS 2, per quanto Internet Explorer la supporti solo dalla versione 8 in poi) inserisce del testo aggiuntivo dopo i link con classe internal-link-tofile.
    Il contenuto di questo testo è preso dall'attributo title, ma vi vengono aggiunte delle parentesi. Ovviamente questa classe CSS aggiuntiva è inserita dal nostro plugin in aggiunta alla già nota internal-link.

L'ultima funzionalità è forse la più interessante e per quanto il metodo usato sia davvero poco invasivo e l'effetto finale a dir poco bello, il limite ad avere Internet Explorer 8 è ancora grande.
E' comunque sopportabile? Sì, dato che l'attributo title rimane comunque disponibile agli utenti (e agli Screen Reader) in tutti i casi.

Preview degli effetti del Plugin

Note tecniche di estendibilità

TinyMCE per Plone sfrutta chiamate AJAX per richiedere al server informazioni sui contenuti. Come sempre le modifiche lato server sono minime e perfettamente integrate con quanto Plone già fornisce.

E' bastato fornire un nuovo adapter.

  <adapter
        for="Products.ATContentTypes.interface.IATFile"
        provides="Products.TinyMCE.adapters.interfaces.JSONDetails.IJSONDetails"
        factory=".adapters.JSONDetails"
        />

Grazie alla ZCA, questo adapter aggiuntivo interviene solo per i contenuti di tipo File o sottotipi (a volte ho l'impressione che senza adapter i plonisti non vivrebbero più!).

I problemi maggiori sono lato client... L'idea sarebbe come sempre estendere e non sovrascrivere. In un mondo perfetto questo plugin si sarebbe dovuto integrare con quello preesistente, sfruttandone tutto il codice presente.

Non mi è ancora chiaro se questo non è stato possibile per limiti miei, del plugin stesso, o di TinyMCE, ma il risultato per quanto funzionante è anche una copia di molti dei file originali (una forma di branch del plugin)... probabilmente non dormirò di notte per aver dovuto copiare i file di lingua... ma dopo tutto è una versione alpha!

Il limite maggiore di TinyMCE attualmente è che non usa jQuery (per quanto ci sia un progetto che integra jQuery e TinyMCE) e soprattutto che non c'è uso di eventi Javascript.

Selezione link interni in TinyMCESarebbe stato bello (ma che dico bello! Utile) se al click del mouse sul pulsante radio che seleziona un file piuttosto che un qualunque altro documento a cui associare il link, venisse lanciato un evento Javascript... evento al quale un buon plugin per jQuery avrebbe potuto reagire per eseguire azioni...

Per ora questo non pare possibile, ma sarebbe un buon passo avanti per TinyMCE.

Nota sul namespace

Sono rimasto colpito nel vedere come sulla collective ci siano così pochi plugin the TinyMCE (l'unica eccezione pare essere collective.tinymcetiles). Ci sono state sanguinose discussioni in passato sull'uso di namespace a 2 o 3 livelli (ne ricordo una completa e interessante). In questo caso l'uso dei 3 livelli mi è parso opportuno.

Spero che in futuro altri contribuiscano al gruppo di plugin collective.tinymceplugins e figli!

Riferimenti

Jul 14, 2010

New collective.navigationtoggle release: integration with any theme (I hope)

The new release only fixed a small bug, but also add some better integration with Plone themes. What if fun: a bug inside Sunburst theme was the demonstration that the approach is good!

I already talked about the features of collective.navigationtoggle in previous post, but the new release helped me to be sure of one thing: the unobtrusive approach chosen was good.

The new version also add some refactoring and support for other themes than the classic Plone one. Plone 4 is coming... we must live with this and luckily the products migration has begun.

What is more difficult, after years the default theme is changed (for what I remember, the default theme you all know is with us from Plone 2.0... maybe some changes was done to it at Plone 2.1, but the core never changed). All products that act on Plone UI must check also the new Sunburst theme.

Going back to navigationtoggle, I choosed an approach that was "use existing Plone navigation element to know how to render new ones".

For the new release I only empowered some existings feature, like also generate CSS classes for new element on the navigation.

Why? In Plone 3 navigation main node is like this:

<li class="navTreeItem visualNoMarker">
      <div>
        <a title="..." class="state-... navTreeFolderish" href="...">
            <img width="16" height="16" alt="..." src="...">
            <span>Foo</span>
        </a>
    </div>
   ...
</li>

And Sunburst is like this:

<li class="navTreeItem visualNoMarker">
        <a title="" class="state-... navTreeFolderish contenttype-..." href="...">
            <img height="16" width="16" alt="Folder" src="...">
            <span>Foo</span>
        </a>
   ...
</li>

Apart some node difference (no more containing DIV) the new theme also rely on a contenttype-xxx class.

What is funny (and what make me say "thanks navigationtoggle") is an unwanted behavior of the current Sunburst theme. A bug that double the content type icon: one given from the IMG tag and another ones from CSS, thanks to the new class.

I'm not interested in this bug (Irene says that probably it has been already fixed), but using navigationtoggle with this bugged version of Sunburst... also make the bug applyed to elements navigation nodes generated by our script!

This (uncommonly) is good as respect the original idea: the original theme use doubled icons?! Is not a problem of navigationtoggle, so do it!