basic set up for view configurator stuff
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1200 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
d8de666f2f
commit
cbc15a5a2d
7 changed files with 195 additions and 15 deletions
|
@ -3,8 +3,12 @@ Browser View Tools
|
|||
|
||||
We first set up a test and working environment:
|
||||
|
||||
>>> from zope.app import zapi
|
||||
>>> from zope.app.testing import ztapi
|
||||
>>> from zope.app import zapi
|
||||
>>> from zope.app.testing import ztapi
|
||||
|
||||
>>> from zope import component, interface
|
||||
>>> from zope.publisher.browser import TestRequest
|
||||
>>> from zope.publisher.interfaces.browser import IBrowserRequest
|
||||
|
||||
The View Controller
|
||||
-------------------
|
||||
|
@ -91,3 +95,43 @@ The pre-set collection of macros for a certain slot may be extended:
|
|||
>>> print m5.name, m5.media, m5.resourceName
|
||||
css all node.css
|
||||
|
||||
|
||||
The View Configurator
|
||||
---------------------
|
||||
|
||||
A view configurator is a multiadapter for a content object that provides
|
||||
a set of properties to be used for setting up special presentation
|
||||
characteristics of a page. Typical examples for such characteristics are
|
||||
|
||||
- the skin to be used
|
||||
- the logo to show in the corner of the page
|
||||
|
||||
The default configurator uses attribute annotations for retrieving view
|
||||
properties; that means that there could be form somewhere to edit those
|
||||
properties and store them in the content object's annotations.
|
||||
|
||||
The configurator is called automatically from the controller if there is
|
||||
an appropriate adapter:
|
||||
|
||||
>>> from cybertools.browser.configurator import IViewConfigurator
|
||||
>>> from cybertools.browser.configurator import ViewConfigurator
|
||||
>>> component.provideAdapter(ViewConfigurator, (SomeObject, IBrowserRequest),
|
||||
... IViewConfigurator)
|
||||
>>> controller = Controller(view, request)
|
||||
|
||||
But this does not have any effect as long as there aren't any properties
|
||||
stored in the attribute annotations. So let's set a 'skinName' attribute:
|
||||
|
||||
>>> from zope.app.annotation.interfaces import IAttributeAnnotatable, IAnnotations
|
||||
>>> from zope.app.annotation.attribute import AttributeAnnotations
|
||||
>>> interface.classImplements(SomeObject, IAttributeAnnotatable)
|
||||
>>> component.provideAdapter(AttributeAnnotations, (SomeObject,), IAnnotations)
|
||||
>>> ann = IAnnotations(obj)
|
||||
>>> setting = {'skinName': {'value': 'SuperSkin'}}
|
||||
>>> from cybertools.browser.configurator import ANNOTATION_KEY
|
||||
>>> ann[ANNOTATION_KEY] = setting
|
||||
|
||||
>>> controller = Controller(view, request)
|
||||
>>> controller.skinName.value
|
||||
'SuperSkin'
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2005 Helmut Merz helmutm@cy55.de
|
||||
# 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
|
||||
|
@ -21,13 +21,3 @@ cybertools browser package.
|
|||
|
||||
$Id$
|
||||
"""
|
||||
|
||||
from zope.viewlet.interfaces import IViewletManager
|
||||
|
||||
class ILeft(IViewletManager):
|
||||
""" Left slot.
|
||||
"""
|
||||
|
||||
class IBody(IViewletManager):
|
||||
""" Body (main) content slot.
|
||||
"""
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
<metal:logo define-macro="logo">
|
||||
<a href="#" name="logo" title="Home"
|
||||
tal:attributes="href macro/href;
|
||||
title macro/title"><img
|
||||
src="logo.gif" border="0" alt="Home"
|
||||
tal:attributes="src string:${resourceBase}${macro/resourceName};
|
||||
alt macro/alt" /></a>
|
||||
</metal:logo>
|
||||
|
||||
|
||||
<metal:css define-macro="css">
|
||||
<style type="text/css" media="all"
|
||||
tal:attributes="media macro/media"
|
||||
|
|
118
browser/configurator.py
Normal file
118
browser/configurator.py
Normal file
|
@ -0,0 +1,118 @@
|
|||
#
|
||||
# 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
|
||||
#
|
||||
|
||||
"""
|
||||
A view configurator provides configuration data for a view controller.
|
||||
|
||||
$Id$
|
||||
"""
|
||||
|
||||
from zope.app import zapi
|
||||
from zope.app.annotation.interfaces import IAttributeAnnotatable
|
||||
from zope.app.annotation.attribute import AttributeAnnotations
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
from zope.interface import Interface, Attribute, implements
|
||||
from zope.component import adapts
|
||||
|
||||
|
||||
# interfaces
|
||||
|
||||
class IViewConfigurator(Interface):
|
||||
""" Usually implemented by an adapter (e.g. to IAnnotatable);
|
||||
provides a set of properties that govern the appearance of a
|
||||
page, e.g. the name of the logo, CSS file(s), or portlets.
|
||||
"""
|
||||
|
||||
viewProperties = Attribute('A sequence of IViewProperty objects')
|
||||
|
||||
|
||||
class IViewProperty(Interface):
|
||||
|
||||
slot = Attribute('The property slot to fill')
|
||||
name = Attribute('The name of the object to fill the slot')
|
||||
|
||||
|
||||
class IMacroViewProperty(IViewProperty):
|
||||
|
||||
slot = Attribute('The property slot to fill')
|
||||
name = Attribute('The name of the macro to use; may be None, '
|
||||
'meaning that the slot name will be used')
|
||||
template = Attribute('The template providing the macro')
|
||||
params = Attribute('A mapping with parameters (key/value pairs) '
|
||||
'to be handed over to the macro')
|
||||
|
||||
|
||||
#default implementations
|
||||
|
||||
ANNOTATION_KEY = 'cybertools.browser.configurator.ViewConfigurator'
|
||||
|
||||
class ViewConfigurator(AttributeAnnotations):
|
||||
""" Simple/basic default adapter using attribute annotations as storage
|
||||
for view properties.
|
||||
"""
|
||||
|
||||
implements(IViewConfigurator)
|
||||
|
||||
def __init__(self, context, request):
|
||||
AttributeAnnotations.__init__(self, context)
|
||||
self.context = context
|
||||
self.request = request
|
||||
|
||||
@property
|
||||
def viewProperties(self):
|
||||
propDefs = self.get(ANNOTATION_KEY, [])
|
||||
result = []
|
||||
for prop in propDefs:
|
||||
vp = zapi.queryMultiAdapter((self.context, self.request),
|
||||
IViewProperty, name=prop)
|
||||
if vp is None:
|
||||
vp = ViewProperty(self.context, self.request)
|
||||
vp.slot = prop
|
||||
vp.setParams(propDefs[prop])
|
||||
result.append(vp)
|
||||
return result
|
||||
|
||||
|
||||
class ViewProperty(object):
|
||||
|
||||
implements(IViewProperty)
|
||||
|
||||
def __init__(self, context, request):
|
||||
self.context = context
|
||||
self.request = request
|
||||
self.slot = None
|
||||
self.name = None
|
||||
self.value = None
|
||||
self.params = {}
|
||||
|
||||
def setParams(self, params):
|
||||
self.name = params.pop('name', '')
|
||||
self.value = params.pop('value', None)
|
||||
self.params = params
|
||||
|
||||
|
||||
class MacroViewProperty(object):
|
||||
|
||||
implements(IMacroViewProperty)
|
||||
|
||||
template = None
|
||||
|
||||
def setParams(self, params):
|
||||
self.name = params.pop('name', '')
|
||||
self.template = params.pop('template', None)
|
||||
self.params = params
|
|
@ -26,6 +26,8 @@ from zope.app import zapi
|
|||
from zope.app.pagetemplate import ViewPageTemplateFile
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
|
||||
from cybertools.browser.configurator import IViewConfigurator, IMacroViewProperty
|
||||
|
||||
|
||||
class Controller(object):
|
||||
|
||||
|
@ -34,6 +36,7 @@ class Controller(object):
|
|||
self.context = context.context
|
||||
self.request = request
|
||||
self.skin = None # may be overwritten by the view
|
||||
self.configure()
|
||||
context.controller = self # notify the view
|
||||
|
||||
@Lazy
|
||||
|
@ -46,6 +49,17 @@ class Controller(object):
|
|||
# TODO: put '/@@' etc after path to site instead of directly after URL0
|
||||
return self.request.URL[0] + skinSetter + '/@@/'
|
||||
|
||||
def configure(self):
|
||||
configurator = zapi.queryMultiAdapter((self.context, self.request),
|
||||
IViewConfigurator)
|
||||
if configurator is not None:
|
||||
for item in configurator.viewProperties:
|
||||
if IMacroViewProperty.providedBy(item):
|
||||
self.macros.register(item.slot, item.template, item.name,
|
||||
**item.params)
|
||||
else:
|
||||
setattr(self, item.slot, item)
|
||||
|
||||
|
||||
class Macros(dict):
|
||||
|
||||
|
|
|
@ -33,6 +33,10 @@ body {
|
|||
border-left: none;
|
||||
}
|
||||
|
||||
div.box h4 {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.footer {
|
||||
text-align: center;
|
||||
border-top: 1px solid #ccc;
|
||||
|
|
|
@ -296,7 +296,7 @@ pre {
|
|||
}
|
||||
|
||||
div#action {
|
||||
height: 16px;
|
||||
height: 1.35em;
|
||||
/*width: 100%;*/
|
||||
background-color: #c8c4ff;
|
||||
border-left: 1px solid #6478b0;
|
||||
|
@ -368,7 +368,7 @@ div.box h4 {
|
|||
color: #606060;
|
||||
padding: 0px 5px;
|
||||
display: block;
|
||||
height: 18px;
|
||||
/* height: 18px; */
|
||||
}
|
||||
|
||||
.box div.body {
|
||||
|
|
Loading…
Add table
Reference in a new issue