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
This commit is contained in:
helmutm 2006-03-14 09:33:44 +00:00
parent 072318ea06
commit f15f2e94e3
8 changed files with 59 additions and 171 deletions

View file

@ -31,7 +31,6 @@ from zope.security.proxy import removeSecurityProxy
from cybertools.typology.interfaces import IType from cybertools.typology.interfaces import IType
from loops import util from loops import util
from loops.target import getTargetTypes
class BaseView(object): class BaseView(object):

View file

@ -41,7 +41,6 @@ from zope.security.proxy import removeSecurityProxy
from cybertools.typology.interfaces import ITypeManager from cybertools.typology.interfaces import ITypeManager
from loops.interfaces import IConcept from loops.interfaces import IConcept
from loops.concept import Concept, ConceptTypeSourceList, PredicateSourceList from loops.concept import Concept, ConceptTypeSourceList, PredicateSourceList
from loops.target import getTargetTypes
from loops.browser.common import BaseView, LoopsTerms from loops.browser.common import BaseView, LoopsTerms
from loops import util from loops import util

View file

@ -24,9 +24,17 @@
<metal:body fill-slot="body"> <metal:body fill-slot="body">
<tal:content define="item view/page; <tal:content define="item view/page;
level level|python: 1"> level level|python: 1;
target request/annotations/loops.view/target | nothing">
<tal:content condition="not:target">
<metal:block use-macro="views/node_macros/content" /> <metal:block use-macro="views/node_macros/content" />
</tal:content> </tal:content>
<tal:target condition="target">
<div>
Here comes the real target... <span tal:replace="target/title" />
</div>
</tal:target>
</tal:content>
</metal:body> </metal:body>

View file

