Using basic vocabulary/source stuff for assigning target on the edit form
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1051 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
788e21dc8c
commit
15fa9c6a91
10 changed files with 175 additions and 39 deletions
|
@ -358,12 +358,6 @@ and of a lot of other stuff needed for the rendering machine.
|
||||||
... with=(IBrowserRequest,))
|
... with=(IBrowserRequest,))
|
||||||
|
|
||||||
>>> from zope.component.interfaces import IFactory
|
>>> from zope.component.interfaces import IFactory
|
||||||
>>> from zope.app.renderer import plaintext
|
|
||||||
>>> ztapi.provideUtility(IFactory, plaintext.PlainTextSourceFactory,
|
|
||||||
... 'zope.source.plaintext')
|
|
||||||
>>> ztapi.provideAdapter(plaintext.IPlainTextSource, Interface,
|
|
||||||
... plaintext.PlainTextToHTMLRenderer,
|
|
||||||
... with=(IBrowserRequest,))
|
|
||||||
>>> from zope.app.renderer import rest
|
>>> from zope.app.renderer import rest
|
||||||
>>> ztapi.provideUtility(IFactory, rest.ReStructuredTextSourceFactory,
|
>>> ztapi.provideUtility(IFactory, rest.ReStructuredTextSourceFactory,
|
||||||
... 'zope.source.rest')
|
... 'zope.source.rest')
|
||||||
|
@ -377,7 +371,7 @@ and of a lot of other stuff needed for the rendering machine.
|
||||||
u''
|
u''
|
||||||
>>> doc1.data = u'Test data\n\nAnother paragraph'
|
>>> doc1.data = u'Test data\n\nAnother paragraph'
|
||||||
>>> view.renderTargetBody()
|
>>> view.renderTargetBody()
|
||||||
u'Test data<br />\n<br />\nAnother paragraph'
|
u'Test data\n\nAnother paragraph'
|
||||||
>>> doc1.contentType = 'text/restructured'
|
>>> doc1.contentType = 'text/restructured'
|
||||||
>>> view.renderTargetBody()
|
>>> view.renderTargetBody()
|
||||||
u'<p>Test data</p>\n<p>Another paragraph</p>\n'
|
u'<p>Test data</p>\n<p>Another paragraph</p>\n'
|
||||||
|
|
|
@ -28,6 +28,8 @@ from zope.app.folder.folder import Folder
|
||||||
from zope.interface import implements
|
from zope.interface import implements
|
||||||
from interfaces import ILoops
|
from interfaces import ILoops
|
||||||
|
|
||||||
|
loopsPrefix = '.loops'
|
||||||
|
|
||||||
class Loops(Folder):
|
class Loops(Folder):
|
||||||
|
|
||||||
implements(ILoops)
|
implements(ILoops)
|
||||||
|
@ -39,5 +41,9 @@ class Loops(Folder):
|
||||||
return self['views']
|
return self['views']
|
||||||
|
|
||||||
def getLoopsUri(self, obj):
|
def getLoopsUri(self, obj):
|
||||||
return str('.loops' + zapi.getPath(obj)[len(zapi.getPath(self)):])
|
return str(loopsPrefix + zapi.getPath(obj)[len(zapi.getPath(self)):])
|
||||||
|
|
||||||
|
def loopsTraverse(self, uri):
|
||||||
|
prefix = loopsPrefix + '/'
|
||||||
|
if uri.startswith(prefix):
|
||||||
|
return zapi.traverse(self, uri[len(prefix):])
|
||||||
|
|
|
@ -191,6 +191,14 @@
|
||||||
permission="zope.ManageContent"
|
permission="zope.ManageContent"
|
||||||
menu="zmi_views" title="Edit" />
|
menu="zmi_views" title="Edit" />
|
||||||
|
|
||||||
|
<zope:adapter
|
||||||
|
for="loops.interfaces.IDocument
|
||||||
|
zope.publisher.interfaces.browser.IBrowserRequest"
|
||||||
|
provides="zope.interface.Interface"
|
||||||
|
factory="loops.browser.resource.DocumentView"
|
||||||
|
permission="zope.View"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- media asset -->
|
<!-- media asset -->
|
||||||
|
|
||||||
<addform
|
<addform
|
||||||
|
@ -301,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"
|
fields="title description nodeType body target"
|
||||||
for="loops.interfaces.INode"
|
for="loops.interfaces.INode"
|
||||||
template="edit.pt"
|
template="edit.pt"
|
||||||
permission="zope.ManageContent"
|
permission="zope.ManageContent"
|
||||||
|
@ -369,6 +377,17 @@
|
||||||
menu="zmi_views" title="Edit Document"
|
menu="zmi_views" title="Edit Document"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<editform
|
||||||
|
label="Edit Concept"
|
||||||
|
name="edit_target.html"
|
||||||
|
schema="loops.interfaces.IConcept"
|
||||||
|
fields="title"
|
||||||
|
for="loops.interfaces.IConceptView"
|
||||||
|
template="edit.pt"
|
||||||
|
permission="zope.ManageContent"
|
||||||
|
menu="zmi_views" title="Edit Concept"
|
||||||
|
/>
|
||||||
|
|
||||||
<page
|
<page
|
||||||
name="node.html"
|
name="node.html"
|
||||||
for="loops.interfaces.INode"
|
for="loops.interfaces.INode"
|
||||||
|
@ -390,12 +409,4 @@
|
||||||
name="node.html"
|
name="node.html"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<zope:adapter
|
|
||||||
for="loops.interfaces.IDocument
|
|
||||||
zope.publisher.interfaces.browser.IBrowserRequest"
|
|
||||||
provides="zope.interface.Interface"
|
|
||||||
factory="loops.browser.resource.DocumentView"
|
|
||||||
permission="zope.View"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</configure>
|
</configure>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<!-- content macros -->
|
<!-- content macros -->
|
||||||
|
|
||||||
<metal:block define-macro="content"
|
<metal:block define-macro="content"
|
||||||
tal:define="bodyMacro view/bodyMacro">
|
tal:define="bodyMacro item/bodyMacro">
|
||||||
<metal:body use-macro="views/node_macros/?bodyMacro" />
|
<metal:body use-macro="views/node_macros/?bodyMacro" />
|
||||||
<tal:sub define="level python:level+1">
|
<tal:sub define="level python:level+1">
|
||||||
<tal:items repeat="item item/textItems">
|
<tal:items repeat="item item/textItems">
|
||||||
|
@ -49,22 +49,22 @@
|
||||||
|
|
||||||
|
|
||||||
<metal:body define-macro="imagebody">
|
<metal:body define-macro="imagebody">
|
||||||
<tal:body define="body item/body"
|
<tal:body define="body item/body">
|
||||||
condition="body">
|
<div class="content-1" style="margin-top: 12px"
|
||||||
<div class="content-1"
|
|
||||||
tal:define="onclick string:openEditWindow('${item/url}/@@edit.html')"
|
|
||||||
tal:attributes="class string:content-$level;
|
|
||||||
ondblclick python: item.editable and onclick or ''"
|
|
||||||
tal:content="structure body">
|
|
||||||
The body
|
|
||||||
</div>
|
|
||||||
<div class="content-1"
|
|
||||||
tal:define="onclick string:openEditWindow('${item/url}/@@edit_target.html')"
|
tal:define="onclick string:openEditWindow('${item/url}/@@edit_target.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 ''">
|
||||||
<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"
|
||||||
|
tal:condition="body"
|
||||||
|
tal:define="onclick string:openEditWindow('${item/url}/@@edit.html')"
|
||||||
|
tal:attributes="class string:content-$level;
|
||||||
|
ondblclick python: item.editable and onclick or ''"
|
||||||
|
tal:content="structure body">
|
||||||
|
The body
|
||||||
|
</div>
|
||||||
</tal:body>
|
</tal:body>
|
||||||
</metal:body>
|
</metal:body>
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,9 @@ class DocumentView(object):
|
||||||
""" Return the rendered content (data) of the context object.
|
""" Return the rendered content (data) of the context object.
|
||||||
"""
|
"""
|
||||||
text = self.context.data
|
text = self.context.data
|
||||||
typeKey = renderingFactories.get(self.context.contentType,
|
typeKey = renderingFactories.get(self.context.contentType, None)
|
||||||
renderingFactories['text/plain'])
|
if typeKey is None:
|
||||||
|
return text
|
||||||
source = zapi.createObject(typeKey, text)
|
source = zapi.createObject(typeKey, text)
|
||||||
view = zapi.getMultiAdapter((removeAllProxies(source), self.request))
|
view = zapi.getMultiAdapter((removeAllProxies(source), self.request))
|
||||||
return view.render()
|
return view.render()
|
||||||
|
|
76
browser/target.py
Normal file
76
browser/target.py
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2006 Helmut Merz helmutm@cy55.de
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
Class(es) for representing a target attribute, to be used e.g. for
|
||||||
|
vocabularies and widgets.
|
||||||
|
|
||||||
|
$Id$
|
||||||
|
"""
|
||||||
|
|
||||||
|
from zope.app import zapi
|
||||||
|
from zope.app.form.browser.interfaces import ITerms
|
||||||
|
from zope.schema.interfaces import IIterableSource
|
||||||
|
from zope.cachedescriptors.property import Lazy
|
||||||
|
from zope.interface import implements
|
||||||
|
from zope.security.proxy import removeSecurityProxy
|
||||||
|
|
||||||
|
|
||||||
|
class Term(object):
|
||||||
|
|
||||||
|
def __init__(self, **kw):
|
||||||
|
self.__dict__.update(kw)
|
||||||
|
|
||||||
|
|
||||||
|
class TargetTerms(object):
|
||||||
|
|
||||||
|
implements(ITerms)
|
||||||
|
|
||||||
|
def __init__(self, context, request):
|
||||||
|
self.context = context.context
|
||||||
|
self.request = request
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def loopsRoot(self):
|
||||||
|
return self.context.getLoopsRoot()
|
||||||
|
|
||||||
|
def getTerm(self, value):
|
||||||
|
token = self.loopsRoot.getLoopsUri(value)
|
||||||
|
#token = value.getLoopsRoot().getLoopsUri(value)
|
||||||
|
title = value.title
|
||||||
|
return Term(title=title, token=token)
|
||||||
|
|
||||||
|
def getValue(self, 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)
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ from persistent import Persistent
|
||||||
from cybertools.relation import DyadicRelation
|
from cybertools.relation import DyadicRelation
|
||||||
from cybertools.relation.registry import IRelationsRegistry, getRelations
|
from cybertools.relation.registry import IRelationsRegistry, getRelations
|
||||||
|
|
||||||
from interfaces import IConcept
|
from interfaces import IConcept, IConceptView
|
||||||
from interfaces import IConceptManager, IConceptManagerContained
|
from interfaces import IConceptManager, IConceptManagerContained
|
||||||
from interfaces import ILoopsContained
|
from interfaces import ILoopsContained
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ class Concept(Contained, Persistent):
|
||||||
|
|
||||||
implements(IConcept, IConceptManagerContained)
|
implements(IConcept, IConceptManagerContained)
|
||||||
|
|
||||||
proxyInterface = IConcept
|
proxyInterface = IConceptView
|
||||||
|
|
||||||
_title = u''
|
_title = u''
|
||||||
def getTitle(self): return self._title
|
def getTitle(self): return self._title
|
||||||
|
|
|
@ -230,6 +230,17 @@
|
||||||
permission="zope.ManageContent" />
|
permission="zope.ManageContent" />
|
||||||
<adapter factory="loops.target.MediaAssetProxy"
|
<adapter factory="loops.target.MediaAssetProxy"
|
||||||
permission="zope.ManageContent" />
|
permission="zope.ManageContent" />
|
||||||
|
<adapter factory="loops.target.ConceptProxy"
|
||||||
|
permission="zope.ManageContent" />
|
||||||
|
|
||||||
|
<adapter factory="loops.browser.target.TargetTerms"
|
||||||
|
for="loops.browser.target.TargetSourceList
|
||||||
|
zope.publisher.interfaces.browser.IBrowserRequest" />
|
||||||
|
|
||||||
|
<vocabulary
|
||||||
|
factory="loops.browser.target.TargetSourceList"
|
||||||
|
name="loops.targetSource"
|
||||||
|
/>
|
||||||
|
|
||||||
<view factory="loops.view.NodeTraverser"
|
<view factory="loops.view.NodeTraverser"
|
||||||
for="loops.interfaces.INode"
|
for="loops.interfaces.INode"
|
||||||
|
|
|
@ -114,6 +114,10 @@ class IConcept(ILoopsObject, IPotentialTarget):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class IConceptView(Interface):
|
||||||
|
""" Used for accessing a concept via a node's target attribute"""
|
||||||
|
|
||||||
|
|
||||||
class IConceptManager(ILoopsObject, IContainer):
|
class IConceptManager(ILoopsObject, IContainer):
|
||||||
""" A manager/container for concepts.
|
""" A manager/container for concepts.
|
||||||
"""
|
"""
|
||||||
|
@ -174,7 +178,7 @@ class IDocumentSchema(IResourceSchema):
|
||||||
title=_(u'Content Type'),
|
title=_(u'Content Type'),
|
||||||
description=_(u'Content type (format) of the data field'),
|
description=_(u'Content type (format) of the data field'),
|
||||||
values=('text/restructured', 'text/structured', 'text/html',
|
values=('text/restructured', 'text/structured', 'text/html',
|
||||||
'text/plain',),
|
'text/plain', 'text/xml', 'text/css'),
|
||||||
default='text/restructured',
|
default='text/restructured',
|
||||||
required=True)
|
required=True)
|
||||||
|
|
||||||
|
@ -237,7 +241,14 @@ class IView(ILoopsObject):
|
||||||
default=u'',
|
default=u'',
|
||||||
required=False)
|
required=False)
|
||||||
|
|
||||||
target = Attribute('Target object that is referenced by this view')
|
#target = Attribute('Target object that is referenced by this view')
|
||||||
|
|
||||||
|
target = schema.Choice(
|
||||||
|
title=_(u'Target'),
|
||||||
|
description=_(u'The target object of this view or node'),
|
||||||
|
default=None,
|
||||||
|
source="loops.targetSource",
|
||||||
|
required=False)
|
||||||
|
|
||||||
|
|
||||||
class IBaseNode(IOrderedContainer):
|
class IBaseNode(IOrderedContainer):
|
||||||
|
@ -325,7 +336,8 @@ class ITargetProperties(Interface):
|
||||||
targetType = schema.Choice(
|
targetType = schema.Choice(
|
||||||
title=_(u'Target Type'),
|
title=_(u'Target Type'),
|
||||||
description=_(u'Type of the target'),
|
description=_(u'Type of the target'),
|
||||||
values=('loops.resource.Document', 'loops.resource.MediaAsset'),
|
values=('loops.resource.Document', 'loops.resource.MediaAsset',
|
||||||
|
'loops.concept.Concept'),
|
||||||
default=None,
|
default=None,
|
||||||
required=False)
|
required=False)
|
||||||
|
|
||||||
|
@ -361,6 +373,10 @@ class ILoops(ILoopsObject, IFolder):
|
||||||
def getLoopsUri(obj):
|
def getLoopsUri(obj):
|
||||||
""" Return the relativ path to obj, starting with '.loops/...'.
|
""" Return the relativ path to obj, starting with '.loops/...'.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def loopsTraverse(uri):
|
||||||
|
""" Retrieve object specified by the loops uri given.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class ILoopsContained(Interface):
|
class ILoopsContained(Interface):
|
||||||
|
|
29
target.py
29
target.py
|
@ -33,12 +33,37 @@ from loops.interfaces import IResource
|
||||||
from loops.interfaces import IDocument, IMediaAsset
|
from loops.interfaces import IDocument, IMediaAsset
|
||||||
from loops.interfaces import IDocumentView, IMediaAssetView
|
from loops.interfaces import IDocumentView, IMediaAssetView
|
||||||
from loops.interfaces import IView
|
from loops.interfaces import IView
|
||||||
|
from loops.interfaces import IConcept, IConceptView
|
||||||
|
|
||||||
|
|
||||||
|
class ConceptProxy(object):
|
||||||
|
|
||||||
|
implements(IConcept)
|
||||||
|
adapts(IConceptView)
|
||||||
|
|
||||||
|
def __init__(self, context):
|
||||||
|
#self.context = context
|
||||||
|
self.context = removeSecurityProxy(context)
|
||||||
|
|
||||||
|
def getTitle(self): return self.target.title
|
||||||
|
def setTitle(self, title): self.target.title = title
|
||||||
|
title = property(getTitle, setTitle)
|
||||||
|
|
||||||
|
def getSubConcepts(self, relationships=None):
|
||||||
|
return self.target.getSubConcepts(relationships)
|
||||||
|
|
||||||
|
def getParentConcepts(self, relationships=None):
|
||||||
|
return self.target.getParentConcepts(relationships)
|
||||||
|
|
||||||
|
|
||||||
class ResourceProxy(object):
|
class ResourceProxy(object):
|
||||||
|
|
||||||
adapts(IView)
|
adapts(IView)
|
||||||
|
|
||||||
|
def __init__(self, context):
|
||||||
|
#self.context = context
|
||||||
|
self.context = removeSecurityProxy(context)
|
||||||
|
|
||||||
def getTitle(self): return self.target.title
|
def getTitle(self): return self.target.title
|
||||||
def setTitle(self, title): self.target.title = title
|
def setTitle(self, title): self.target.title = title
|
||||||
title = property(getTitle, setTitle)
|
title = property(getTitle, setTitle)
|
||||||
|
@ -48,10 +73,6 @@ class ResourceProxy(object):
|
||||||
def getContentType(self): return self.target.contentType
|
def getContentType(self): return self.target.contentType
|
||||||
contentType = property(getContentType, setContentType)
|
contentType = property(getContentType, setContentType)
|
||||||
|
|
||||||
def __init__(self, context):
|
|
||||||
#self.context = context
|
|
||||||
self.context = removeSecurityProxy(context)
|
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def target(self):
|
def target(self):
|
||||||
return self.context.target
|
return self.context.target
|
||||||
|
|
Loading…
Add table
Reference in a new issue