more on schemas and fields: make it usable for interface-driven form generation; + minor bug fixes

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1998 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-09-05 07:40:55 +00:00
parent aadd146ae8
commit 7b553a5955
5 changed files with 50 additions and 12 deletions

View file

@ -220,12 +220,15 @@ Real work can only be done by an adapter to GenericView that provides the
IFormController interface with its update(). There also must be a IFormController interface with its update(). There also must be a
form variable (typically coming from a hidden field) with the name form variable (typically coming from a hidden field) with the name
'form.action' that provides the name under which the form controller is 'form.action' that provides the name under which the form controller is
registered. registered. The ``update()`` method should return a boolean that indicates
if the view should be rendered or not; return ``False`` e.g. if the form
controller issues a redirect.
>>> from cybertools.browser.form import IFormController, FormController >>> from cybertools.browser.form import IFormController, FormController
>>> class MyController(FormController): >>> class MyController(FormController):
... def update(self): ... def update(self):
... print 'updating...' ... print 'updating...'
... return True
>>> component.provideAdapter(MyController, (View, IBrowserRequest), >>> component.provideAdapter(MyController, (View, IBrowserRequest),
... IFormController, name='save') ... IFormController, name='save')

View file

@ -39,6 +39,7 @@ class Field(Component):
required = False required = False
standardFieldName = None standardFieldName = None
renderFactory = None
def __init__(self, name, title=None, fieldType='textline', **kw): def __init__(self, name, title=None, fieldType='textline', **kw):
assert name assert name

View file

@ -24,17 +24,48 @@ $Id$
from BTrees.OOBTree import OOBTree from BTrees.OOBTree import OOBTree
from zope.component import adapts from zope.component import adapts
from zope.interface import implements from zope.interface import implements, Interface
from cybertools.composer.instance import Instance from cybertools.composer.instance import Instance as BaseInstance
from cybertools.composer.interfaces import IInstance from cybertools.composer.interfaces import IInstance
from cybertools.composer.schema.interfaces import IClient from cybertools.composer.schema.interfaces import IClient
from cybertools.composer.schema.schema import FormState from cybertools.composer.schema.schema import FormState
class Editor(Instance): class Instance(BaseInstance):
implements(IInstance)
adapts(Interface)
aspect = 'schema.editor.default' aspect = 'schema.editor.default'
template = None
def applyTemplate(self, *args, **kw):
#result = dict(__name__=self.context.__name__)
result = {}
mode = kw.get('mode', 'view')
template = self.template
if template is not None:
for f in template.components:
fieldType = f.getFieldTypeInfo()
if not fieldType.storeData:
# a dummy field, e.g. a spacer
continue
fi = f.getFieldInstance()
name = f.name
value = getattr(self.context, name, u'')
value = (mode == 'view' and fi.display(value)) or fi.marshall(value)
result[name] = value
return result
class Editor(BaseInstance):
implements(IInstance)
adapts(Interface)
aspect = 'schema.editor.default'
template = None
def applyTemplate(self, data={}, *args, **kw): def applyTemplate(self, data={}, *args, **kw):
for c in self.template.components: for c in self.template.components:

View file

@ -78,6 +78,7 @@ fieldTypes = SimpleVocabulary((
instanceName='number'), instanceName='number'),
#FieldType('date', 'date', u'Date'), #FieldType('date', 'date', u'Date'),
#FieldType('checkbox', 'checkbox', u'Checkbox'), #FieldType('checkbox', 'checkbox', u'Checkbox'),
FieldType('dropdown', 'dropdown', u'Drop-down selection'),
FieldType('spacer', 'spacer', u'Spacer', fieldMacro='field_spacer', FieldType('spacer', 'spacer', u'Spacer', fieldMacro='field_spacer',
storeData=False), storeData=False),
)) ))
@ -139,6 +140,12 @@ class IField(IComponent):
default=3, default=3,
required=False,) required=False,)
renderFactory = Attribute('A class or another factory providing an '
'object used for rendering the data e.g. as a '
'cell on a tabular report. See cybertools.reporter. '
'May become replaced with a more intelligent kind of '
'field instance.')
class IFieldInstance(Interface): class IFieldInstance(Interface):
""" An adapter for checking and converting data values coming """ An adapter for checking and converting data values coming

View file

@ -28,13 +28,14 @@ from cybertools.composer.schema.field import Field
fieldMapping = { fieldMapping = {
schema.TextLine: ('text',), schema.TextLine: ('textline',),
schema.ASCII: ('text',), schema.ASCII: ('textline',),
schema.Text: ('textarea',), schema.Text: ('textarea',),
schema.Date: ('date',), schema.Date: ('date',),
schema.Int: ('number',), schema.Int: ('number',),
schema.Bool: ('checkbox',), schema.Bool: ('checkbox',),
schema.Choice: ('dropdown',), schema.Choice: ('dropdown',),
schema.Bytes: ('fileupload',),
} }
@ -44,12 +45,7 @@ def getSchemaFromInterface(ifc, manager):
field = ifc[fname] field = ifc[fname]
if field.__class__ in fieldMapping: if field.__class__ in fieldMapping:
info = fieldMapping[field.__class__] info = fieldMapping[field.__class__]
voc = getattr(field, 'vocabulary', ()) or getattr(field, 'vocabularyName', ()) voc = getattr(field, 'vocabulary', ()) or getattr(field, 'vocabularyName', None)
if voc:
if isinstance(voc, str):
voc = vocabularies[voc]
else:
voc = [(t.token, t.title or t.token) for t in voc]
f = Field(field.getName(), f = Field(field.getName(),
fieldType = info[0], fieldType = info[0],
required=field.required, required=field.required,