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,))
|
||||
|
||||
>>> 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
|
||||
>>> ztapi.provideUtility(IFactory, rest.ReStructuredTextSourceFactory,
|
||||
... 'zope.source.rest')
|
||||
|
@ -377,7 +371,7 @@ and of a lot of other stuff needed for the rendering machine.
|
|||
u''
|
||||
>>> doc1.data = u'Test data\n\nAnother paragraph'
|
||||
>>> view.renderTargetBody()
|
||||
u'Test data<br />\n<br />\nAnother paragraph'
|
||||
u'Test data\n\nAnother paragraph'
|
||||
>>> doc1.contentType = 'text/restructured'
|
||||
>>> view.renderTargetBody()
|
||||
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 interfaces import ILoops
|
||||
|
||||
loopsPrefix = '.loops'
|
||||
|
||||
class Loops(Folder):
|
||||
|
||||
implements(ILoops)
|
||||
|
@ -39,5 +41,9 @@ class Loops(Folder):
|
|||
return self['views']
|
||||
|
||||
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"
|
||||
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 -->
|
||||
|
||||
<addform
|
||||
|
@ -301,7 +309,7 @@
|
|||
label="Edit Node"
|
||||
name="edit.html"
|
||||
schema="loops.interfaces.INode"
|
||||
fields="title description nodeType body"
|
||||
fields="title description nodeType body target"
|
||||
for="loops.interfaces.INode"
|
||||
template="edit.pt"
|
||||
permission="zope.ManageContent"
|
||||
|
@ -369,6 +377,17 @@
|
|||
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
|
||||
name="node.html"
|
||||
for="loops.interfaces.INode"
|
||||
|
@ -390,12 +409,4 @@
|
|||
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>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!-- content macros -->
|
||||
|
||||
<metal:block define-macro="content"
|
||||
tal:define="bodyMacro view/bodyMacro">
|
||||
tal:define="bodyMacro item/bodyMacro">
|
||||
<metal:body use-macro="views/node_macros/?bodyMacro" />
|
||||
<tal:sub define="level python:level+1">
|
||||
<tal:items repeat="item item/textItems">
|
||||
|
@ -49,22 +49,22 @@
|
|||
|
||||
|
||||
<metal:body define-macro="imagebody">
|
||||
<tal:body define="body item/body"
|
||||
condition="body">
|
||||
<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:body define="body item/body">
|
||||
<div class="content-1" style="margin-top: 12px"
|
||||
tal:define="onclick string:openEditWindow('${item/url}/@@edit_target.html')"
|
||||
tal:attributes="class string:content-$level;
|
||||
ondblclick python: item.editable and onclick or ''">
|
||||
<img src="target"
|
||||
tal:attributes="src string:${item/url}/target" />
|
||||
</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>
|
||||
</metal:body>
|
||||
|
||||
|
|
|
@ -50,8 +50,9 @@ class DocumentView(object):
|
|||
""" Return the rendered content (data) of the context object.
|
||||
"""
|
||||
text = self.context.data
|
||||
typeKey = renderingFactories.get(self.context.contentType,
|
||||
renderingFactories['text/plain'])
|
||||
typeKey = renderingFactories.get(self.context.contentType, None)
|
||||
if typeKey is None:
|
||||
return text
|
||||
source = zapi.createObject(typeKey, text)
|
||||
view = zapi.getMultiAdapter((removeAllProxies(source), self.request))
|
||||
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.registry import IRelationsRegistry, getRelations
|
||||
|
||||
from interfaces import IConcept
|
||||
from interfaces import IConcept, IConceptView
|
||||
from interfaces import IConceptManager, IConceptManagerContained
|
||||
from interfaces import ILoopsContained
|
||||
|
||||
|
@ -54,7 +54,7 @@ class Concept(Contained, Persistent):
|
|||
|
||||
implements(IConcept, IConceptManagerContained)
|
||||
|
||||
proxyInterface = IConcept
|
||||
proxyInterface = IConceptView
|
||||
|
||||
_title = u''
|
||||
def getTitle(self): return self._title
|
||||
|
|
|
@ -230,6 +230,17 @@
|
|||
permission="zope.ManageContent" />
|
||||
<adapter factory="loops.target.MediaAssetProxy"
|
||||
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"
|
||||
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):
|
||||
""" A manager/container for concepts.
|
||||
"""
|
||||
|
@ -174,7 +178,7 @@ class IDocumentSchema(IResourceSchema):
|
|||
title=_(u'Content Type'),
|
||||
description=_(u'Content type (format) of the data field'),
|
||||
values=('text/restructured', 'text/structured', 'text/html',
|
||||
'text/plain',),
|
||||
'text/plain', 'text/xml', 'text/css'),
|
||||
default='text/restructured',
|
||||
required=True)
|
||||
|
||||
|
@ -237,7 +241,14 @@ class IView(ILoopsObject):
|
|||
default=u'',
|
||||
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):
|
||||
|
@ -325,7 +336,8 @@ class ITargetProperties(Interface):
|
|||
targetType = schema.Choice(
|
||||
title=_(u'Target Type'),
|
||||
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,
|
||||
required=False)
|
||||
|
||||
|
@ -361,6 +373,10 @@ class ILoops(ILoopsObject, IFolder):
|
|||
def getLoopsUri(obj):
|
||||
""" Return the relativ path to obj, starting with '.loops/...'.
|
||||
"""
|
||||
|
||||
def loopsTraverse(uri):
|
||||
""" Retrieve object specified by the loops uri given.
|
||||
"""
|
||||
|
||||
|
||||
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 IDocumentView, IMediaAssetView
|
||||
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):
|
||||
|
||||
adapts(IView)
|
||||
|
||||
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)
|
||||
|
@ -48,10 +73,6 @@ class ResourceProxy(object):
|
|||
def getContentType(self): return self.target.contentType
|
||||
contentType = property(getContentType, setContentType)
|
||||
|
||||
def __init__(self, context):
|
||||
#self.context = context
|
||||
self.context = removeSecurityProxy(context)
|
||||
|
||||
@Lazy
|
||||
def target(self):
|
||||
return self.context.target
|
||||
|
|
Loading…
Add table
Reference in a new issue