Creare un widget personalizzato con Archetypes
Plone: come personalizzare l'inserimento e la visualizzazione dei dati nei nostri tipi di contenuti.
Mi occorreva un widget personalizzato per un mio content type quindi mi sono dovuto studiare il funzionamento del modulo Products.Archetypes.widget
Con piacevole sorpresa ho capito che la creazione di un widget personalizzato non è troppo complicato.
Buona parte delle funzionalità del mio widgets sono già presenti in StringWidget, uno dei widget più comuni.
Premesse
Quando ci si aproccia ai widget di Archetypes bisogna tenere presente alcune cose fondamenteali:
La prima è che ciascun widget può essere associato a uno o più Field di Archetypes.
La seconda è che ogni widget può avere principalmente due modalità: edit e view. La prima viene utilizzata per visualizzare il widget per l'inserimento e la modifica dei dati il secondo per la loro visualizzazione.
Per fare questo i procedimenti da seguire sono esattamente tre:
- creare una classe widget che contenga le proprietà ed i metodi necessari al suo funzionamento
- registrare il widget per uno o più tipi di campo
- realizzare un template contenente una particolare macro per ogni modalità del widget
Realizzazione
All'interno del mio pacchetto creo un modulo widget.py che contiene la definizione del widget:
from Products.Archetypes.Widget import StringWidget
from Products.Archetypes.Registry import registerWidget
class MyStringWidget(StringWidget):
"""Un widget personalizzato basato su StringWidget"""
# copio le proprietà del widget originario
_properties = StringWidget._properties.copy()
# qui posso aggiungere tutte le proprietà che voglio
# esse potranno essere impostate alla definizione dello
# schema del mio archetype
_properties.update({
'macro' : "mystring_widget", # questo è il page template
# che verrà utilizzato dal widget
'mia_proprieta' : 'una proprietà personalizzata'
})
def simpleValue(self):
"""Oltre a personalizzare ogni metodo originario
posso creare tutti i metodi che voglio"""
return u"Troppo fico questo tutorial!!!"
# alla fine posso registrare il widget per un campo particolare
registerWidget(MyStringWidget,
title='MyWidget',
description=('Descrizione del mio widget'),
used_for=('Products.Archetypes.Field.StringField'))
Adesso posso registrare il template -- mystring_widget.pt -- per il mio widget in uno skin layer copiando alla grande da string.pt ;-)
...
<!-- macro per la modalità view -->
<metal:view_macro define-macro="view"
tal:define="kssClassesView context/@@kss_field_decorator_view;
getKssClasses nocall:kssClassesView/getKssClassesInlineEditable;">
<span metal:define-macro="string-field-view"
tal:define="kss_class python:getKssClasses(fieldName,
templateId='widgets/mystring_widget', macro='string-field-view');"
tal:attributes="class kss_class;
id string:parent-fieldname-$fieldName">
<!-- richiamando accessor() visualizzo
il valore del campo associato al widget -->
<span metal:define-slot="inside"
tal:replace="accessor">string</span>
<!-- posso richiamare i metodi del mio widget nel seguente modo -->
<span tal:replace="widget/simpleValue">valore del metodo simpleValue</span>
</span>
</metal:view_macro>
<!-- macro per la modalità di edit
l'ho lasciata uguale all'originale cfr. string.pt -->
<metal:define define-macro="edit">
<metal:use use-macro="field_macro | here/widgets/field/macros/edit">
<input metal:fill-slot="widget_body"
...
/>
</metal:use>
</metal:define>
...
Partendo da questa base posso quindi creare i widget che voglio a seconda del caso; consiglio di guardare cosa fanno i widget di default di Archetypes piuttosto che guardare il funzionamento di quelli nella sezione prodotti di plone.org.

Del.icio.us
Facebook
Google Bookmarks
Technorati
Twitter
Digg
Reddit