miziodel

qualche nota su Maurizio Delmonte, il web e tutto..

permalink

ContentMirror modificato per esportare traduzioni LinguaPlone

Le traduzioni di LinguaPlone non sono attualmente gestite da ContentMirror (è ancora nella Maybe list..). Aimè, ne ho bisogno urgentemente e decido di patchare il prodotto..

Ecco come:

1. Nel modulo schema.py va aggiunta la struttura per la tabella translations:

translations = rdb.Table(
"translations",
metadata,
rdb.Column( "source_id", rdb.Integer,
rdb.ForeignKey('content.content_id', ondelete='CASCADE'),
primary_key=True ),
rdb.Column( "target_id", rdb.Integer,
rdb.ForeignKey('content.content_id', ondelete='CASCADE'),
primary_key=True),
rdb.Column( "target_language", rdb.String(8), primary_key=True ),
rdb.Column( "target_state", rdb.String(64), primary_key=False )
)

class Translation( object ):

def __init__( self, source=None, target=None, target_language=None, target_state=None):
self.source = source
self.target = target
self.target_language = target_language
self.target_state = target_state

orm.mapper( Translation, translations,
properties = {
'source': orm.relation(Content, uselist=False, backref='translations',
primaryjoin=content.c.content_id==translations.c.source_id ),
'target': orm.relation(Content, uselist=False,
primaryjoin=content.c.content_id==translations.c.target_id ),
})

NB: ricordate di rilanciare il comando DDL per ottenere la struttura della tabella da creare nel DB..

2. Nel modulo transform.py va aggiunta la gestione delle info delle traduzioni (che non sono agganciate a campi Archetypes, per questo non si riesce a lavorare in modo più *pulito*..). Ho fatto questo modificando il metodo copy della classe SchemaTransformer come segue:

    def copy( self, instance, peer ):
for field in self.context.Schema().fields():
transformer = component.queryMultiAdapter( ( field, self ))
transformer.copy( instance, peer )
# gestione LinguaPlone
value = instance.getTranslations( )
if not value:
return

for lang, (ob, review_state) in value.items():

# no language specified
if not lang:
continue
# not recording the context itself
if ob.UID() == instance.UID():
continue

t_oid = ob.UID()

# fetch the remote side's peer
peer_ob = schema.fromUID( ob.UID() )
if peer_ob is None:
serializer = interfaces.ISerializer( ob, None )
if serializer is None: continue
peer_ob = serializer.add()

# create the translation
translation = schema.Translation( peer, peer_ob, lang, review_state)

Lanciate il bulk e vedrete comparire le info delle vostre traduzioni nella tabella appena creata :)

permalink

SQLAlchemy ProgrammingError: Can't adapt INSERT...

Se ricevi tale errore NON cercare lontano.. ricontrolla tutti i campi che valorizzi uno per uno e verifica che tutti siano del tipo giusto!!

Controlla che nei campi booleani non finiscano stringhe e così via!

Niente di esotico, o di particolare.. ma abbastanza per fare le 2 di notte pensando che sia un problema di SQLAlchemy :/

Que Viva ZODB !!

permalink

Assegnare ruoli locali agli oggetti Plone in modo personalizzato

borg.localrole fa molto bene il suo lavoro!

piazzalo nel buildout, importalo nel configure.zcml del tuo pacchetto, definisci il tuo adapter e il gioco è fatto!

Nota: lancia lo step di importazione fornito col pacchetto in portal_setup!

un paio di adapter a cui ispirarsi sono quelli forniti dal pacchetto stesso: quello di default (che permette alla policy di base di funzionare con il plugin attivato) e quello fornito per lavorare come necessario sugli oggetti temporanei generati dal portal_factory..

permalink

piazzare un'icona nelle action della personal bar in Plone 3.2

mi trovo a scriverlo dato che non era affatto chiaro il modo più rapido :/

alla fine dovrebbe bastare:

  1. piazzare nella action, nella proprietà “icon” un’espressione che risulti True (es. python:True)
  2. piazzare nel CSS una classe corrispondente a .actionicon-categoria_azione-id_azione in cui definire il proprio background image a piacere
permalink

MemberArea selettive in Plone

Ho bisogno di generare aree utente in Plone solo per gli utenti che appartengono a certi gruppi.

Dopo aver studiato le varie possibilità a disposizione ispezionando il codice, ne esce che non c’è modo a basso livello di discriminare la creazione dell’area dell’utente in nessun modo: o ce l’hanno tutti o non ce l’ha nessuno.

Una cosa interessante nasce dal fatto che l’area viene creata (se necessario) al login, quindi si potrebbe intecettare l’evento di login e creare noi manualmente l’area utente solo per chi diciamo noi, ma di fatto equivarrebbe a un gran spreco di codice (da mantenere!), e chissà in quali punti il fatto che il flag di creazione aree utenti è a zero potrebbe dare “noie”.

