Some refactoring concerning node configuration and target assignment

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1052 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2006-02-04 20:38:30 +00:00
parent 15fa9c6a91
commit 4bbf9d4df9
9 changed files with 72 additions and 59 deletions

View file

@ -274,12 +274,9 @@ Node Views
Node Schema Adapters Node Schema Adapters
-------------------- --------------------
When creating or editing (more precisely: configuring) a node you may When configuring a node you may
specify what you want to do with respect to the node's target: associate specify what you want to do with respect to the node's target: associate
an existing one or create a new one (with specifying the target's type), an existing one or create a new one.
and give an URI that will be used to identify the target. (Internally
the reference to the target will be stored as a relation so that the
target may be moved or renamed without any problems.)
>>> from loops.interfaces import INodeConfigSchema >>> from loops.interfaces import INodeConfigSchema
>>> from loops.view import NodeConfigAdapter >>> from loops.view import NodeConfigAdapter
@ -293,7 +290,7 @@ target may be moved or renamed without any problems.)
u'New title for m111' u'New title for m111'
>>> m111.title >>> m111.title
u'New title for m111' u'New title for m111'
>>> nodeConfig.targetUri = '.loops/resources/doc1' >>> nodeConfig.target = doc1
>>> m111.target is doc1 >>> m111.target is doc1
True True
>>> nodeConfig.targetType >>> nodeConfig.targetType
@ -305,6 +302,8 @@ There is a special edit view class that can be used to configure a node
in a way, that allows the creation of a target object on the fly. in a way, that allows the creation of a target object on the fly.
(We here use the base class providing the method for this action; the real (We here use the base class providing the method for this action; the real
application uses a subclass that does all the other stuff for form handling.) application uses a subclass that does all the other stuff for form handling.)
When creating a new target object you may specify a uri that determines
the location of the new target object and its name.
>>> from loops.browser.node import ConfigureBaseView >>> from loops.browser.node import ConfigureBaseView
>>> view = ConfigureBaseView(INodeConfigSchema(m111), TestRequest()) >>> view = ConfigureBaseView(INodeConfigSchema(m111), TestRequest())

View file

@ -309,7 +309,7 @@
label="Edit Node" label="Edit Node"
name="edit.html" name="edit.html"
schema="loops.interfaces.INode" schema="loops.interfaces.INode"
fields="title description nodeType body target" fields="title description nodeType body"
for="loops.interfaces.INode" for="loops.interfaces.INode"
template="edit.pt" template="edit.pt"
permission="zope.ManageContent" permission="zope.ManageContent"
@ -330,7 +330,7 @@
label="Configure Node" label="Configure Node"
name="configure.html" name="configure.html"
schema="loops.interfaces.INodeConfigSchema" schema="loops.interfaces.INodeConfigSchema"
fields="title description nodeType targetUri targetType createTarget" fields="title description nodeType target createTarget targetUri targetType"
for="loops.interfaces.INode" for="loops.interfaces.INode"
template="edit.pt" template="edit.pt"
class="loops.browser.node.ConfigureView" class="loops.browser.node.ConfigureView"
@ -409,4 +409,17 @@
name="node.html" name="node.html"
/> />
<!-- vocabulary, traversing, and other stuff -->
<zope:adapter factory="loops.browser.target.TargetTerms"
for="loops.target.TargetSourceList
zope.publisher.interfaces.browser.IBrowserRequest" />
<zope:view factory="loops.view.NodeTraverser"
for="loops.interfaces.INode"
type="zope.publisher.interfaces.browser.IBrowserRequest"
provides="zope.publisher.interfaces.browser.IBrowserPublisher"
allowed_interface="zope.publisher.interfaces.browser.IBrowserPublisher"
permission="zope.Public" />
</configure> </configure>

View file

@ -163,7 +163,8 @@ class ConfigureBaseView(object):
target = container[name] target = container[name]
# set possibly new targetUri in request for further processing: # set possibly new targetUri in request for further processing:
targetUri = self.loopsRoot.getLoopsUri(target) targetUri = self.loopsRoot.getLoopsUri(target)
form['field.targetUri'] = targetUri #form['field.targetUri'] = targetUri
form['field.target'] = targetUri
return target return target

View file

@ -25,24 +25,18 @@ $Id$
from zope.app import zapi from zope.app import zapi
from zope.app.form.browser.interfaces import ITerms from zope.app.form.browser.interfaces import ITerms
from zope.schema.interfaces import IIterableSource from zope.schema.vocabulary import SimpleTerm
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from zope.interface import implements from zope.interface import implements
from zope.security.proxy import removeSecurityProxy from zope.security.proxy import removeSecurityProxy
class Term(object):
def __init__(self, **kw):
self.__dict__.update(kw)
class TargetTerms(object): class TargetTerms(object):
implements(ITerms) implements(ITerms)
def __init__(self, context, request): def __init__(self, context, request):
self.context = context.context self.context = context.context # the context parameter is the source object
self.request = request self.request = request
@Lazy @Lazy
@ -51,26 +45,8 @@ class TargetTerms(object):
def getTerm(self, value): def getTerm(self, value):
token = self.loopsRoot.getLoopsUri(value) token = self.loopsRoot.getLoopsUri(value)
#token = value.getLoopsRoot().getLoopsUri(value) return SimpleTerm(value, token, value.title)
title = value.title
return Term(title=title, token=token)
def getValue(self, token): def getValue(self, token):
return self.loopsRoot.loopsTraverse(token) return self.loopsRoot.loopsTraverse(token)
class TargetSourceList(object):
implements(IIterableSource)
def __init__(self, context):
self.context = removeSecurityProxy(context)
self.resources = self.context.getLoopsRoot()['resources']
def __iter__(self):
return iter(self.resources.values())
def __len__():
return len(self.resources)

