Personal tools

You are reading the articles stored in Tutorial

Jun 12, 2013

Un sito, mille colori. Come colorare sezioni diverse di un portale Plone

mille modi per dare colore ad un sito

Un sito, mille colori. Come colorare sezioni diverse di un portale Plone

Filed Under:

Breve guida per personalizzare graficamente diverse sezioni di un sito con dei colori caratteristici grazie ad una semplice viewlet che genera CSS dinamico

 

Oggi, invece che affrontare i soliti temi di migrazioni o contentrule, mi dedico ad un argomento più "grafico".

restroomPensando all’argomento di questo post, mi è venuto in mente che in azienda abbiamo una divisione dei ruoli con qualche connotazione sessista: i maschi sono rudi e badano al sodo quindi si occupano della programmazione backend, mentre alle donne, che hanno decisamente dei gusti migliori, spetta il compito di ricamare e colorare.

Detto questo, però, spesso i baldi giovani si vedono costretti a dare una mano alle dolci donzelle (anche se contro voglia), sia per alleggerire il loro carico di lavoro, che per supporto vero e proprio nella creazione di strumenti/strutture utili per poter creare il risultato grafico desiderato.

Una necessità ricorrente è quella di avere diverse sezioni principali del sito, ognuna contraddistinta da un colore che va a caratterizzare diversi elementi della pagina (per esempio i titoli, lo sfondo delle descrizioni o le testate delle portlet).

Se le sezioni principali sono statiche, gestire queste personalizzazioni solamente via CSS si potrebbe anche fare.
Basterebbe modificare la generazione delle classi del body nel main template, in modo da avere in ogni sezione e nei suoi figli una determinata classe (un esempio su come fare, lo si può trovare su developer.plone.org). In questo modo, via CSS si gestiscono senza problemi i vari scenari.

Ok, ma se i redattori vogliono gestire in autonomia i colori?

Il gioco diventa difficile quando le sezioni possono cambiare nel tempo, e le redazioni vogliono gestire i colori autonomamente.

Per risolvere questo problema, dopo diverse ricerche, ho trovato un valido esempio in un vecchio post di Kees Hink dove parlava esattamente di quello che mi serviva: applicare dinamicamente un determinato stile solo ad una sezione precisa del sito.

Innanzitutto serve una modifica agli Archetypes per poter aggiungere il campo di selezione del colore. Qui le possibilità sono diverse:

  • si fa un nuovo Archetype folderish adibito al ruolo di cartella di tassonomia

  • si usa archetypes.schemaextender e si aggiunge il campo a determinati AT folderish (le cartelle per esempio?)

  • si crea una interfaccia “marker” per la quale si registra l’adapter di archetypes.schemaextender, e poi si applica questa interfaccia via ZMI (o con un qualche meccanismo di subtyping) direttamente alle cartelle desiderate.

L’ultima ipotesi è la più flessibile e di minor impatto, visto che si può decidere di marcare solo delle cartelle selezionate come tassonomie.

Una volta marcate le varie cartelle e impostato un colore (in valore esadecimale sarebbe meglio, così è già pronto da usare), non resta che creare gli stili veri e propri... ma come?

Seguendo l’idea del blog, basta registrare una viewlet dentro al viewletmanager IHTMLHeadLinks, che viene caricata negli header della pagina, e permette di definire nuovi stili e inserirli proprio nell'header, insieme agli altri CSS di Plone.

<browser:viewlet
name="custom_color.viewlet"
manager="plone.app.layout.viewlets.interfaces.IHtmlHeadLinks"
class=".viewlets.CustomColorViewlets"
layer="..interfaces.IMyProductLayer"
permission="zope.Public"
/>

Questa viewlet andrà visualizzata ovviamente solo nei contenuti che sono all’interno di una tassonomia, e deve ritornare una stringa di codice CSS che darà proprio i colori impostati.

L'ultimo problema da affrontare è stato quello relativo al modo con cui generare questi stili.
In un primo momento avevo pensato di cablarli direttamente nel codice della viewlet, ma poi mi è venuto in mente che in un futuro avremmo potuto dover aggiornare quegli stili, quindi c'era bisogno di qualcosa di più dinamico e configurabile... e cosa c'è di meglio di un bel pannello di controllo che memorizza i dati nel registro di Plone?

