configurator stuff now working for controlling skin from menu node
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1202 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
d384a11c32
commit
8bba484be0
5 changed files with 152 additions and 2 deletions
|
@ -52,7 +52,7 @@ class BaseView(object):
|
||||||
skin = None
|
skin = None
|
||||||
if skinName and IView.providedBy(self.context):
|
if skinName and IView.providedBy(self.context):
|
||||||
skin = zapi.queryUtility(ISkin, skinName)
|
skin = zapi.queryUtility(ISkin, skinName)
|
||||||
if skin is not None:
|
if skin:
|
||||||
applySkin(self.request, skin)
|
applySkin(self.request, skin)
|
||||||
self.skin = skin
|
self.skin = skin
|
||||||
|
|
||||||
|
|
|
@ -565,4 +565,32 @@
|
||||||
allowed_interface="zope.publisher.interfaces.browser.IBrowserPublisher"
|
allowed_interface="zope.publisher.interfaces.browser.IBrowserPublisher"
|
||||||
permission="zope.Public" />
|
permission="zope.Public" />
|
||||||
|
|
||||||
|
<!-- view configurator stuff -->
|
||||||
|
|
||||||
|
<zope:adapter factory="loops.browser.node.ViewPropertiesConfigurator" />
|
||||||
|
|
||||||
|
<editform
|
||||||
|
label="Configure View Properties"
|
||||||
|
name="viewconfigure.html"
|
||||||
|
schema="loops.interfaces.IViewConfiguratorSchema"
|
||||||
|
for="loops.interfaces.INode"
|
||||||
|
template="edit.pt"
|
||||||
|
permission="zope.ManageContent"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<menuItem
|
||||||
|
for="loops.interfaces.INode"
|
||||||
|
action="viewconfigure.html"
|
||||||
|
permission="zope.ManageContent"
|
||||||
|
menu="zmi_views" title="View Properties"
|
||||||
|
filter="python: context.nodeType == 'menu'"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<zope:adapter
|
||||||
|
factory="loops.browser.node.NodeViewConfigurator"
|
||||||
|
for="loops.interfaces.INode
|
||||||
|
zope.publisher.interfaces.browser.IBrowserRequest"
|
||||||
|
provides="cybertools.browser.configurator.IViewConfigurator"
|
||||||
|
/>
|
||||||
|
|
||||||
</configure>
|
</configure>
|
||||||
|
|
|
@ -22,8 +22,10 @@ View class for Node objects.
|
||||||
$Id$
|
$Id$
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from zope import component, interface
|
||||||
from zope.cachedescriptors.property import Lazy
|
from zope.cachedescriptors.property import Lazy
|
||||||
from zope.app import zapi
|
from zope.app import zapi
|
||||||
|
from zope.app.annotation.interfaces import IAnnotations
|
||||||
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.container.browser.adding import ContentAdding
|
from zope.app.container.browser.adding import ContentAdding
|
||||||
|
@ -36,8 +38,10 @@ from zope.proxy import removeAllProxies
|
||||||
from zope.security import canAccess, canWrite
|
from zope.security import canAccess, canWrite
|
||||||
from zope.security.proxy import removeSecurityProxy
|
from zope.security.proxy import removeSecurityProxy
|
||||||
|
|
||||||
|
from cybertools.browser import configurator
|
||||||
from cybertools.typology.interfaces import ITypeManager
|
from cybertools.typology.interfaces import ITypeManager
|
||||||
from loops.interfaces import IConcept, IResource, IDocument, IMediaAsset, INode
|
from loops.interfaces import IConcept, IResource, IDocument, IMediaAsset, INode
|
||||||
|
from loops.interfaces import IViewConfiguratorSchema
|
||||||
from loops.resource import MediaAsset
|
from loops.resource import MediaAsset
|
||||||
from loops import util
|
from loops import util
|
||||||
from loops.browser.common import BaseView
|
from loops.browser.common import BaseView
|
||||||
|
@ -314,3 +318,43 @@ class NodeAdding(ContentAdding):
|
||||||
# 'has_custom_add_view': True,
|
# 'has_custom_add_view': True,
|
||||||
# 'description': 'This creates a node with an associated document'})
|
# 'description': 'This creates a node with an associated document'})
|
||||||
return info
|
return info
|
||||||
|
|
||||||
|
|
||||||
|
class ViewPropertiesConfigurator(object):
|
||||||
|
|
||||||
|
interface.implements(IViewConfiguratorSchema)
|
||||||
|
component.adapts(INode)
|
||||||
|
|
||||||
|
def __init__(self, context):
|
||||||
|
self.context = removeSecurityProxy(context)
|
||||||
|
|
||||||
|
def setSkinName(self, skinName):
|
||||||
|
ann = IAnnotations(self.context)
|
||||||
|
setting = ann.get(configurator.ANNOTATION_KEY, {})
|
||||||
|
setting['skinName'] = {'value': skinName}
|
||||||
|
ann[configurator.ANNOTATION_KEY] = setting
|
||||||
|
def getSkinName(self):
|
||||||
|
ann = IAnnotations(self.context)
|
||||||
|
setting = ann.get(configurator.ANNOTATION_KEY, {})
|
||||||
|
return setting.get('skinName', {}).get('value', '')
|
||||||
|
skinName = property(getSkinName, setSkinName)
|
||||||
|
|
||||||
|
|
||||||
|
class NodeViewConfigurator(configurator.ViewConfigurator):
|
||||||
|
""" Take properties from next menu item...
|
||||||
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def viewProperties(self):
|
||||||
|
result = []
|
||||||
|
for p in list(reversed(zapi.getParents(self.context))) + [self.context]:
|
||||||
|
if not INode.providedBy(p) or p.nodeType != 'menu':
|
||||||
|
continue
|
||||||
|
ann = IAnnotations(p)
|
||||||
|
propDefs = ann.get(configurator.ANNOTATION_KEY, {})
|
||||||
|
if propDefs:
|
||||||
|
result.extend([self.setupViewProperty(prop, propDef)
|
||||||
|
for prop, propDef in propDefs.items() if propDef])
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
69
helpers.txt
69
helpers.txt
|
@ -13,6 +13,7 @@ Let's first do some basic imports
|
||||||
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
|
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
|
||||||
>>> site = placefulSetUp(True)
|
>>> site = placefulSetUp(True)
|
||||||
|
|
||||||
|
>>> from zope import interface, component
|
||||||
>>> from zope.app import zapi
|
>>> from zope.app import zapi
|
||||||
>>> from zope.app.tests import ztapi
|
>>> from zope.app.tests import ztapi
|
||||||
>>> from zope.interface import Interface
|
>>> from zope.interface import Interface
|
||||||
|
@ -32,6 +33,10 @@ and setup a simple loops site with its manager objects,
|
||||||
>>> loopsRoot['resources'] = ResourceManager()
|
>>> loopsRoot['resources'] = ResourceManager()
|
||||||
>>> resources = loopsRoot['resources']
|
>>> resources = loopsRoot['resources']
|
||||||
|
|
||||||
|
>>> from loops.view import ViewManager, Node
|
||||||
|
>>> loopsRoot['views'] = ViewManager()
|
||||||
|
>>> views = loopsRoot['views']
|
||||||
|
|
||||||
some concepts,
|
some concepts,
|
||||||
|
|
||||||
>>> cc1 = Concept(u'Zope')
|
>>> cc1 = Concept(u'Zope')
|
||||||
|
@ -44,7 +49,7 @@ some concepts,
|
||||||
>>> cc2.title
|
>>> cc2.title
|
||||||
u'Zope 3'
|
u'Zope 3'
|
||||||
|
|
||||||
and resources:
|
resources,
|
||||||
|
|
||||||
>>> doc1 = Document(u'Zope Info')
|
>>> doc1 = Document(u'Zope Info')
|
||||||
>>> resources['doc1'] = doc1
|
>>> resources['doc1'] = doc1
|
||||||
|
@ -54,6 +59,16 @@ and resources:
|
||||||
>>> img1 = MediaAsset(u'An Image')
|
>>> img1 = MediaAsset(u'An Image')
|
||||||
>>> resources['img1'] = img1
|
>>> resources['img1'] = img1
|
||||||
|
|
||||||
|
and nodes (in view space):
|
||||||
|
|
||||||
|
>>> m1 = Node(u'Home')
|
||||||
|
>>> views['m1'] = m1
|
||||||
|
>>> m1.nodeType = 'menu'
|
||||||
|
|
||||||
|
>>> m1p1 = Node(u'Page')
|
||||||
|
>>> m1['p1'] = m1p1
|
||||||
|
>>> m1p1.nodeType = 'page'
|
||||||
|
|
||||||
Finally, we also need a relation registry:
|
Finally, we also need a relation registry:
|
||||||
|
|
||||||
>>> from cybertools.relation.interfaces import IRelationRegistry
|
>>> from cybertools.relation.interfaces import IRelationRegistry
|
||||||
|
@ -229,3 +244,55 @@ i.e. the 'topic' concept, via an adapter:
|
||||||
>>> cc1Adapter = cc1_type.typeInterface(cc1)
|
>>> cc1Adapter = cc1_type.typeInterface(cc1)
|
||||||
>>> ITopic.providedBy(cc1Adapter)
|
>>> ITopic.providedBy(cc1Adapter)
|
||||||
True
|
True
|
||||||
|
|
||||||
|
|
||||||
|
Controlling presentation using view properties
|
||||||
|
----------------------------------------------
|
||||||
|
|
||||||
|
>>> from zope.app.annotation.interfaces import IAttributeAnnotatable, IAnnotations
|
||||||
|
>>> from zope.app.annotation.attribute import AttributeAnnotations
|
||||||
|
>>> from loops.interfaces import INode
|
||||||
|
|
||||||
|
First we have to make sure we can use attribute annotations with our nodes,
|
||||||
|
and we also have to register an IViewConfigurator adapter for them:
|
||||||
|
|
||||||
|
>>> component.provideAdapter(AttributeAnnotations, (INode,), IAnnotations)
|
||||||
|
|
||||||
|
>>> from cybertools.browser.configurator import IViewConfigurator
|
||||||
|
>>> from loops.browser.node import NodeViewConfigurator
|
||||||
|
>>> from zope.publisher.interfaces.browser import IBrowserRequest
|
||||||
|
>>> component.provideAdapter(NodeViewConfigurator, (INode, IBrowserRequest),
|
||||||
|
... IViewConfigurator)
|
||||||
|
|
||||||
|
Now we are ready to set up a view on our page node:
|
||||||
|
|
||||||
|
>>> from loops.browser.node import NodeView
|
||||||
|
>>> request = TestRequest()
|
||||||
|
>>> view = NodeView(m1p1, request)
|
||||||
|
|
||||||
|
The elements responsible for presentation are controlled by a controller
|
||||||
|
object:
|
||||||
|
|
||||||
|
>>> from cybertools.browser.controller import Controller
|
||||||
|
>>> controller = Controller(view, request)
|
||||||
|
>>> getattr(controller, 'skinName', None) is None
|
||||||
|
True
|
||||||
|
|
||||||
|
There is no `skinName` setting in the controller as we did not set any.
|
||||||
|
The configurator (IViewConfigurator adapter, see above) takes the
|
||||||
|
view properties from the attribute annotations. We set these properties
|
||||||
|
using an adapter to the config schema; the configurator will only use
|
||||||
|
settings on menu nodes (possibly above the node to be viewed in the
|
||||||
|
browser).
|
||||||
|
|
||||||
|
>>> from loops.interfaces import IViewConfiguratorSchema
|
||||||
|
>>> from loops.browser.node import ViewPropertiesConfigurator
|
||||||
|
>>> component.provideAdapter(ViewPropertiesConfigurator, (INode,),
|
||||||
|
... IViewConfiguratorSchema)
|
||||||
|
|
||||||
|
>>> pageConfigurator = IViewConfiguratorSchema(m1)
|
||||||
|
>>> pageConfigurator.skinName = 'SuperSkin'
|
||||||
|
|
||||||
|
>>> controller = Controller(view, request)
|
||||||
|
>>> controller.skinName.value
|
||||||
|
'SuperSkin'
|
||||||
|
|
|
@ -497,3 +497,14 @@ class ITypeConcept(Interface):
|
||||||
source="loops.TypeInterfaceSource",
|
source="loops.TypeInterfaceSource",
|
||||||
required=False)
|
required=False)
|
||||||
|
|
||||||
|
|
||||||
|
# view configurator stuff
|
||||||
|
|
||||||
|
class IViewConfiguratorSchema(Interface):
|
||||||
|
|
||||||
|
skinName = schema.TextLine(
|
||||||
|
title=_(u'Skin Name'),
|
||||||
|
description=_(u'Name of the skin to use for this part of the site'),
|
||||||
|
default=u'',
|
||||||
|
required=False)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue