From 117d8b194cbd6fe37794c4d94d7a99d6b3aac237 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Tue, 27 Dec 2011 20:10:20 +0100 Subject: [PATCH] backport changes from BlueBream version, e.g. for dynamic retrieving renderer; provide context and request for field instance in order to work with vocabularies depending on context --- composer/schema/field.py | 24 +++++++++++++++++------- composer/schema/grid/field.py | 2 ++ composer/schema/instance.py | 3 ++- composer/schema/interfaces.py | 12 +++++++++--- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/composer/schema/field.py b/composer/schema/field.py index 3509b7b..dc89e92 100644 --- a/composer/schema/field.py +++ b/composer/schema/field.py @@ -18,8 +18,6 @@ """ Schema fields and related classes. - -$Id$ """ from datetime import datetime @@ -32,7 +30,7 @@ from zope.component import adapts from zope import component from zope.i18n.format import DateTimeParseError from zope.i18n.locales import locales -from zope.schema.interfaces import IVocabularyFactory +from zope.schema.interfaces import IVocabularyFactory, IContextSourceBinder from zope.tales.engine import Engine from zope.tales.tales import Context @@ -139,8 +137,15 @@ class Field(Component): return terms voc = voc.splitlines() return [dict(token=t, title=t) for t in voc if t.strip()] - else: - return [dict(token=t.token, title=t.title or t.value) for t in voc] + elif IContextSourceBinder.providedBy(voc): + source = voc(context) + terms = component.queryMultiAdapter((source, request), ITerms) + if terms is not None: + termsList = [terms.getTerm(value) for value in source] + return [dict(token=t.token, title=t.title) for t in termsList] + else: + return None + return [dict(token=t.token, title=t.title or t.value) for t in voc] def getVocabularyTerms(self, name, context, request): if context is None or request is None: @@ -157,12 +162,14 @@ class Field(Component): def getFieldTypeInfo(self): return self.fieldTypeInfo or fieldTypes.getTerm(self.fieldType) - def getFieldInstance(self, clientInstance=None): + def getFieldInstance(self, clientInstance=None, context=None, request=None): instanceName = self.instance_name or self.getFieldTypeInfo().instanceName fi = component.queryAdapter(self, IFieldInstance, name=instanceName) if fi is None: fi = component.getAdapter(self, IFieldInstance, name='') fi.clientInstance = clientInstance + fi.clientContext = context + fi.request = request return fi def getContextProperties(self): @@ -216,6 +223,9 @@ class FieldInstance(object): self.errors.append(error) self.severity = max(error.severity, self.severity) + def getRenderer(self, name): + return None + class NumberFieldInstance(FieldInstance): @@ -385,7 +395,7 @@ class CheckBoxesFieldInstance(ListFieldInstance): class DropdownFieldInstance(FieldInstance): def display(self, value): - items = self.context.getVocabularyItems() + items = self.context.getVocabularyItems(self.clientContext, self.request) for item in items: if item['token'] == value: return item['title'] diff --git a/composer/schema/grid/field.py b/composer/schema/grid/field.py index e5c8152..b2eefc9 100644 --- a/composer/schema/grid/field.py +++ b/composer/schema/grid/field.py @@ -162,6 +162,8 @@ class KeyTableFieldInstance(RecordsFieldInstance): def display(self, value): headers = [fi.context.title for fi in self.columnFieldInstances] rows = [] + if value is None: + value = {} for k, v in value.items(): row = [k] for idx, fi in enumerate(self.columnFieldInstances[1:]): diff --git a/composer/schema/instance.py b/composer/schema/instance.py index 682898f..1c5ffbf 100644 --- a/composer/schema/instance.py +++ b/composer/schema/instance.py @@ -52,7 +52,8 @@ class Instance(BaseInstance): if not f.storeData: # a dummy field, e.g. a spacer continue - fi = f.getFieldInstance(self) + fi = f.getFieldInstance(self, context=kw.get('context'), + request=kw.get('request')) name = f.name value = getattr(self.context, name) or fi.default if mode in ('view', 'preview'): diff --git a/composer/schema/interfaces.py b/composer/schema/interfaces.py index 6ed3551..9e3f809 100644 --- a/composer/schema/interfaces.py +++ b/composer/schema/interfaces.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2010 Helmut Merz helmutm@cy55.de +# Copyright (c) 2011 Helmut Merz helmutm@cy55.de # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -18,8 +18,6 @@ """ Schemas and Fields. - -$Id$ """ from zope import schema @@ -278,6 +276,14 @@ class IFieldInstance(Interface): allow for checking more than one data element. """ + def getRenderer(name): + """ Return the renderer object (e.g. a ZPT macro) for this field + with the name given. + + May return None in which case the calling application should + use a default renderer. + """ + class IFormState(Interface): """ Represents the state of all fields when editing.