View file

@ -233,22 +233,11 @@
<adapter factory="loops.target.ConceptProxy" <adapter factory="loops.target.ConceptProxy"
permission="zope.ManageContent" /> permission="zope.ManageContent" />
<adapter factory="loops.browser.target.TargetTerms"
for="loops.browser.target.TargetSourceList
zope.publisher.interfaces.browser.IBrowserRequest" />
<vocabulary <vocabulary
factory="loops.browser.target.TargetSourceList" factory="loops.target.TargetSourceList"
name="loops.targetSource" name="loops.targetSource"
/> />
<view factory="loops.view.NodeTraverser"
for="loops.interfaces.INode"
type="zope.publisher.interfaces.browser.IBrowserRequest"
provides="zope.publisher.interfaces.browser.IBrowserPublisher"
allowed_interface="zope.publisher.interfaces.browser.IBrowserPublisher"
permission="zope.Public" />
<!-- Register various browser related components, including all views --> <!-- Register various browser related components, including all views -->
<include package=".browser" /> <include package=".browser" />

View file

@ -31,6 +31,8 @@ from zope.app.file.interfaces import IImage as IBaseAsset
from zope.app.folder.interfaces import IFolder from zope.app.folder.interfaces import IFolder
from cybertools.relation.interfaces import IRelation from cybertools.relation.interfaces import IRelation
import util
_ = MessageFactory('loops') _ = MessageFactory('loops')
@ -258,7 +260,7 @@ class IBaseNode(IOrderedContainer):
def getLoopsRoot(): def getLoopsRoot():
""" Return the loops root object. """ Return the loops root object.
""" """
class INode(IView, IBaseNode): class INode(IView, IBaseNode):
""" A node is a view that may contain other views, thus building a """ A node is a view that may contain other views, thus building a
@ -272,7 +274,12 @@ class INode(IView, IBaseNode):
nodeType = schema.Choice( nodeType = schema.Choice(
title=_(u'Node Type'), title=_(u'Node Type'),
description=_(u'Type of the node'), description=_(u'Type of the node'),
values=('text', 'page', 'menu', 'info'), source=util.KeywordVocabulary((
('text', _(u'Text')),
('page', _(u'Page')),
('menu', _(u'Menu')),
('info', _(u'Info')),
)),
default='info', default='info',
required=True) required=True)
@ -312,8 +319,7 @@ class INode(IView, IBaseNode):
""" """
def getTextItems(): def getTextItems():
""" Return the menu items belonging to this object (that should be """ Return the text items belonging to this object.
a menu).
""" """

View file

@ -27,6 +27,7 @@ from zope.app import zapi
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from zope.component import adapts from zope.component import adapts
from zope.interface import implements from zope.interface import implements
from zope import schema
from zope.security.proxy import removeSecurityProxy from zope.security.proxy import removeSecurityProxy
from loops.interfaces import IResource from loops.interfaces import IResource
@ -36,6 +37,8 @@ from loops.interfaces import IView
from loops.interfaces import IConcept, IConceptView from loops.interfaces import IConcept, IConceptView
# proxies for accessing target objects from views/nodes
class ConceptProxy(object): class ConceptProxy(object):
implements(IConcept) implements(IConcept)
@ -98,3 +101,20 @@ class MediaAssetProxy(ResourceProxy):
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 = removeSecurityProxy(context)
self.resources = self.context.getLoopsRoot()['resources']
def __iter__(self):
return iter(self.resources.values())
def __len__():
return len(self.resources)

11
util.py
View file

@ -23,7 +23,16 @@ $Id$
""" """
from zope.interface import directlyProvides, directlyProvidedBy from zope.interface import directlyProvides, directlyProvidedBy
from view import TargetRelation from zope.schema import vocabulary
#from view import TargetRelation
class KeywordVocabulary(vocabulary.SimpleVocabulary):
def __init__(self, items, *interfaces):
terms = [vocabulary.SimpleTerm(token, token, title)
for token, title in items]
super(KeywordVocabulary, self).__init__(terms, *interfaces)
def removeTargetRelation(context, event): def removeTargetRelation(context, event):

12
view.py
View file

@ -71,11 +71,10 @@ class View(object):
rels = list(registry.query(first=self, relationship=TargetRelation)) rels = list(registry.query(first=self, relationship=TargetRelation))
if len(rels) > 0: if len(rels) > 0:
oldRel = rels[0] oldRel = rels[0]
if oldRel.second is target: if oldRel.second == target:
return return
else: else:
registry.unregister(oldRel) registry.unregister(oldRel)
if target: if target:
targetSchema = target.proxyInterface targetSchema = target.proxyInterface
rel = TargetRelation(self, target) rel = TargetRelation(self, target)
@ -196,15 +195,15 @@ class NodeConfigAdapter(object):
def setNodeType(self, nodeType): self.context.nodeType = nodeType def setNodeType(self, nodeType): self.context.nodeType = nodeType
nodeType = property(getNodeType, setNodeType) 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: # the real config stuff:
@Lazy @Lazy
def loopsRoot(self): return self.context.getLoopsRoot() def loopsRoot(self): return self.context.getLoopsRoot()
@readproperty
def target(self):
return self.context.target
def getTargetUri(self): def getTargetUri(self):
target = self.target target = self.target
if target is not None: if target is not None:
@ -213,6 +212,7 @@ class NodeConfigAdapter(object):
return '' return ''
def setTargetUri(self, uri): def setTargetUri(self, uri):
return # ignore - only relevant for target creation
if uri: if uri:
names = uri.split('/') names = uri.split('/')
if names[0] == '.loops': if names[0] == '.loops':