[Zope3-Users] zope.schema.Object and custom widgets in formlib

Jachin Rupe jachin at voltzsoftware.com
Tue May 23 12:21:54 EDT 2006


On May 23, 2006, at 5:33 AM, Frank Burkhardt wrote:

[snip]

>
>> 	<content class=".entry.StreetAddress">
>> 		<allow interface=".interfaces.IABookEntry" />
>> 	</content>
>
> [snip]
>
> I bet '.interfaces.IABookEntry' doesn't cover the 'street'  
> attribut. You should better use
> '.interfaces.IStreetAddress' for your Object()-object.

[snip]

I'm not exactly sure what your getting at here, but I made a guess.   
I also found another error in my "widgets" package.  For some strange  
reason I was making an ObjectWIdget for entry.ABookEntry when I  
believe I should have been making one for entry.StreetAddress

Anyway I made some changes and I could add "entry.ABookEntry"s but  
editing them resulted in this error:  UnpickleableError: Cannot  
pickle <type 'zope.security._proxy._Proxy'> objects

There were a couple of other posts to the zope3-users message board  
about that problem and I read them.  The one that help was this one:

http://www.mail-archive.com/zope3-users@zope.org/msg00890.html

Now as far as I can tell everything is working.  I'll include all my  
code at the bottom in case anyone else is following along.  The  
changes from my last version are in entry.py, widges.py and  
configure.zcml

I'm working on a larger address book example, if anyone has any  
comments on how I'm going about this please share.

Also I'm still a little fuzzy on how  
objectwidgetdispatcher.ObjectInputWidget works.  I would really  
appreciate a little more explanation.

thanks

-jachin

<!-- -=configure.zcml=- -->

<configure
	xmlns="http://namespaces.zope.org/zope"
	xmlns:browser="http://namespaces.zope.org/browser">
	
	<content class=".entry.ABookEntry">
		<factory
			id = "entry.ABookEntry"
			title = "An address book entry"
			/>
		<require
			permission="zope.View"
			interface=".interfaces.IABookEntry"
			/>
		<require
			permission="zope.ManageContent"
			set_schema=".interfaces.IABookEntry"
			/>
	</content>
	<!--
	<content class=".entry.StreetAddress">
		<allow interface=".interfaces.IABookEntry" />
	</content>
	-->
	
	<content class=".entry.StreetAddress">
		<factory
			id = "entry.StreetAddress"
			title = "An street address"
			/>
		<require
			permission="zope.View"
			interface=".interfaces.IStreetAddress"
			/>
		<require
			permission="zope.ManageContent"
			set_schema=".interfaces.IStreetAddress"
			/>
	</content>
	
	<view type="zope.publisher.interfaces.browser.IBrowserRequest"
		for="zope.schema.interfaces.IObject"
		provides="zope.app.form.interfaces.IInputWidget"
		factory=".objectwidgetdispatcher.ObjectInputWidget"
		permission="zope.Public"
	/>
	
	<view
		type="zope.publisher.interfaces.browser.IBrowserRequest"
		for="zope.schema.interfaces.IObject .interfaces.IStreetAddress"
		provides="zope.app.form.interfaces.IInputWidget"
		factory=".widgets.StreetAddressWidget"
		permission="zope.Public"
	/>
	
	<browser:addform
		label = "New address book entry"
		name = "add_address_book_entry.html"
		schema = ".interfaces.IABookEntry"
		content_factory = ".entry.ABookEntry"
		permission = "zope.ManageContent"
		/>
	
	<browser:editform
		label = "Change address book entry"
		name = "edit.html"
		schema = ".interfaces.IABookEntry"
		permission = "zope.ManageContent"
		menu="zmi_views"
		title="Edit"
		/>
	
	<browser:addMenuItem
		title="ABook Entry"
		class=".entry.ABookEntry"
		permission="zope.ManageContent"
		view = "add_address_book_entry.html"
		/>
	
</configure>


# -=entry.py=-

from zope.security.proxy import removeSecurityProxy
from zope.interface import implements
from persistent import Persistent
from interfaces import IStreetAddress
from interfaces import IABookEntry


class StreetAddress(Persistent):
	"""The Street Address object."""
	implements(IStreetAddress)
	street = u""


class ABookEntry(Persistent):
	"""The Address Book Entry object."""
	implements(IABookEntry)
	firstName = u""
	
	def get_streetAddress(self):
		return self._streetAddress
		
	def set_streetAddress(self, streetAddress):
		self._streetAddress = removeSecurityProxy(streetAddress)
		
	streetAddress = property(get_streetAddress, set_streetAddress, None)
	

# -=interfaces.py=-

from zope.interface import Interface
from zope.schema import TextLine, Object

class IStreetAddress(Interface):
	"""A street address"""
	
	street = TextLine(
		title=u"street",
		description=u"",
		required=False)


class IABookEntry(Interface):
	"""An address book entry"""
	streetAddress = Object(
		schema=IStreetAddress,
		title=u"Street Address",
		description=u"",
		required=False)
	
	firstName = TextLine(
		title=u"First Name",
		description=u"",
		required=False)
	

# -=objectwidgetdispatcher.py=-

from zope.app import zapi
from zope.interface import implements

from zope.app.form.interfaces import IInputWidget

def ObjectInputWidget(context, request):
	"""Dispatch widget for Object schema field to a widget that is
	registered for (IObject, schema, IBrowserRequest) where schema
	is the schema of the object."""
	
	class Obj(object):
		implements(context.schema)
	
	widget=zapi.getMultiAdapter((context, Obj(), request), IInputWidget)
	return widget


# -=widgets.py=-

from zope.app.form.browser import ObjectWidget
from entry import StreetAddress

def StreetAddressWidget(context, obj, request):
	return ObjectWidget(context, request, StreetAddress)



More information about the Zope3-users mailing list