La scelta per ora semplice consiste nel:

  • creare un proprio oggetto “MemberArea”
  • fare in modo che su tale oggetto il metodo “getLocallyAllowedTypes” che gestisce quali tipi possono essere aggiunti localmente sia condizionato a quel che vogliamo noi!

facile no? :)

permalink

I perchè di Repoze.bfg..

Why?

Familiarity: As web developers, we’ve become accustomed to working in very particular ways over the years. This framework is a canonization of practices that “fit our brains”.

Simplicity: repoze.bfg attempts to be a “pay only for what you eat” framework in which you can be productive quickly with partial knowledge. We contrast this with “pay up front for what anyone might eventually want to eat” frameworks, which tend to expect you to understand a great many concepts and technologies fully before you can be truly productive. repoze.bfg doesn’t force you to use any particular technology to produce an application, and we try to keep the core set of concepts you need to understand to a minimum.

Minimalism: repoze.bfg provides only the very basics: URL to code mapping, templating, security, and resources. There is not much more to the framework than these pieces: you are expected to provide the rest.

Documentation: Because repoze.bfg is minimal, it’s relatively easy to keep its documentation up-to-date, which is helpful to bring new developers up to speed. It’s our goal that nothing remain undocumented about repoze.bfg.

Speed: repoze.bfg is faster than many other popular Python web frameworks for common tasks such as templating and simple response generation. The “hardware is cheap” mantra has its limits when you’re responsible for managing a great many machines: the fewer you need, the less pain you’ll have.

[leggi il resto..]

permalink

Aggiornare i valori a una form z3c.form

z3c.form è una libreria capace di costruire da codice le form web di cui abbiamo bisogno in ambiente python/zope.

Molti pacchetti più specializzati ne fanno uso, anche in ambito Plone, mediante plone.z3cform. Per iniziare ad utilizzare plone.z3cform suggerisco di usare il tutorial scritto da Daniel Nouri su plone.org: http://plone.org/documentation/how-to/easy-forms-with-plone.

Fatto il preambolo, ecco il problema: come impostare dei valori nei widget del form prendendoli magari da una querystring impostata?

la mia soluzione, mettere nella classe che eredita da form.Form questo metodo:

def update(self):
  # lascio costruire i widget
self.updateWidgets() # ottengo i valori da preimpostare dalla querystring for k,v in self.request.form.items():
wdg = self.widgets.get(k)
if wdg:
wdg.value = v
# aggiorno il widget se ne ha bisogno per il rendering
if IChoice.providedBy(wdg.field):
wdg.update()
# aggiorno le action e le eseguo
self.updateActions()
self.actions.execute()

Che ne dite? C’è un modo più pulito di farlo?

permalink
That huge learning curve that everyone talks about may just turn out to be a myth. Heavy customization may take you deep into the bowels of Zope, but I rarely need more than CSS, ArgoUML, and cursory Python ability to produce wonderfully sophisticated portals. One doesn’t need to know eight frameworks to be able to deploy a Plone site.
permalink
La parola d’ordine è intraprendenza. Purtroppo il lavoro come ce lo hanno spiegato i nostri genitori non esiste più. Non esiste più il posto fisso, tanto che secondo i dati della Banca d’Italia oltre il 50% dei nuovi contratti sono atipici (progetto, partita Iva, tempo determinato, ecc.).
permalink

Note su collective.solr in ordine sparso

  • il portal_catalog NON va eliminato, a meno che non si decida di usare solo solr per tutte le esigenze di indicizzazione del portale plone (in tal caso andare nel pannello di controllo ed eliminare SearchableText dai parametri richiesti per il dispatch a solr della query (di default, solr non viene interpellato se nella query non compare il parametro SearchableText! occhio agli effetti collaterali!). Attenzione che costruire la navigazione mediante il portal_catalog dovrebbe essere in ogni caso conveniente, magari spostandolo in uno ZODB a parte.
  • l’indice SearchableText va eliminato dal portal_catalog, in modo da evitare la doppia indicizzazione
  • nel buildout solr-instance.cfg nello specificare gli indici si può anche chiedere di mantenere un attributo stored ma non indexed. gli indici stored vengono usati per poter costruire la lista dei risultati delle query (come i metadati in portal_catalog)
  • nell’aggiungere nuovi indici nel solr-instance.cfg tenere presente che se gli indici non sono presenti anche in portal_catalog è necessario nello script queryCatalog aggiungere tali indici mediante il parametro quote_logic_indexes, altrimenti verranno spazzati via dalla query
prossime note al prossimo post..