diff --git a/browser/README.txt b/browser/README.txt index 0f2d99b..20cbbb5 100644 --- a/browser/README.txt +++ b/browser/README.txt @@ -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 form variable (typically coming from a hidden field) with the name '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 >>> class MyController(FormController): ... def update(self): ... print 'updating...' + ... return True >>> component.provideAdapter(MyController, (View, IBrowserRequest), ... IFormController, name='save') diff --git a/composer/schema/field.py b/composer/schema/field.py index 315fff8..1e122d2 100644 --- a/composer/schema/field.py +++ b/composer/schema/field.py @@ -39,6 +39,7 @@ class Field(Component): required = False standardFieldName = None + renderFactory = None def __init__(self, name, title=None, fieldType='textline', **kw): assert name diff --git a/composer/schema/instance.py b/composer/schema/instance.py index 4e598a2..e873b82 100644 --- a/composer/schema/instance.py +++ b/composer/schema/instance.py @@ -24,17 +24,48 @@ $Id$ from BTrees.OOBTree import OOBTree 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.schema.interfaces import IClient from cybertools.composer.schema.schema import FormState -class Editor(Instance): +class Instance(BaseInstance): + + implements(IInstance) + adapts(Interface) 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): for c in self.template.components: diff --git a/composer/schema/interfaces.py b/composer/schema/interfaces.py index a02f719..fec3082 100644 --- a/composer/schema/interfaces.py +++ b/composer/schema/interfaces.py @@ -78,6 +78,7 @@ fieldTypes = SimpleVocabulary(( instanceName='number'), #FieldType('date', 'date', u'Date'), #FieldType('checkbox', 'checkbox', u'Checkbox'), + FieldType('dropdown', 'dropdown', u'Drop-down selection'), FieldType('spacer', 'spacer', u'Spacer', fieldMacro='field_spacer', storeData=False), )) @@ -139,6 +140,12 @@ class IField(IComponent): default=3, 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): """ An adapter for checking and converting data values coming diff --git a/composer/schema/util.py b/composer/schema/util.py index 5f6bc59..5c38c8e 100644 --- a/composer/schema/util.py +++ b/composer/schema/util.py @@ -28,13 +28,14 @@ from cybertools.composer.schema.field import Field fieldMapping = { - schema.TextLine: ('text',), - schema.ASCII: ('text',), + schema.TextLine: ('textline',), + schema.ASCII: ('textline',), schema.Text: ('textarea',), schema.Date: ('date',), schema.Int: ('number',), schema.Bool: ('checkbox',), schema.Choice: ('dropdown',), + schema.Bytes: ('fileupload',), } @@ -44,12 +45,7 @@ def getSchemaFromInterface(ifc, manager): field = ifc[fname] if field.__class__ in fieldMapping: info = fieldMapping[field.__class__] - voc = getattr(field, 'vocabulary', ()) or getattr(field, 'vocabularyName', ()) - if voc: - if isinstance(voc, str): - voc = vocabularies[voc] - else: - voc = [(t.token, t.title or t.token) for t in voc] + voc = getattr(field, 'vocabulary', ()) or getattr(field, 'vocabularyName', None) f = Field(field.getName(), fieldType = info[0], required=field.required,