Non mi dilungo su come creare un pannello di controllo basato su plone.app.registry perché è già stato trattato ampiamente dal nostro Luca Fabbri in non uno ma bensì in due post, poi si può trovare una buona guida scritta da Timo Stollenwerk o si può guardare il sorgente di diversi prodotti che ne creano uno, come ad esempio collective.analyticspanel.

Il campo nel pannello di controllo viene creato come una textarea, per poter inserire più righe di stili:

color_styles = schema.Text(
title=_(u"Stili aggiuntivi"),
description=_(u"Inserisci una serie di stili CSS aggiuntivi.
Dove vuoi usare il colore personalizzato,
scrivi la stringa $color$.")

Nella viewlet, ogni volta che viene disegnata, si va a prendere la tassonomia di appartenenza navigando a ritroso l'albero (se non sono dentro nessuna tassonomia ovviamente non viene disegnata) e si recupera il valore salvato nel registry per ritornarlo come CSS:

def render(self):
taxonomy = self.getTaxonomy()
if not taxonomy:
return ""
color = self.getFieldValue(taxonomy)
if not color:
return ""
registry = queryUtility(IRegistry)
settings = registry.forInterface(IMyRegistrySettings, check=False)
css = settings.primary_color_styles
if not css:
return ""
css = css.replace('\r\n', ' ')
css = css.replace('$color, color)
return "<style type='text/css'>%s</style>" % css

def getTaxonomy(self):
"""
Controlla ricorsivamente se l'elemento corrente è all'interno di una cartella
marcata con la mia interfaccia definita precedentemente
"""
for elem in self.context.aq_inner.aq_chain:
if IMyMarkerInterface.providedBy(elem):
return elem
return None

def getFieldValue(self, taxonomy, field_name):
"""
Ritorna il valore del campo definito con schemaextender
"""
field = taxonomy.getField(field_name)
if field:
return field.get(taxonomy)
return ""

 

In questo modo, si possono creare quante sezioni si vogliono, e dare ad ognuna un colore caratteristico diverso. Bisogna solo stare attenti a non usare troppi colori diversi in una pagina, per evitare di avere un "effetto arlecchino" non proprio gradevolissimo.

La foto in testata è di Sultry/sulky/silly, mentre l'immagine nel testo è di Joel Kramer

read more

May 24, 2013

WebHelpers, tanti piccoli aiuti per un web migliore

aiutati che il web ti aiuta!

WebHelpers, tanti piccoli aiuti per un web migliore

Filed Under:

A volte si devono utilizzare finezze per avere un prodotto più gradevole o facilitarne lo sviluppo. Gli strumenti giusti per fare velocemente il lavoro sono fondamentali

Lavorando a un progetto Pyramid mi sono imbattuto in un pacchetto decisamente interessante: webhelpers.

read more

Apr 12, 2013

How to automatically refresh your database in "silent mode"

The nightly wave

How to automatically refresh your database in "silent mode"

Filed Under:

Break away from dependence on the Lotus Notes client to update your database: an easy tutorial to get applications with the latest update every morning

Scenario: a development server, a release server and many production customers' servers: nothing more classic.

Every time a change is deployed on the release server, the best thing would be to "push" it automatically on production server, or as soon as possible (at least).

 

 

read more

Apr 03, 2013

PuDB, ovvero: come ho imparato a velocizzare il mio debug

Bug? Find it!

PuDB, ovvero: come ho imparato a velocizzare il mio debug

Filed Under:

Quando si fa debug di codice poco "docile" è importante avere gli strumenti giusti per non impazzire sprecando tempo prezioso nel trovare il problema

Nella vita di ogni sviluppatore arriva il giorno in cui si incrocia la propria tastiera con codice incomprensibile, dai risultati inspiegabili e che, ovviamente, bisogna correggere. Avere gli strumenti adatti per il debugging è fondamentale.

Come programmatore python ho avuto modo di utilizzare diversi tipi di debugger, dal semplice pdb a una versione più completa: pdb++. Esistono debugger integrati nei vari IDE di sviluppo, di cui però non ho mai approfondito troppo l'uso dal momento che li ho sempre trovato ambienti un po' pesanti. Da amante della shell, divido il mio tempo di sviluppo fra vim e un editor di testo molto semplice come sublime.

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

Filed Under:

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