provide create and edit dialogs for concepts - starting with glossary items
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2209 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
3a3755f466
commit
309f5f1e21
13 changed files with 228 additions and 73 deletions
|
@ -239,10 +239,13 @@ class BaseView(GenericView):
|
||||||
def listTypes(self, include=None, exclude=None, sortOn='title'):
|
def listTypes(self, include=None, exclude=None, sortOn='title'):
|
||||||
types = [dict(token=t.token, title=t.title)
|
types = [dict(token=t.token, title=t.title)
|
||||||
for t in ITypeManager(self.context).listTypes(include, exclude)]
|
for t in ITypeManager(self.context).listTypes(include, exclude)]
|
||||||
if sortOn:
|
#if sortOn:
|
||||||
types.sort(key=lambda x: x[sortOn])
|
# types.sort(key=lambda x: x[sortOn])
|
||||||
return types
|
return types
|
||||||
|
|
||||||
|
def getTypesVocabulary(self, include=None):
|
||||||
|
return util.KeywordVocabulary(self.listTypes(include, ('hidden',)))
|
||||||
|
|
||||||
def resourceTypes(self):
|
def resourceTypes(self):
|
||||||
return util.KeywordVocabulary(self.listTypes(('resource',), ('hidden',)))
|
return util.KeywordVocabulary(self.listTypes(('resource',), ('hidden',)))
|
||||||
#if t.factory == Resource]) # ? if necessary -> type.qualifiers
|
#if t.factory == Resource]) # ? if necessary -> type.qualifiers
|
||||||
|
@ -377,16 +380,6 @@ class BaseView(GenericView):
|
||||||
cm.register('js', 'dojo.js', resourceName='ajax.dojo/dojo.js')
|
cm.register('js', 'dojo.js', resourceName='ajax.dojo/dojo.js')
|
||||||
|
|
||||||
|
|
||||||
# actions - obsolete, see loops.browser.action
|
|
||||||
|
|
||||||
#class Action(object):
|
|
||||||
|
|
||||||
# def __init__(self, renderer, url, **kw):
|
|
||||||
# self.renderer = renderer
|
|
||||||
# self.url = url
|
|
||||||
# self.__dict__.update(kw)
|
|
||||||
|
|
||||||
|
|
||||||
# vocabulary stuff
|
# vocabulary stuff
|
||||||
|
|
||||||
class LoopsTerms(object):
|
class LoopsTerms(object):
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2004 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2007 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
|
||||||
|
@ -60,10 +60,13 @@ class ConceptEditForm(EditForm):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def form_fields(self):
|
def form_fields(self):
|
||||||
fields = FormFields(IConcept)
|
|
||||||
typeInterface = self.typeInterface
|
typeInterface = self.typeInterface
|
||||||
if typeInterface is not None:
|
if typeInterface is None:
|
||||||
fields = FormFields(fields, typeInterface)
|
fields = FormFields(IConcept)
|
||||||
|
elif 'title' in typeInterface: # new "complete" type interface
|
||||||
|
fields = FormFields(typeInterface)
|
||||||
|
else:
|
||||||
|
fields = FormFields(IConcept, typeInterface)
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
def setUpWidgets(self, ignore_request=False):
|
def setUpWidgets(self, ignore_request=False):
|
||||||
|
@ -96,9 +99,12 @@ class ConceptView(BaseView):
|
||||||
|
|
||||||
def fieldData(self):
|
def fieldData(self):
|
||||||
ti = IType(self.context).typeInterface
|
ti = IType(self.context).typeInterface
|
||||||
if not ti: return
|
if not ti:
|
||||||
|
return
|
||||||
adapter = ti(self.context)
|
adapter = ti(self.context)
|
||||||
for n, f in schema.getFieldsInOrder(ti):
|
for n, f in schema.getFieldsInOrder(ti):
|
||||||
|
if n in ('title', 'description',): # already shown in header
|
||||||
|
continue
|
||||||
value = getattr(adapter, n, '')
|
value = getattr(adapter, n, '')
|
||||||
if not value:
|
if not value:
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -557,6 +557,13 @@
|
||||||
permission="zope.ManageContent"
|
permission="zope.ManageContent"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<page
|
||||||
|
name="create_concept.html"
|
||||||
|
for="loops.interfaces.INode"
|
||||||
|
class="loops.browser.form.CreateConceptForm"
|
||||||
|
permission="zope.ManageContent"
|
||||||
|
/>
|
||||||
|
|
||||||
<page
|
<page
|
||||||
name="edit_concept.html"
|
name="edit_concept.html"
|
||||||
for="loops.interfaces.INode"
|
for="loops.interfaces.INode"
|
||||||
|
@ -571,6 +578,13 @@
|
||||||
permission="zope.ManageContent"
|
permission="zope.ManageContent"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<page
|
||||||
|
name="inner_concept_form.html"
|
||||||
|
for="loops.interfaces.INode"
|
||||||
|
class="loops.browser.form.InnerConceptForm"
|
||||||
|
permission="zope.ManageContent"
|
||||||
|
/>
|
||||||
|
|
||||||
<zope:adapter
|
<zope:adapter
|
||||||
name="create_resource"
|
name="create_resource"
|
||||||
for="loops.browser.node.NodeView
|
for="loops.browser.node.NodeView
|
||||||
|
@ -587,6 +601,22 @@
|
||||||
permission="zope.ManageContent"
|
permission="zope.ManageContent"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<zope:adapter
|
||||||
|
name="create_concept"
|
||||||
|
for="loops.browser.node.NodeView
|
||||||
|
zope.publisher.interfaces.browser.IBrowserRequest"
|
||||||
|
factory="loops.browser.form.CreateConcept"
|
||||||
|
permission="zope.ManageContent"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<zope:adapter
|
||||||
|
name="edit_concept"
|
||||||
|
for="loops.browser.node.NodeView
|
||||||
|
zope.publisher.interfaces.browser.IBrowserRequest"
|
||||||
|
factory="loops.browser.form.EditConcept"
|
||||||
|
permission="zope.ManageContent"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- inner HTML views -->
|
<!-- inner HTML views -->
|
||||||
|
|
||||||
<page
|
<page
|
||||||
|
|
158
browser/form.py
158
browser/form.py
|
@ -25,6 +25,7 @@ $Id$
|
||||||
from zope import component, interface, schema
|
from zope import component, interface, schema
|
||||||
from zope.component import adapts
|
from zope.component import adapts
|
||||||
from zope.event import notify
|
from zope.event import notify
|
||||||
|
from zope.interface import Interface
|
||||||
from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
|
from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
|
||||||
|
|
||||||
from zope.app.container.interfaces import INameChooser
|
from zope.app.container.interfaces import INameChooser
|
||||||
|
@ -46,8 +47,8 @@ from cybertools.composer.schema.browser.common import schema_macros, schema_edit
|
||||||
from cybertools.composer.schema.schema import FormState
|
from cybertools.composer.schema.schema import FormState
|
||||||
from cybertools.typology.interfaces import IType, ITypeManager
|
from cybertools.typology.interfaces import IType, ITypeManager
|
||||||
from loops.common import adapted
|
from loops.common import adapted
|
||||||
from loops.concept import Concept, ResourceRelation
|
from loops.concept import Concept, ConceptRelation, ResourceRelation
|
||||||
from loops.interfaces import IConcept, IResourceManager, IDocument
|
from loops.interfaces import IConcept, IConceptSchema, IResourceManager, IDocument
|
||||||
from loops.interfaces import IFile, IExternalFile, INote, ITextDocument
|
from loops.interfaces import IFile, IExternalFile, INote, ITextDocument
|
||||||
from loops.browser.node import NodeView
|
from loops.browser.node import NodeView
|
||||||
from loops.browser.concept import ConceptRelationView
|
from loops.browser.concept import ConceptRelationView
|
||||||
|
@ -98,9 +99,10 @@ class ObjectForm(NodeView):
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def schema(self):
|
def schema(self):
|
||||||
|
#ti = self.typeInterface or Interface #IConcept
|
||||||
|
ti = self.typeInterface or IConceptSchema
|
||||||
schemaFactory = component.getAdapter(self.adapted, ISchemaFactory)
|
schemaFactory = component.getAdapter(self.adapted, ISchemaFactory)
|
||||||
return schemaFactory(self.typeInterface, manager=self,
|
return schemaFactory(ti, manager=self, request=self.request)
|
||||||
request=self.request)
|
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def fields(self):
|
def fields(self):
|
||||||
|
@ -186,11 +188,10 @@ class EditConceptForm(EditObjectForm):
|
||||||
|
|
||||||
title = _(u'Edit Concept')
|
title = _(u'Edit Concept')
|
||||||
form_action = 'edit_concept'
|
form_action = 'edit_concept'
|
||||||
isInnerHtml = False
|
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def typeInterface(self):
|
def typeInterface(self):
|
||||||
return IType(self.target).typeInterface or IConcept
|
return IType(self.target).typeInterface or IConceptSchema
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def assignments(self):
|
def assignments(self):
|
||||||
|
@ -224,13 +225,11 @@ class CreateObjectForm(ObjectForm):
|
||||||
t = self.loopsRoot.loopsTraverse(typeToken)
|
t = self.loopsRoot.loopsTraverse(typeToken)
|
||||||
return removeSecurityProxy(ITypeConcept(t).typeInterface)
|
return removeSecurityProxy(ITypeConcept(t).typeInterface)
|
||||||
else:
|
else:
|
||||||
#return INote
|
|
||||||
return ITextDocument
|
return ITextDocument
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def assignments(self):
|
def assignments(self):
|
||||||
target = self.virtualTargetObject
|
target = self.virtualTargetObject
|
||||||
#target = self.target
|
|
||||||
if (IConcept.providedBy(target) and
|
if (IConcept.providedBy(target) and
|
||||||
target.conceptType !=
|
target.conceptType !=
|
||||||
self.loopsRoot.getConceptManager().getTypeConcept()):
|
self.loopsRoot.getConceptManager().getTypeConcept()):
|
||||||
|
@ -239,10 +238,58 @@ class CreateObjectForm(ObjectForm):
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
|
|
||||||
|
class CreateConceptForm(CreateObjectForm):
|
||||||
|
|
||||||
|
title = _(u'Create Concept, Type = ')
|
||||||
|
form_action = 'create_concept'
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def dialog_name(self):
|
||||||
|
return self.request.get('dialog', 'createConcept')
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def adapted(self):
|
||||||
|
ti = self.typeInterface
|
||||||
|
if ti is None:
|
||||||
|
return Concept()
|
||||||
|
return ti(Concept())
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def instance(self):
|
||||||
|
return IInstance(Concept())
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def typeInterface(self):
|
||||||
|
typeToken = self.request.get('form.type')
|
||||||
|
if typeToken:
|
||||||
|
t = self.loopsRoot.loopsTraverse(typeToken)
|
||||||
|
return removeSecurityProxy(ITypeConcept(t).typeInterface)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def assignments(self):
|
||||||
|
target = self.virtualTargetObject
|
||||||
|
if (IConcept.providedBy(target) and
|
||||||
|
target.conceptType !=
|
||||||
|
self.loopsRoot.getConceptManager().getTypeConcept()):
|
||||||
|
rv = ConceptRelationView(ConceptRelation(target, None), self.request)
|
||||||
|
return (rv,)
|
||||||
|
return ()
|
||||||
|
|
||||||
|
|
||||||
class InnerForm(CreateObjectForm):
|
class InnerForm(CreateObjectForm):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def macro(self): return self.fieldRenderers['fields']
|
def macro(self):
|
||||||
|
return self.fieldRenderers['fields']
|
||||||
|
|
||||||
|
|
||||||
|
class InnerConceptForm(CreateConceptForm):
|
||||||
|
|
||||||
|
@property
|
||||||
|
def macro(self):
|
||||||
|
return self.fieldRenderers['fields']
|
||||||
|
|
||||||
|
|
||||||
# processing form input
|
# processing form input
|
||||||
|
@ -296,12 +343,6 @@ class EditObject(FormController):
|
||||||
self.object = obj
|
self.object = obj
|
||||||
formState = self.updateFields()
|
formState = self.updateFields()
|
||||||
# TODO: error handling
|
# TODO: error handling
|
||||||
#errors = self.updateFields()
|
|
||||||
#if errors:
|
|
||||||
# self.view.setUp()
|
|
||||||
# for fieldName, message in errors.items():
|
|
||||||
# self.view.widgets[fieldName].error = message
|
|
||||||
# return True
|
|
||||||
self.request.response.redirect(self.view.virtualTargetUrl + '?version=this')
|
self.request.response.redirect(self.view.virtualTargetUrl + '?version=this')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -342,8 +383,10 @@ class EditObject(FormController):
|
||||||
return dict(fileupload=self.handleFileUpload)
|
return dict(fileupload=self.handleFileUpload)
|
||||||
|
|
||||||
def collectConcepts(self, fieldName, value):
|
def collectConcepts(self, fieldName, value):
|
||||||
if self.old is None: self.old = []
|
if self.old is None:
|
||||||
if self.selected is None: self.selected = []
|
self.old = []
|
||||||
|
if self.selected is None:
|
||||||
|
self.selected = []
|
||||||
for v in value:
|
for v in value:
|
||||||
if fieldName == 'old':
|
if fieldName == 'old':
|
||||||
self.old.append(v)
|
self.old.append(v)
|
||||||
|
@ -356,15 +399,24 @@ class EditObject(FormController):
|
||||||
c, p = v.split(':')
|
c, p = v.split(':')
|
||||||
concept = util.getObjectForUid(c)
|
concept = util.getObjectForUid(c)
|
||||||
predicate = util.getObjectForUid(p)
|
predicate = util.getObjectForUid(p)
|
||||||
obj.deassignConcept(concept, [predicate])
|
self.deassignConcept(obj, concept, [predicate])
|
||||||
for v in self.selected:
|
for v in self.selected:
|
||||||
if v != 'none' and v not in self.old:
|
if v != 'none' and v not in self.old:
|
||||||
c, p = v.split(':')
|
c, p = v.split(':')
|
||||||
concept = util.getObjectForUid(c)
|
concept = util.getObjectForUid(c)
|
||||||
predicate = util.getObjectForUid(p)
|
predicate = util.getObjectForUid(p)
|
||||||
exists = obj.getConceptRelations(predicates=[p], concept=concept)
|
exists = self.getConceptRelations(obj, [p], concept)
|
||||||
if not exists:
|
if not exists:
|
||||||
obj.assignConcept(concept, predicate)
|
self.assignConcept(obj, concept, predicate)
|
||||||
|
|
||||||
|
def getConceptRelations(self, obj, predicates, concept):
|
||||||
|
return obj.getConceptRelations(predicates=predicates, concept=concept)
|
||||||
|
|
||||||
|
def assignConcept(self, obj, concept, predicate):
|
||||||
|
obj.assignConcept(concept, predicate)
|
||||||
|
|
||||||
|
def deassignConcept(self, obj, concept, predicates):
|
||||||
|
obj.deassignConcept(concept, predicates)
|
||||||
|
|
||||||
def checkCreateVersion(self, obj):
|
def checkCreateVersion(self, obj):
|
||||||
form = self.request.form
|
form = self.request.form
|
||||||
|
@ -379,14 +431,15 @@ class EditObject(FormController):
|
||||||
|
|
||||||
class CreateObject(EditObject):
|
class CreateObject(EditObject):
|
||||||
|
|
||||||
def update(self):
|
factory = Resource
|
||||||
form = self.request.form
|
defaultTypeToken = '.loops/concepts/textdocument'
|
||||||
container = self.loopsRoot.getResourceManager()
|
|
||||||
title = form.get('title')
|
@Lazy
|
||||||
if not title:
|
def container(self):
|
||||||
raise BadRequest('Title field is empty')
|
return self.loopsRoot.getResourceManager()
|
||||||
obj = Resource(title)
|
|
||||||
data = form.get('data')
|
def getNameFromData(self):
|
||||||
|
data = self.request.form.get('data')
|
||||||
if data and isinstance(data, FileUpload):
|
if data and isinstance(data, FileUpload):
|
||||||
name = getattr(data, 'filename', None)
|
name = getattr(data, 'filename', None)
|
||||||
# strip path from IE uploads:
|
# strip path from IE uploads:
|
||||||
|
@ -394,11 +447,21 @@ class CreateObject(EditObject):
|
||||||
name = name.rsplit('\\', 1)[-1]
|
name = name.rsplit('\\', 1)[-1]
|
||||||
else:
|
else:
|
||||||
name = None
|
name = None
|
||||||
|
return name
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
form = self.request.form
|
||||||
|
container = self.container
|
||||||
|
title = form.get('title')
|
||||||
|
if not title:
|
||||||
|
raise BadRequest('Title field is empty')
|
||||||
|
obj = self.factory(title)
|
||||||
|
name = self.getNameFromData()
|
||||||
# TODO: validate fields
|
# TODO: validate fields
|
||||||
name = INameChooser(container).chooseName(name, obj)
|
name = INameChooser(container).chooseName(name, obj)
|
||||||
container[name] = obj
|
container[name] = obj
|
||||||
tc = form.get('form.type') or '.loops/concepts/note'
|
tc = form.get('form.type') or self.defaultTypeToken
|
||||||
obj.resourceType = self.loopsRoot.loopsTraverse(tc)
|
obj.setType(self.loopsRoot.loopsTraverse(tc))
|
||||||
notify(ObjectCreatedEvent(obj))
|
notify(ObjectCreatedEvent(obj))
|
||||||
self.object = obj
|
self.object = obj
|
||||||
self.updateFields() # TODO: suppress validation
|
self.updateFields() # TODO: suppress validation
|
||||||
|
@ -406,3 +469,38 @@ class CreateObject(EditObject):
|
||||||
self.request.response.redirect(self.view.request.URL)
|
self.request.response.redirect(self.view.request.URL)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class EditConcept(EditObject):
|
||||||
|
|
||||||
|
def getConceptRelations(self, obj, predicates, concept):
|
||||||
|
return obj.getParentRelations(predicates=predicates, parent=concept)
|
||||||
|
|
||||||
|
def assignConcept(self, obj, concept, predicate):
|
||||||
|
obj.assignParent(concept, predicate)
|
||||||
|
|
||||||
|
def deassignConcept(self, obj, concept, predicates):
|
||||||
|
obj.deassignParent(concept, predicates)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
self.object = self.view.virtualTargetObject
|
||||||
|
formState = self.updateFields()
|
||||||
|
# TODO: error handling
|
||||||
|
self.request.response.redirect(self.view.virtualTargetUrl)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class CreateConcept(EditConcept, CreateObject):
|
||||||
|
|
||||||
|
factory = Concept
|
||||||
|
defaultTypeToken = '.loops/concepts/topic'
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def container(self):
|
||||||
|
return self.loopsRoot.getConceptManager()
|
||||||
|
|
||||||
|
def getNameFromData(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
return CreateObject.update(self)
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,9 @@
|
||||||
|
|
||||||
|
|
||||||
<metal:block define-macro="create" i18n:domain="loops">
|
<metal:block define-macro="create" i18n:domain="loops">
|
||||||
<form method="post" enctype="multipart/form-data">
|
<form method="post" enctype="multipart/form-data"
|
||||||
|
tal:define="qualifier request/qualifier | string:resource;
|
||||||
|
innerForm request/inner_form | string:inner_form.html">
|
||||||
<input type="hidden" name="form.action" value="create"
|
<input type="hidden" name="form.action" value="create"
|
||||||
tal:attributes="value view/form_action" />
|
tal:attributes="value view/form_action" />
|
||||||
<table cellpadding="3" class="form">
|
<table cellpadding="3" class="form">
|
||||||
|
@ -47,10 +49,12 @@
|
||||||
tal:attributes="onChange
|
tal:attributes="onChange
|
||||||
string:return replaceFieldsNode(
|
string:return replaceFieldsNode(
|
||||||
'form.fields', 'form.type',
|
'form.fields', 'form.type',
|
||||||
'${view/url}/inner_form.html')">
|
'${view/url}/$innerForm')">
|
||||||
<option value=".loops/concepts/note"
|
<option value=".loops/concepts/note"
|
||||||
i18n:translate=""
|
i18n:translate=""
|
||||||
tal:repeat="type view/resourceTypes"
|
xtal:repeat="type view/resourceTypes"
|
||||||
|
tal:repeat="type python:
|
||||||
|
view.getTypesVocabulary((qualifier,))"
|
||||||
tal:content="type/title"
|
tal:content="type/title"
|
||||||
tal:attributes="value type/token;
|
tal:attributes="value type/token;
|
||||||
selected python:
|
selected python:
|
||||||
|
|
|
@ -23,7 +23,6 @@ $Id$
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope import component, schema
|
from zope import component, schema
|
||||||
#from zope.app import zapi
|
|
||||||
from zope.app.container.btree import BTreeContainer
|
from zope.app.container.btree import BTreeContainer
|
||||||
from zope.app.container.contained import Contained
|
from zope.app.container.contained import Contained
|
||||||
from zope.cachedescriptors.property import Lazy
|
from zope.cachedescriptors.property import Lazy
|
||||||
|
@ -130,6 +129,9 @@ class Concept(Contained, Persistent):
|
||||||
def getType(self):
|
def getType(self):
|
||||||
return self.conceptType
|
return self.conceptType
|
||||||
|
|
||||||
|
def setType(self, value):
|
||||||
|
self.conceptType = value
|
||||||
|
|
||||||
def getLoopsRoot(self):
|
def getLoopsRoot(self):
|
||||||
return getParent(self).getLoopsRoot()
|
return getParent(self).getLoopsRoot()
|
||||||
|
|
||||||
|
@ -252,7 +254,6 @@ class ConceptManager(BTreeContainer):
|
||||||
|
|
||||||
def getTypeConcept(self):
|
def getTypeConcept(self):
|
||||||
if self.typeConcept is None:
|
if self.typeConcept is None:
|
||||||
#self.typeConcept = self['type']
|
|
||||||
self.typeConcept = self.get('type')
|
self.typeConcept = self.get('type')
|
||||||
return self.typeConcept
|
return self.typeConcept
|
||||||
|
|
||||||
|
@ -311,7 +312,6 @@ class PredicateSourceList(object):
|
||||||
typePred = cm.getTypePredicate()
|
typePred = cm.getTypePredicate()
|
||||||
if defPred is not None and typePred is not None:
|
if defPred is not None and typePred is not None:
|
||||||
result.append(defPred)
|
result.append(defPred)
|
||||||
#result.append(typePred)
|
|
||||||
predType = defPred.conceptType
|
predType = defPred.conceptType
|
||||||
if predType is not None and predType != cm.getTypeConcept():
|
if predType is not None and predType != cm.getTypeConcept():
|
||||||
result.extend(p for p in predType.getChildren([typePred])
|
result.extend(p for p in predType.getChildren([typePred])
|
||||||
|
|
|
@ -69,11 +69,8 @@ class IPotentialTarget(Interface):
|
||||||
|
|
||||||
# concept interfaces
|
# concept interfaces
|
||||||
|
|
||||||
class IConcept(ILoopsObject, IPotentialTarget):
|
class IConceptSchema(Interface):
|
||||||
""" The concept is the central element of the loops framework.
|
""" The primary fields of a concept object.
|
||||||
|
|
||||||
A concept is related to other concepts, may have resources
|
|
||||||
associated with it and may be referenced by views.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
title = schema.TextLine(
|
title = schema.TextLine(
|
||||||
|
@ -90,6 +87,14 @@ class IConcept(ILoopsObject, IPotentialTarget):
|
||||||
missing_value=u'',
|
missing_value=u'',
|
||||||
required=False)
|
required=False)
|
||||||
|
|
||||||
|
|
||||||
|
class IConcept(IConceptSchema, ILoopsObject, IPotentialTarget):
|
||||||
|
""" The concept is the central element of the loops framework.
|
||||||
|
|
||||||
|
A concept is related to other concepts, may have resources
|
||||||
|
associated with it and may be referenced by views.
|
||||||
|
"""
|
||||||
|
|
||||||
conceptType = schema.Choice(
|
conceptType = schema.Choice(
|
||||||
title=_(u'Concept Type'),
|
title=_(u'Concept Type'),
|
||||||
description=_(u"The type of the concept, specified by a relation to "
|
description=_(u"The type of the concept, specified by a relation to "
|
||||||
|
@ -575,7 +580,8 @@ class IIndexAttributes(Interface):
|
||||||
|
|
||||||
# types stuff
|
# types stuff
|
||||||
|
|
||||||
class ITypeConcept(Interface):
|
#class ITypeConcept(Interface):
|
||||||
|
class ITypeConcept(IConceptSchema):
|
||||||
""" Concepts of type 'type' should be adaptable to this interface.
|
""" Concepts of type 'type' should be adaptable to this interface.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,12 @@
|
||||||
</zope:class>
|
</zope:class>
|
||||||
|
|
||||||
<zope:adapter factory="loops.knowledge.knowledge.Topic"
|
<zope:adapter factory="loops.knowledge.knowledge.Topic"
|
||||||
provides="cybertools.knowledge.interfaces.IKnowledgeElement"
|
provides="loops.knowledge.interfaces.ITopic"
|
||||||
trusted="True" />
|
trusted="True" />
|
||||||
|
|
||||||
<zope:class class="loops.knowledge.knowledge.Topic">
|
<zope:class class="loops.knowledge.knowledge.Topic">
|
||||||
<require permission="zope.View"
|
<require permission="zope.View"
|
||||||
interface="cybertools.knowledge.interfaces.IKnowledgeElement" />
|
interface="loops.knowledge.interfaces.ITopic" />
|
||||||
</zope:class>
|
</zope:class>
|
||||||
|
|
||||||
<zope:adapter factory="loops.knowledge.knowledge.Task"
|
<zope:adapter factory="loops.knowledge.knowledge.Task"
|
||||||
|
|
|
@ -46,10 +46,14 @@ class GlossaryView(ConceptView):
|
||||||
if category == 'portlet':
|
if category == 'portlet':
|
||||||
actions.append(Action(self, title='Create Glossary Item...',
|
actions.append(Action(self, title='Create Glossary Item...',
|
||||||
description='Create a new glossary item.',
|
description='Create a new glossary item.',
|
||||||
url='create_glossaryitem.html',
|
url='create_concept.html',
|
||||||
onClick="objectDialog('create', '%s/create_object.html'); "
|
onClick="objectDialog('createGlossaryItem', "
|
||||||
"return false;" % self.virtualTargetUrl,
|
" '%s/create_concept.html?qualifier=concept"
|
||||||
innerHtmlId='dialog.create'))
|
"&form.type=.loops/concepts/topic"
|
||||||
|
"&inner_form=inner_concept_form.html"
|
||||||
|
"&dialog=createGlossaryItem'); "
|
||||||
|
"return false;" % page.virtualTargetUrl,
|
||||||
|
innerHtmlId='dialog.createGlossaryItem'))
|
||||||
return actions
|
return actions
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,11 +66,13 @@ class GlossaryItemView(ConceptView):
|
||||||
def getActions(self, category='object', page=None):
|
def getActions(self, category='object', page=None):
|
||||||
actions = []
|
actions = []
|
||||||
if category == 'portlet':
|
if category == 'portlet':
|
||||||
actions.append(Action(self, title='Create Glossary Item...',
|
|
||||||
description='Create a new glossary item.',
|
|
||||||
url='create_glossaryitem.html'))
|
|
||||||
actions.append(Action(self, title='Edit Glossary Item...',
|
actions.append(Action(self, title='Edit Glossary Item...',
|
||||||
description='Modify glossary item.',
|
description='Modify glossary item.',
|
||||||
url='edit_glossaryitem.html'))
|
url='edit_concept.html',
|
||||||
|
onClick="objectDialog('editGlossaryItem', "
|
||||||
|
" '%s/edit_concept.html"
|
||||||
|
"?dialog=editGlossaryItem'); "
|
||||||
|
"return false;" % page.virtualTargetUrl,
|
||||||
|
innerHtmlId='dialog.editGlossaryItem'))
|
||||||
return actions
|
return actions
|
||||||
|
|
||||||
|
|
|
@ -26,4 +26,5 @@
|
||||||
</a><tal:comma condition="not:repeat/related/end">,</tal:comma>
|
</a><tal:comma condition="not:repeat/related/end">,</tal:comma>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
<metal:resources use-macro="item/conceptMacros/conceptresources" />
|
||||||
</metal:block>
|
</metal:block>
|
||||||
|
|
|
@ -29,8 +29,10 @@ from zope.i18nmessageid import MessageFactory
|
||||||
from zope.security.proxy import removeSecurityProxy
|
from zope.security.proxy import removeSecurityProxy
|
||||||
|
|
||||||
from cybertools.knowledge.interfaces import IKnowing, IRequirementProfile
|
from cybertools.knowledge.interfaces import IKnowing, IRequirementProfile
|
||||||
from loops.organize.interfaces import IPerson as IBasePerson
|
from cybertools.knowledge.interfaces import IKnowledgeElement
|
||||||
from cybertools.organize.interfaces import ITask as IBaseTask
|
from cybertools.organize.interfaces import ITask as IBaseTask
|
||||||
|
from loops.interfaces import IConceptSchema
|
||||||
|
from loops.organize.interfaces import IPerson as IBasePerson
|
||||||
|
|
||||||
_ = MessageFactory('zope')
|
_ = MessageFactory('zope')
|
||||||
|
|
||||||
|
@ -45,3 +47,9 @@ class IPerson(IBasePerson, IKnowing):
|
||||||
class ITask(IBaseTask, IRequirementProfile):
|
class ITask(IBaseTask, IRequirementProfile):
|
||||||
""" A task, also acting as a knowledge requirement profile.
|
""" A task, also acting as a knowledge requirement profile.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ITopic(IConceptSchema, IKnowledgeElement):
|
||||||
|
""" Just a topic, some general classification concept.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ from cybertools.typology.interfaces import IType
|
||||||
from cybertools.knowledge.interfaces import IKnowledgeElement, IKnowledgeProvider
|
from cybertools.knowledge.interfaces import IKnowledgeElement, IKnowledgeProvider
|
||||||
from cybertools.knowledge.knowing import Knowing
|
from cybertools.knowledge.knowing import Knowing
|
||||||
from loops.interfaces import IConcept, IResource
|
from loops.interfaces import IConcept, IResource
|
||||||
from loops.knowledge.interfaces import IPerson, ITask
|
from loops.knowledge.interfaces import IPerson, ITask, ITopic
|
||||||
from loops.organize.party import Person as BasePerson
|
from loops.organize.party import Person as BasePerson
|
||||||
from loops.organize.task import Task as BaseTask
|
from loops.organize.task import Task as BaseTask
|
||||||
from loops.common import AdapterBase
|
from loops.common import AdapterBase
|
||||||
|
@ -42,7 +42,7 @@ from loops.type import TypeInterfaceSourceList
|
||||||
|
|
||||||
# register type interfaces - (TODO: use a function for this)
|
# register type interfaces - (TODO: use a function for this)
|
||||||
|
|
||||||
TypeInterfaceSourceList.typeInterfaces += (IPerson, IKnowledgeElement,
|
TypeInterfaceSourceList.typeInterfaces += (IPerson, ITopic, IKnowledgeElement,
|
||||||
ITask, IKnowledgeProvider)
|
ITask, IKnowledgeProvider)
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ class Topic(AdapterBase, KnowledgeAdapterMixin):
|
||||||
may act as a knowledge element.
|
may act as a knowledge element.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
implements(IKnowledgeElement)
|
implements(ITopic)
|
||||||
_adapterAttributes = ('context', '__parent__', 'parent')
|
_adapterAttributes = ('context', '__parent__', 'parent')
|
||||||
|
|
||||||
def getParent(self):
|
def getParent(self):
|
||||||
|
|
|
@ -140,6 +140,9 @@ class Resource(Image, Contained):
|
||||||
def getType(self):
|
def getType(self):
|
||||||
return self.resourceType
|
return self.resourceType
|
||||||
|
|
||||||
|
def setType(self, value):
|
||||||
|
self.resourceType = value
|
||||||
|
|
||||||
def _setData(self, data):
|
def _setData(self, data):
|
||||||
#if not data:
|
#if not data:
|
||||||
# return
|
# return
|
||||||
|
|
Loading…
Add table
Reference in a new issue