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:
helmutm 2006-05-10 10:18:10 +00:00
parent d384a11c32
commit 8bba484be0
5 changed files with 152 additions and 2 deletions

View file

@ -52,7 +52,7 @@ class BaseView(object):
skin = None
if skinName and IView.providedBy(self.context):
skin = zapi.queryUtility(ISkin, skinName)
if skin is not None:
if skin:
applySkin(self.request, skin)
self.skin = skin

View file

@ -565,4 +565,32 @@
allowed_interface="zope.publisher.interfaces.browser.IBrowserPublisher"
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>

View file

@ -22,8 +22,10 @@ View class for Node objects.
$Id$
"""
from zope import component, interface
from zope.cachedescriptors.property import Lazy
from zope.app import zapi
from zope.app.annotation.interfaces import IAnnotations
from zope.app.catalog.interfaces import ICatalog
from zope.app.container.browser.contents import JustContents
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.proxy import removeSecurityProxy
from cybertools.browser import configurator
from cybertools.typology.interfaces import ITypeManager
from loops.interfaces import IConcept, IResource, IDocument, IMediaAsset, INode
from loops.interfaces import IViewConfiguratorSchema
from loops.resource import MediaAsset
from loops import util
from loops.browser.common import BaseView
@ -314,3 +318,43 @@ class NodeAdding(ContentAdding):
# 'has_custom_add_view': True,
# 'description': 'This creates a node with an associated document'})
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

View file

@ -13,6 +13,7 @@ Let's first do some basic imports
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
>>> site = placefulSetUp(True)
>>> from zope import interface, component
>>> from zope.app import zapi
>>> from zope.app.tests import ztapi
>>> from zope.interface import Interface
@ -32,6 +33,10 @@ and setup a simple loops site with its manager objects,
>>> loopsRoot['resources'] = ResourceManager()
>>> resources = loopsRoot['resources']
>>> from loops.view import ViewManager, Node
>>> loopsRoot['views'] = ViewManager()
>>> views = loopsRoot['views']
some concepts,
>>> cc1 = Concept(u'Zope')
@ -44,7 +49,7 @@ some concepts,
>>> cc2.title
u'Zope 3'
and resources:
resources,
>>> doc1 = Document(u'Zope Info')
>>> resources['doc1'] = doc1
@ -54,6 +59,16 @@ and resources:
>>> img1 = MediaAsset(u'An Image')
>>> 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:
>>> from cybertools.relation.interfaces import IRelationRegistry
@ -229,3 +244,55 @@ i.e. the 'topic' concept, via an adapter:
>>> cc1Adapter = cc1_type.typeInterface(cc1)
>>> ITopic.providedBy(cc1Adapter)
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'

View file

@ -497,3 +497,14 @@ class ITypeConcept(Interface):
source="loops.TypeInterfaceSource",
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)