[Zope3-dev] A generic Decorator class
Steve Alexander
steve@cat-box.net
Sat, 16 Feb 2002 19:17:25 +0000
Hi Folks,
This email is moderately long. It explains the generic Decorator class
I've written. I'd like to check Decorator.py into Zope3 somewhere, and
I'm seeking opinions on this.
Continuing in my quest to write a real application using Zope 3, I've
been extending the Contact example.
On thing I wanted to do was to make ContactInfoView show both the
IContactInfo and the IPostalInfo information when viewed.
To do this, I added two more table rows to info.pt:
<tr>
<td>City:</td>
<td tal:content="here/city">City</td>
</tr>
<tr>
<td>State:</td>
<td tal:content="here/state">State</td>
</tr>
Then, I needed a way of combining the Contact object with the
ContactCityState object (or whatever IPostalInfo is returned by the
utility).
Here's what I've done:
----
from Zope.Publisher.Browser.AttributePublisher import AttributePublisher
from Zope.PageTemplate import PageTemplateFile
from IContactInfo import IContactInfo
from Zope.ComponentArchitecture import getAdapter
from IPostal import IPostalInfo
class ContactInfoView(AttributePublisher):
"""Provide an interface for viewing a contact
"""
# Boiler plate
def __init__(self, context):
info = getAdapter(context, IPostalInfo, None)
self._context=Decorator(context, info)
def getContext(self):
return self._context
# Assert that we can only be applied to IContactInfo
__used_for__=IContactInfo
# Input form
index = PageTemplateFile('info.pt', globals())
from Interface.Util import objectImplements
from types import ListType, TupleType
class Decorator(object):
def __init__(self, context, decorations,
ArrayTypes=(ListType, TupleType)):
"""
context is the object to be decorated. All
attribute access falls through to this object.
decorations is a sequence of objects.
When an attribute is accessed, we see if it is a method
of an interface of one of the decorations. If so,
the decoration gets the message.
"""
self._context=context
if not isinstance(decorations, ArrayTypes):
decorations=[decorations]
self._decorations=decorations
def __getattribute__(self, attr_name):
for d in object.__getattribute__(self, '_decorations'):
for i in objectImplements(d):
if attr_name in i.names():
return getattr(d, attr_name)
return getattr(object.__getattribute__(self, '_context'),
attr_name)
----
Is there anything like this Decorator class in Zope3 at present?
It looks like it will be very useful when presenting a view combined
from a content objects and one or more adapters.
Can I check this in? Is there a better way to achieve my aims?
Thanks.
--
Steve Alexander