From f15f2e94e3b90172b363558101e8ba69ec33c31e Mon Sep 17 00:00:00 2001 From: helmutm Date: Tue, 14 Mar 2006 09:33:44 +0000 Subject: [PATCH] work in progress: provide target listings and views on nodes, possibly via concepts git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1125 fd906abe-77d9-0310-91a1-e0d9ade77398 --- browser/common.py | 1 - browser/concept.py | 1 - browser/node.pt | 12 ++++++-- browser/node.py | 67 ++++++++++++++---------------------------- browser/node_macros.pt | 16 ++++++---- configure.zcml | 8 ----- target.py | 66 +++++------------------------------------ view.py | 59 +++++++------------------------------ 8 files changed, 59 insertions(+), 171 deletions(-) diff --git a/browser/common.py b/browser/common.py index b91f6ea..9572993 100644 --- a/browser/common.py +++ b/browser/common.py @@ -31,7 +31,6 @@ from zope.security.proxy import removeSecurityProxy from cybertools.typology.interfaces import IType from loops import util -from loops.target import getTargetTypes class BaseView(object): diff --git a/browser/concept.py b/browser/concept.py index c05e64d..6bdbeb5 100644 --- a/browser/concept.py +++ b/browser/concept.py @@ -41,7 +41,6 @@ from zope.security.proxy import removeSecurityProxy from cybertools.typology.interfaces import ITypeManager from loops.interfaces import IConcept from loops.concept import Concept, ConceptTypeSourceList, PredicateSourceList -from loops.target import getTargetTypes from loops.browser.common import BaseView, LoopsTerms from loops import util diff --git a/browser/node.pt b/browser/node.pt index 2589a6f..3f5e71d 100644 --- a/browser/node.pt +++ b/browser/node.pt @@ -24,8 +24,16 @@ - + level level|python: 1; + target request/annotations/loops.view/target | nothing"> + + + + +
+ Here comes the real target... +
+
diff --git a/browser/node.py b/browser/node.py index 2147491..a895efe 100644 --- a/browser/node.py +++ b/browser/node.py @@ -26,9 +26,7 @@ from zope.cachedescriptors.property import Lazy from zope.app import zapi from zope.app.catalog.interfaces import ICatalog from zope.app.container.browser.contents import JustContents -from zope.app.dublincore.interfaces import ICMFDublinCore from zope.app.event.objectevent import ObjectCreatedEvent -#import zope.configuration.name from zope.dottedname.resolve import resolve from zope.event import notify from zope.proxy import removeAllProxies @@ -36,32 +34,19 @@ from zope.security import canAccess, canWrite from zope.security.proxy import removeSecurityProxy from cybertools.typology.interfaces import ITypeManager -from loops.interfaces import IConcept, IDocument, IMediaAsset +from loops.interfaces import IConcept, IResource, IDocument, IMediaAsset from loops.resource import MediaAsset -from loops.target import getTargetTypes, getTargetTypesForSearch from loops import util from loops.browser.common import BaseView from loops.browser.concept import ConceptView -class NodeView(object): - - def __init__(self, context, request): - self.context = context - self.request = request - - @Lazy - def title(self): - return self.context.title +class NodeView(BaseView): @Lazy def nodeType(self): return self.context.nodeType - @Lazy - def url(self): - return zapi.absoluteURL(self.context, self.request) - def render(self, text=None): if text is None: text = self.context.body @@ -74,19 +59,19 @@ class NodeView(object): return view.render() @Lazy - def modified(self): - """ get date/time of last modification - """ - dc = ICMFDublinCore(self.context) - d = dc.modified or dc.created - return d and d.strftime('%Y-%m-%d %H:%M') or '' + def targetObject(self): + return self.context.target @Lazy def target(self): - return self.context.target + obj = self.targetObject + if obj is not None: + if IConcept.providedBy(obj): + return ConceptView(obj, self.request) + return BaseView(obj, self.request) def renderTarget(self): - target = self.target + target = self.targetObject if target is not None: targetView = zapi.getMultiAdapter((target, self.request), name=zapi.getDefaultViewName(target, self.request)) @@ -94,7 +79,7 @@ class NodeView(object): return u'' def renderTargetBody(self): - target = self.target + target = self.targetObject if target is not None: targetView = zapi.getMultiAdapter((target, self.request)) return targetView.render() @@ -115,7 +100,7 @@ class NodeView(object): @Lazy def bodyMacro(self): - target = self.target + target = self.targetObject if target is None or IDocument.providedBy(target): return 'textbody' if IConcept.providedBy(target): # TODO... @@ -140,8 +125,17 @@ class NodeView(object): def selected(self, item): return item.context == self.context + # view @@target - probably obsolete, replace by view.NodeTraverser + def renderTarget(self): + target = self.target + if target is not None: + targetView = zapi.getMultiAdapter((target, self.request), + name=zapi.getDefaultViewName(target, self.request)) + return targetView() + return u'' -class ConfigureView(BaseView): + +class ConfigureView(NodeView): """ An editing view for configuring a node, optionally creating a target object. """ @@ -151,19 +145,6 @@ class ConfigureView(BaseView): self.context = removeSecurityProxy(context) self.request = request - @Lazy - def loopsRoot(self): - return self.context.getLoopsRoot() - - @property - def target(self): - target = self.context.target - if target is not None: - if IConcept.providedBy(target): - return ConceptView(target, self.request) - return BaseView(target, self.request) - return None - def update(self): request = self.request action = request.get('action') @@ -249,8 +230,4 @@ class ConfigureView(BaseView): if o == self.context.target: continue yield BaseView(o, request) - #if IConcept.providedBy(o): - # yield ConceptView(o, request) - #else: - # yield BaseView(o, request) diff --git a/browser/node_macros.pt b/browser/node_macros.pt index c963483..1f73843 100644 --- a/browser/node_macros.pt +++ b/browser/node_macros.pt @@ -35,15 +35,19 @@ - +
+ Node Body +
+
The body + tal:attributes="href + string:${item/url}/.target${repeat/resource/number}/@@node.html" + tal:content="resource/title">Resource Title
@@ -56,7 +60,7 @@ tal:attributes="class string:content-$level; ondblclick python: item.editable and onclick or ''"> The body @@ -70,7 +74,7 @@ tal:attributes="class string:content-$level; ondblclick python: item.editable and onclick or ''"> + tal:attributes="src string:${item/url}/@@target" />
- - - - diff --git a/target.py b/target.py index 0663daa..d2b4fb0 100644 --- a/target.py +++ b/target.py @@ -55,11 +55,14 @@ class ConceptProxy(object): def setTitle(self, title): self.target.title = title title = property(getTitle, setTitle) - def getChildren(self, relationships=None): - return self.target.getChildren(relationships) + def getChildren(self, predicates=None): + return self.target.getChildren(predicates) - def getParents(self, relationships=None): - return self.target.getParents(relationships) + def getParents(self, predicates=None): + return self.target.getParents(predicates) + + def getResources(self, predicates=None): + return self.target.getResources(predicates) class ResourceProxy(object): @@ -103,58 +106,3 @@ class MediaAssetProxy(ResourceProxy): def getData(self): return self.target.data data = property(getData, setData) - -# source classes for target vocabularies - -class TargetSourceList(object): - - implements(schema.interfaces.IIterableSource) - - def __init__(self, context): - #self.context = context - self.context = removeSecurityProxy(context) - root = self.context.getLoopsRoot() - self.resources = root.getResourceManager() - # concepts will only be included when we have some really - # queryable source with a corresponding user interface: - #self.concepts = root.getConceptManager() - self.concepts = {} - - def __iter__(self): - for obj in self.resources.values(): - yield obj - for obj in self.concepts.values(): - yield obj - #return iter(list(self.resources.values()) + list(self.concepts.values())) - - def __len__(self): - return len(self.resources) + len(self.concepts) - - -class QueryableTargetSource(object): - - implements(schema.interfaces.ISource) - - def __init__(self, context): - self.context = context - root = self.context.getLoopsRoot() - self.resources = root.getResourceManager() - self.concepts = root.getConceptManager() - - def __contains__(self, value): - return value in self.resources.values() or value in self.concepts.values() - - -def getTargetTypes(): - return (('loops.concept.Concept', _(u'Concept')), - ('loops.resource.Document', _(u'Document')), - ('loops.resource.MediaAsset', _(u'Media Asset')), - ) - -def getTargetTypesForSearch(): - # TODO: provide full list of concept types - return (('loops:concept:*', _(u'Any Concept')), - ('loops:resource:Document', _(u'Document')), - ('loops:resource:MediaAsset', _(u'Media Asset')), - ) - diff --git a/view.py b/view.py index a414f03..bf9c0a4 100644 --- a/view.py +++ b/view.py @@ -42,6 +42,7 @@ from interfaces import IView, INode, INodeConfigSchema from interfaces import IViewManager, INodeContained from interfaces import ILoopsContained from interfaces import ITargetRelation +from interfaces import IConcept class View(object): @@ -167,54 +168,14 @@ class NodeTraverser(ItemTraverser): def publishTraverse(self, request, name): if name == '.loops': return self.context.getLoopsRoot() + if name.startswith('.target'): + target = self.context.target + if len(name) > len('.target') and IConcept.providedBy(target): + idx = int(name[len('.target'):]) - 1 + target = target.getResources()[idx] + viewAnnotations = request.annotations.get('loops.view', {}) + viewAnnotations['target'] = target + request.annotations['loops.view'] = viewAnnotations + return self.context return super(NodeTraverser, self).publishTraverse(request, name) - -class NodeConfigAdapter(object): - - def __init__(self, context): - self.context = removeSecurityProxy(context) - self._targetType = None - - implements(INodeConfigSchema) - adapts(INode) - - # provide access to fields of the Node class: - - def getTitle(self): return self.context.title - def setTitle(self, title): self.context.title = title - title = property(getTitle, setTitle) - - def getDescription(self): return self.context.description - def setDescription(self, description): self.context.description = description - description = property(getDescription, setDescription) - - def getNodeType(self): return self.context.nodeType - def setNodeType(self, nodeType): self.context.nodeType = nodeType - nodeType = property(getNodeType, setNodeType) - - def getTarget(self): return self.context.target - def setTarget(self, target): self.context.target = target - target = property(getTarget, setTarget) - - # the real config stuff: - - @Lazy - def loopsRoot(self): return self.context.getLoopsRoot() - - def getTargetUri(self):return '' - def setTargetUri(self, uri): pass - targetUri = property(getTargetUri, setTargetUri) - - def getTargetType(self): - target = self.target - if target: - return '%s.%s' % (target.__module__, target.__class__.__name__) - return None - def setTargetType(self, tt): pass - targetType = property(getTargetType, setTargetType) - - def getCreateTarget(self): return False - def setCreateTarget(self, value): pass - createTarget = property(getCreateTarget, setCreateTarget) -