@ -26,9 +26,7 @@ from zope.cachedescriptors.property import Lazy
from zope.app import zapi from zope.app import zapi
from zope.app.catalog.interfaces import ICatalog from zope.app.catalog.interfaces import ICatalog
from zope.app.container.browser.contents import JustContents from zope.app.container.browser.contents import JustContents
from zope.app.dublincore.interfaces import ICMFDublinCore
from zope.app.event.objectevent import ObjectCreatedEvent from zope.app.event.objectevent import ObjectCreatedEvent
#import zope.configuration.name
from zope.dottedname.resolve import resolve from zope.dottedname.resolve import resolve
from zope.event import notify from zope.event import notify
from zope.proxy import removeAllProxies from zope.proxy import removeAllProxies
@ -36,32 +34,19 @@ from zope.security import canAccess, canWrite
from zope.security.proxy import removeSecurityProxy from zope.security.proxy import removeSecurityProxy
from cybertools.typology.interfaces import ITypeManager 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.resource import MediaAsset
from loops.target import getTargetTypes, getTargetTypesForSearch
from loops import util from loops import util
from loops.browser.common import BaseView from loops.browser.common import BaseView
from loops.browser.concept import ConceptView from loops.browser.concept import ConceptView
class NodeView(object): class NodeView(BaseView):
def __init__(self, context, request):
self.context = context
self.request = request
@Lazy
def title(self):
return self.context.title
@Lazy @Lazy
def nodeType(self): def nodeType(self):
return self.context.nodeType return self.context.nodeType
@Lazy
def url(self):
return zapi.absoluteURL(self.context, self.request)
def render(self, text=None): def render(self, text=None):
if text is None: if text is None:
text = self.context.body text = self.context.body
@ -74,19 +59,19 @@ class NodeView(object):
return view.render() return view.render()
@Lazy @Lazy
def modified(self): def targetObject(self):
""" get date/time of last modification return self.context.target
"""
dc = ICMFDublinCore(self.context)
d = dc.modified or dc.created
return d and d.strftime('%Y-%m-%d %H:%M') or ''
@Lazy @Lazy
def target(self): 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): def renderTarget(self):
target = self.target target = self.targetObject
if target is not None: if target is not None:
targetView = zapi.getMultiAdapter((target, self.request), targetView = zapi.getMultiAdapter((target, self.request),
name=zapi.getDefaultViewName(target, self.request)) name=zapi.getDefaultViewName(target, self.request))
@ -94,7 +79,7 @@ class NodeView(object):
return u'' return u''
def renderTargetBody(self): def renderTargetBody(self):
target = self.target target = self.targetObject
if target is not None: if target is not None:
targetView = zapi.getMultiAdapter((target, self.request)) targetView = zapi.getMultiAdapter((target, self.request))
return targetView.render() return targetView.render()
@ -115,7 +100,7 @@ class NodeView(object):
@Lazy @Lazy
def bodyMacro(self): def bodyMacro(self):
target = self.target target = self.targetObject
if target is None or IDocument.providedBy(target): if target is None or IDocument.providedBy(target):
return 'textbody' return 'textbody'
if IConcept.providedBy(target): # TODO... if IConcept.providedBy(target): # TODO...
@ -140,8 +125,17 @@ class NodeView(object):
def selected(self, item): def selected(self, item):
return item.context == self.context 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 """ An editing view for configuring a node, optionally creating
a target object. a target object.
""" """
@ -151,19 +145,6 @@ class ConfigureView(BaseView):
self.context = removeSecurityProxy(context) self.context = removeSecurityProxy(context)
self.request = request 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): def update(self):
request = self.request request = self.request
action = request.get('action') action = request.get('action')
@ -249,8 +230,4 @@ class ConfigureView(BaseView):
if o == self.context.target: if o == self.context.target:
continue continue
yield BaseView(o, request) yield BaseView(o, request)
#if IConcept.providedBy(o):
# yield ConceptView(o, request)
#else:
# yield BaseView(o, request)

View file

@ -35,15 +35,19 @@
<metal:body define-macro="conceptbody"> <metal:body define-macro="conceptbody">
<tal:body define="body item/body"> <tal:body define="body item/body;
target item/target;">
<div class="content-1" <div class="content-1"
tal:define="onclick string:openEditWindow('${item/url}/@@configure.html')" tal:define="onclick string:openEditWindow('${item/url}/@@configure.html')"
tal:attributes="class string:content-$level; tal:attributes="class string:content-$level;
ondblclick python: item.editable and onclick or ''"> ondblclick python: item.editable and onclick or ''">
<span tal:content="structure body">Node Body</span>
</div>
<div tal:repeat="resource target/resources">
<a href="#" <a href="#"
tal:omit-tag="" tal:attributes="href
tal:attributes="href item/target/@@absolute_url" string:${item/url}/.target${repeat/resource/number}/@@node.html"
tal:content="structure body">The body</a> tal:content="resource/title">Resource Title</a>
</div> </div>
</tal:body> </tal:body>
</metal:body> </metal:body>
@ -56,7 +60,7 @@
tal:attributes="class string:content-$level; tal:attributes="class string:content-$level;
ondblclick python: item.editable and onclick or ''"> ondblclick python: item.editable and onclick or ''">
<a href="#" <a href="#"
tal:attributes="href string:${item/url}/target" tal:attributes="href string:${item/url}/@@target"
tal:content="structure body">The body</a> tal:content="structure body">The body</a>
</div> </div>
</tal:body> </tal:body>
@ -70,7 +74,7 @@
tal:attributes="class string:content-$level; tal:attributes="class string:content-$level;
ondblclick python: item.editable and onclick or ''"> ondblclick python: item.editable and onclick or ''">
<img src="target" <img src="target"
tal:attributes="src string:${item/url}/target" /> tal:attributes="src string:${item/url}/@@target" />
</div> </div>
<div class="content-1" <div class="content-1"
tal:condition="body" tal:condition="body"

View file

@ -244,9 +244,6 @@
<adapter factory="loops.external.NodesExporter" /> <adapter factory="loops.external.NodesExporter" />
<adapter factory="loops.external.NodesImporter" /> <adapter factory="loops.external.NodesImporter" />
<adapter factory=".view.NodeConfigAdapter"
permission="zope.ManageContent" />
<adapter factory="loops.target.DocumentProxy" <adapter factory="loops.target.DocumentProxy"
permission="zope.ManageContent" /> permission="zope.ManageContent" />
<adapter factory="loops.target.MediaAssetProxy" <adapter factory="loops.target.MediaAssetProxy"
@ -264,11 +261,6 @@
name="loops.PredicateSource" name="loops.PredicateSource"
/> />
<!--<vocabulary
factory="loops.target.TargetSourceList"
name="loops.targetSource"
/>-->
<!-- Register various browser related components, including all views --> <!-- Register various browser related components, including all views -->
<include package=".browser" /> <include package=".browser" />

View file

@ -55,11 +55,14 @@ class ConceptProxy(object):
def setTitle(self, title): self.target.title = title def setTitle(self, title): self.target.title = title
title = property(getTitle, setTitle) title = property(getTitle, setTitle)
def getChildren(self, relationships=None): def getChildren(self, predicates=None):
return self.target.getChildren(relationships) return self.target.getChildren(predicates)
def getParents(self, relationships=None): def getParents(self, predicates=None):
return self.target.getParents(relationships) return self.target.getParents(predicates)
def getResources(self, predicates=None):
return self.target.getResources(predicates)
class ResourceProxy(object): class ResourceProxy(object):
@ -103,58 +106,3 @@ class MediaAssetProxy(ResourceProxy):
def getData(self): return self.target.data def getData(self): return self.target.data
data = property(getData, setData) 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')),
)

59
view.py
View file

@ -42,6 +42,7 @@ from interfaces import IView, INode, INodeConfigSchema
from interfaces import IViewManager, INodeContained from interfaces import IViewManager, INodeContained
from interfaces import ILoopsContained from interfaces import ILoopsContained
from interfaces import ITargetRelation from interfaces import ITargetRelation
from interfaces import IConcept
class View(object): class View(object):
@ -167,54 +168,14 @@ class NodeTraverser(ItemTraverser):
def publishTraverse(self, request, name): def publishTraverse(self, request, name):
if name == '.loops': if name == '.loops':
return self.context.getLoopsRoot() 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) 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)