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 loops import util
from loops.target import getTargetTypes
class BaseView(object):

View file

@ -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

View file

@ -24,8 +24,16 @@
<metal:body fill-slot="body">
<tal:content define="item view/page;
level level|python: 1">
<metal:block use-macro="views/node_macros/content" />
level level|python: 1;
target request/annotations/loops.view/target | nothing">
<tal:content condition="not:target">
<metal:block use-macro="views/node_macros/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>

View file

@ -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)

View file

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

View file

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

View file

@ -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')),
)

59
view.py
View file

@ -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)