[Zope-dev] (New-style) Property Sheets in traditional (Python) products: an example example

Mike Fletcher mfletch@tpresence.com
Tue, 2 May 2000 04:20:37 -0400


Only reference I can find to this topic is 
http://zope.nipltd.com/public/lists/dev-archive.nsf/0a8715d5f3c7b6a3802568c1
006328f7/28e1ed0f8d7efdc980256879003d36d8 , which seems to have gone
unanswered.  So, since it took me so long to figure out (mostly because I
kept trying to put things into the class, not the instance, and 'cause I
didn't realise that the newer property sheet mechanisms don't want to
"pollute" the namespaces of the instance), figured I'd post an example of
using the PropertySheet/PropertySheets constructs.

Notes:
	I'm just guessing with a lot of this stuff, hopefully if there's
problems someone can point them out.  Use at your own risk, and take with a
grain of salt :) .
	I never could get the DefaultProperties mechanism to work (it's what
I was really wanting to use, doing the work with the PropertySheets stuff
means a lot of code re-writing).
	Is there a better/standard mechanism for getting properties than the
getProperty function in the example?  Seems this kind of access should be
included with the basic property system.
	I couldn't use PropertyManager because of limitations on datatypes
it will support.
	Haven't been able to get write-only properties to work.  They either
complain that I'm trying to overwrite them when i use the property
management interfaces, or they turn to "" strings.
	Neither old nor new property addition interfaces allow for adding
datetime or list property types.

Enjoy,
Mike

8<_____________ event2.py ___________

__doc__ = """Event Product Module"""
__version__ = '0.1'

from Globals import HTMLFile 
from Globals import MessageDialog 
from Globals import Persistent

import OFS.SimpleItem
from OFS.PropertySheets import PropertySheets, PropertySheet
import Acquisition                # Various acquisition types. 
import AccessControl.Role         # Zope Security management.
import DateTime

manage_addEvent2Form = HTMLFile('event2Add', globals())

def manage_addEvent2(self, id, REQUEST=None):
	'''Add an event object '''
	newEvent = Event( REQUEST )
	newEvent.id = id
	self._setObject( id, newEvent )
	if REQUEST is not None:
		return self.manage_main(self, REQUEST)

class Event(
		OFS.SimpleItem.Item,   # A simple Principia object. Not
Folderish. 
		Persistent,            # Make us persistent. Yaah! 
		Acquisition.Implicit,  # Let us use our parent's variables
and methods.  
		AccessControl.Role.RoleManager # Security manager.
	):
	meta_type='VRPilot Event'
	index_html =HTMLFile( 'event2Index', globals() )
	event2_display_rows = HTMLFile( 'event2_display_rows', globals() )
	
	manage_main = HTMLFile( 'event2Edit', globals() )
	manage_propertiesForm = manage_main # gets around assumption in
propertysheet code
	
	manage_options = (
		{'label':'Edit', 'action':'manage_main'},
		{'label':'View', 'action':'index_html'},
		# should do something more intelligent than hard-coding in a
real app
		{'label':'Properties',
'action':'properties/default/manage'},
		{'label':'Security', 'action':'manage_access'},
		)
	
	__ac_permissions__ = (
		('View', ('index_html', '')),
		('View management screens', 
			('manage', 'manage_main', 'getProperty')),
		('Manage properties', ('properties',)),
		)
	# these aren't used here, they are copied into the default property
sheet
	_properties = (
		{'id':'title', 'type': 'string', 'mode':'w', "meta": {}},
		{'id':'description', 'type': 'text', 'mode':'w', "meta":
{}},
		{'id':'location', 'type': 'string', 'mode':'w', "meta": {}},
		{'id':'startdate', 'type': 'datetime', 'mode':'w', "meta":
{}},
		{'id':'enddate', 'type': 'datetime', 'mode':'w', "meta":
{}},
	##	{'id':'creationdate', 'type': 'datetime', 'mode':'w',
"meta": {}},
	##	{'id':'creator', 'type': 'string', 'mode':'w', "meta": {}},
	)
	def __init__( self, REQUEST= None ):
		# simple attirbutes
		self.creationdate = DateTime.DateTime()
		self.creator = REQUEST.AUTHENTICATED_USER.getUserName()

		### Build property sheets...
		self.properties = PropertySheets()
		props = PropertySheet( 'default' )
		props._properties = self._properties
		props._extensible= 0 # don't allow definition of new
properties

		# the default values for the properties
		props.title = ""
		props.description = ""
		props.location = ""
		props.startdate = DateTime.DateTime()
		props.enddate = DateTime.DateTime()
		# add the default sheet to the set of sheets
		self.properties.__of__( self ).addPropertySheet( props )

		# now configure the property sheet...
		self.properties.get('default').manage_editProperties(
REQUEST )
		
	def getProperty( self, name, default=None ):
		'''
		Retrieve value of a property by name, from whatever property
sheet it is stored in
		If the property isn't valid for any sheet, return default
		'''
		for sheet in self.properties:
			if sheet.hasProperty( name ):
				return sheet.getProperty( name, default )
		return default
	
__________________________________
 Mike C. Fletcher
 Designer, VR Plumber
 http://members.home.com/mcfletch