[Zope] ObjectManager 'Contents' problem
John Hunter
jdhunter@ace.bsd.uchicago.edu
Mon, 06 May 2002 18:05:15 -0500
I am working on two demo classes in a Product, a Person and an
Address. Both are derived from SimpleItem, and Person is also derived
from ObjectManager, because I want it to be able to contain an Address
in a Person.
Here is my problem:
When I add an Address instance to a Folder, all works as expected, so
I think the Address constructor and class are ok.
When I add an Address instance to an instance of my Person, zope
accepts it fine (no errors) but the instance does not show up in the
Contents view, which displays the message 'There are currently no
items in me' where 'me' is the id of the Person instance . If I try
to add another address with the same id, I get an error saying the id
is already in use. But I cannot see the Address instance, even if I
call a method like
<dtml-in "PARENTS[0].objectValues()">
<h3><dtml-var id>:</h3>
</dtml-in>
on the person instance.
I would appreciate any advice. I don't give a whit about persons or
addresses, but plan to use this code as a template for my actual
development, so I'm also happy to hear any criticism of the code
below. I am using the Component/Interface design suggested in the
Zope Dev Guide, and have based on lot of the code on maxm's HOWTOs and
mxm classes
Thanks,
John Hunter
######### Person.py -- the person interface ##################
from Interface import Base
class Person(Base):
"A person is a person, no matter how small"
def getFullName(self):
"Return full name"
######### PersonImplemetation.py ##################
from Person import Person
import Products
from AccessControl import ClassSecurityInfo
from Globals import DTMLFile, InitializeClass
from OFS.SimpleItem import SimpleItem
from OFS.PropertyManager import PropertyManager
from OFS.ObjectManager import ObjectManager
class PersonImplementation(SimpleItem, PropertyManager, ObjectManager):
"""
Person product class, implements Person interface.
"""
__implements__=Person
meta_type='Person'
security=ClassSecurityInfo()
_properties=({'id':'first', 'type': 'string', 'mode': 'w'},
{'id':'last', 'type': 'string', 'mode': 'w'},
)
_allowed_meta_types = ('Address', )
manage_options = (
(ObjectManager.manage_options[0],)+
PropertyManager.manage_options +
SimpleItem.manage_options +
(
{ 'label' : 'View', 'action' : 'index_html', },
)
)
security.declarePublic('index_html')
#security.declareProtected('View management screens', 'index_html')
index_html=DTMLFile('www/person/index_html', globals())
def __init__(self, id, first, last):
self.id=id
self.first = first
self.last = last
security.declarePublic('getFullName')
def getFullName(self):
"Return full name"
return '%s %s' % (self.first, self.last)
def all_meta_types(self):
"""
Returns what meta_types can be added to the objectmanager
"""
if hasattr(self, '_allowed_meta_types'):
result = []
for metaType in Products.meta_types:
if metaType['name'] in self._allowed_meta_types:
result.append(metaType)
return result
else:
return Products.meta_types
def addPersonForm(dispatcher):
"""
Returns an HTML form.
"""
return """<html>
<head><title>Add Person</title></head>
<body>
<form action="addPersonFunction">
id <input type="type" name="id"><br>
first <input type="type" name="first"><br>
last <input type="type" name="last"><br>
<input type="submit" value="Add">
</form>
</body>
</html>"""
def addPersonFunction(dispatcher, id, first, last, REQUEST=None):
"""
Create a new person and add it to myself
"""
n=PersonImplementation(id, first, last)
dispatcher.Destination()._setObject(id, n)
if REQUEST is not None:
return dispatcher.manage_main(dispatcher, REQUEST)
InitializeClass(PersonImplementation)
######### Address.py -- the interface ##################
from Interface import Base
class Address(Base):
"Where to find me"
def getAddress(self):
"Return full address"
######### AddressImplemetation.py ##################
from Address import Address
from AccessControl import ClassSecurityInfo
from Globals import DTMLFile, InitializeClass
from OFS.SimpleItem import SimpleItem
from OFS.PropertyManager import PropertyManager
class AddressImplementation(SimpleItem, PropertyManager):
"""
Address product class, implements Address interface.
"""
__implements__=Address
meta_type='Address'
security=ClassSecurityInfo()
_properties=({'id':'street', 'type': 'string', 'mode': 'w'},
{'id':'city', 'type': 'string', 'mode': 'w'},
{'id':'state', 'type': 'string', 'mode': 'w'},
{'id':'zip', 'type': 'string', 'mode': 'w'},
)
manage_options = \
PropertyManager.manage_options + \
SimpleItem.manage_options + \
(
{ 'label' : 'View', 'action' : 'index_html', },
)
security.declarePublic('index_html')
#security.declareProtected('View management screens', 'index_html')
index_html=DTMLFile('www/address/index_html', globals())
def __init__(self, id, street, city, state, zip):
self.id=id
self.street = street
self.city = city
self.state = state
self.zip = zip
security.declarePublic('getAddress')
def getAddress(self):
"Return full address"
return '%s\n%s, %s %s' % (self.street, self.city, self.state, self.zip)
def addAddressForm(dispatcher):
"""
Returns an HTML form.
"""
return """<html>
<head><title>Add Address</title></head>
<body>
<form action="addAddressFunction">
id <input type="type" name="id"><br>
street <input type="type" name="street"><br>
city <input type="type" name="city"><br>
state <input type="type" name="state"><br>
zip <input type="type" name="zip"><br>
<input type="submit" value="Add">
</form>
</body>
</html>"""
def addAddressFunction(dispatcher, id, street, city, state, zip, REQUEST=None):
"""
Create a new address and add it to myself
"""
n=AddressImplementation(id, street, city, state, zip)
dispatcher.Destination()._setObject(id, n)
if REQUEST is not None:
return dispatcher.manage_main(dispatcher, REQUEST)
InitializeClass(AddressImplementation)
############### Product __init__.py #####################
from PersonImplementation import PersonImplementation, addPersonForm, addPersonFunction
from AddressImplementation import AddressImplementation, addAddressForm, addAddressFunction
def initialize(registrar):
registrar.registerClass(
PersonImplementation,
constructors = (addPersonForm, addPersonFunction),
icon="www/images/User_icon.gif",
)
registrar.registerClass(
AddressImplementation,
constructors = (addAddressForm, addAddressFunction),
)