provide preset concept lists (via type option qualifier:assign) for create and edit dialog

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1616 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-03-06 15:20:50 +00:00
parent d44b721a89
commit 483a730c6c
3 changed files with 80 additions and 5 deletions

View file

@ -608,6 +608,45 @@ Creating an object
>>> from loops.browser.form import CreateObjectForm, CreateObject
>>> form = CreateObjectForm(m112, TestRequest())
The form provides a set of data entry fields derived from the interface
associated with the new object's resource (or concept) type.
In addition it allows to assign concepts as parents to the object. Beside
an integrated free search for concepts to assign there may be a list of
preset concepts, e.g. depending on the target of the current node:
>>> form.assignments
()
>>> m112.target = cc1
>>> form = CreateObjectForm(m112, TestRequest())
>>> form.assignments
(<...ConceptRelationView object ...>,)
There also may be preset concept types that directly provide lists of
concepts to select from.
To show this let's start with a new type, the customer type.
>>> customer = concepts['customer'] = Concept('Customer')
>>> customer.conceptType = concepts.getTypeConcept()
>>> from loops.type import ConceptType, TypeConcept
>>> custType = TypeConcept(customer)
>>> custType.options
[]
>>> cust1 = concepts['cust1'] = Concept(u'Zope Corporation')
>>> cust2 = concepts['cust2'] = Concept(u'cyberconcepts')
>>> for c in (cust1, cust2): c.conceptType = customer
>>> custType.options = ('qualifier:assign',)
>>> ConceptType(cust1).qualifiers
('concept', 'assign')
>>> form = CreateObjectForm(m112, TestRequest())
>>> form.presetTypesForAssignment
[{'token': 'loops:concept:customer', 'title': 'Customer'}]
OK, so much about the form - now we want to create a new object based
on data provided in this form:
>>> from loops.interfaces import INote, ITypeConcept
>>> from loops.type import TypeConcept
>>> from loops.resource import NoteAdapter
@ -708,7 +747,7 @@ target object's view here:
[<loops.browser.common.Action object ...>]
>>> action = view.virtualTarget.getActions()[0]
>>> action.url
'http://127.0.0.1/loops/views/m1/m11/m111/.target16'
'http://127.0.0.1/loops/views/m1/m11/m111/.target19'
Import/Export

View file

@ -40,12 +40,13 @@ from zope.security.proxy import isinstance
from cybertools.ajax import innerHtml
from cybertools.browser.form import FormController
from cybertools.typology.interfaces import IType
from cybertools.typology.interfaces import IType, ITypeManager
from loops.concept import ResourceRelation
from loops.interfaces import IConcept, IResourceManager, IDocument
from loops.interfaces import IFile, IExternalFile, INote
from loops.browser.node import NodeView
from loops.browser.concept import ConceptRelationView
from loops.query import ConceptQuery
from loops.resource import Resource
from loops.type import ITypeConcept
from loops import util
@ -98,8 +99,27 @@ class ObjectForm(NodeView):
@Lazy
def defaultPredicate(self):
return util.getUidForObject(
self.loopsRoot.getConceptManager().getDefaultPredicate())
return self.loopsRoot.getConceptManager().getDefaultPredicate()
@Lazy
def typeManager(self):
return ITypeManager(self.context)
@Lazy
def presetTypesForAssignment(self):
types = list(self.typeManager.listTypes(include=('assign',)))
assigned = [r.context.conceptType for r in self.assignments]
types = [t for t in types if t.typeProvider not in assigned]
return [dict(title=t.title, token=t.tokenForSearch) for t in types]
def conceptsForType(self, token):
noSelection = dict(token='none', title=u'not selected')
result = sorted(ConceptQuery(self).query(type=token), key=lambda x: x.title)
predicateUid = util.getUidForObject(self.defaultPredicate)
return ([noSelection] +
[dict(title=o.title,
token='%s:%s' % (util.getUidForObject(o), predicateUid))
for o in result])
class WidgetController(object):
@ -241,6 +261,9 @@ class EditObject(FormController):
if fn.startswith(self.conceptPrefix) and value:
self.collectConcepts(fn[len(self.conceptPrefix):], value)
else:
if not value and fn == 'data' and IFile.providedBy(adapted):
# empty file data - don' change
continue
if isinstance(value, FileUpload):
filename = getattr(value, 'filename', '')
value = value.read()
@ -273,7 +296,7 @@ class EditObject(FormController):
predicate = util.getObjectForUid(p)
obj.deassignConcept(concept, [predicate])
for v in self.selected:
if v not in self.old:
if v != 'none' and v not in self.old:
c, p = v.split(':')
concept = util.getObjectForUid(c)
predicate = util.getObjectForUid(p)

View file

@ -105,6 +105,19 @@
<metal:assignments define-macro="assignments">
<tbody id="form.assignments">
<tr tal:repeat="type view/presetTypesForAssignment">
<td><span i18n:translate="">Type: </span></td>
<td><b tal:content="type/title" /></td>
<td><span i18n:translate="">Select value: </span></td>
<td colspan="2">
<select name="form.assignments.selected:list">
<tal:concepts repeat="concept python: view.conceptsForType(type['token'])">
<option tal:attributes="value concept/token"
tal:content="concept/title">Zope Corp</option>
</tal:concepts>
</select>
</td>
</tr>
<tr tal:repeat="relation view/assignments">
<td colspan="5">
<input type="hidden" name="form.assignments.old:list"