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

This commit is contained in:
Helmut Merz 2011-12-27 20:10:20 +01:00
parent 71954f3fe5
commit 117d8b194c
4 changed files with 30 additions and 11 deletions

View file

@ -18,8 +18,6 @@
""" """
Schema fields and related classes. Schema fields and related classes.
$Id$
""" """
from datetime import datetime from datetime import datetime
@ -32,7 +30,7 @@ from zope.component import adapts
from zope import component from zope import component
from zope.i18n.format import DateTimeParseError from zope.i18n.format import DateTimeParseError
from zope.i18n.locales import locales 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.engine import Engine
from zope.tales.tales import Context from zope.tales.tales import Context
@ -139,7 +137,14 @@ class Field(Component):
return terms return terms
voc = voc.splitlines() voc = voc.splitlines()
return [dict(token=t, title=t) for t in voc if t.strip()] return [dict(token=t, title=t) for t in voc if t.strip()]
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: else:
return None
return [dict(token=t.token, title=t.title or t.value) for t in voc] return [dict(token=t.token, title=t.title or t.value) for t in voc]
def getVocabularyTerms(self, name, context, request): def getVocabularyTerms(self, name, context, request):
@ -157,12 +162,14 @@ class Field(Component):
def getFieldTypeInfo(self): def getFieldTypeInfo(self):
return self.fieldTypeInfo or fieldTypes.getTerm(self.fieldType) 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 instanceName = self.instance_name or self.getFieldTypeInfo().instanceName
fi = component.queryAdapter(self, IFieldInstance, name=instanceName) fi = component.queryAdapter(self, IFieldInstance, name=instanceName)
if fi is None: if fi is None:
fi = component.getAdapter(self, IFieldInstance, name='') fi = component.getAdapter(self, IFieldInstance, name='')
fi.clientInstance = clientInstance fi.clientInstance = clientInstance
fi.clientContext = context
fi.request = request
return fi return fi
def getContextProperties(self): def getContextProperties(self):
@ -216,6 +223,9 @@ class FieldInstance(object):
self.errors.append(error) self.errors.append(error)
self.severity = max(error.severity, self.severity) self.severity = max(error.severity, self.severity)
def getRenderer(self, name):
return None
class NumberFieldInstance(FieldInstance): class NumberFieldInstance(FieldInstance):
@ -385,7 +395,7 @@ class CheckBoxesFieldInstance(ListFieldInstance):
class DropdownFieldInstance(FieldInstance): class DropdownFieldInstance(FieldInstance):
def display(self, value): def display(self, value):
items = self.context.getVocabularyItems() items = self.context.getVocabularyItems(self.clientContext, self.request)
for item in items: for item in items:
if item['token'] == value: if item['token'] == value:
return item['title'] return item['title']

View file

@ -162,6 +162,8 @@ class KeyTableFieldInstance(RecordsFieldInstance):
def display(self, value): def display(self, value):
headers = [fi.context.title for fi in self.columnFieldInstances] headers = [fi.context.title for fi in self.columnFieldInstances]
rows = [] rows = []
if value is None:
value = {}
for k, v in value.items(): for k, v in value.items():
row = [k] row = [k]
for idx, fi in enumerate(self.columnFieldInstances[1:]): for idx, fi in enumerate(self.columnFieldInstances[1:]):

View file

@ -52,7 +52,8 @@ class Instance(BaseInstance):
if not f.storeData: if not f.storeData:
# a dummy field, e.g. a spacer # a dummy field, e.g. a spacer
continue continue
fi = f.getFieldInstance(self) fi = f.getFieldInstance(self, context=kw.get('context'),
request=kw.get('request'))
name = f.name name = f.name
value = getattr(self.context, name) or fi.default value = getattr(self.context, name) or fi.default
if mode in ('view', 'preview'): if mode in ('view', 'preview'):

View file

@ -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 # 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 # it under the terms of the GNU General Public License as published by
@ -18,8 +18,6 @@
""" """
Schemas and Fields. Schemas and Fields.
$Id$
""" """
from zope import schema from zope import schema
@ -278,6 +276,14 @@ class IFieldInstance(Interface):
allow for checking more than one data element. 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): class IFormState(Interface):
""" Represents the state of all fields when editing. """ Represents the state of all fields when editing.