[Zope3-Users] Re: Compound Form Elements
Duncan McGreggor
duncan.mcgreggor at gmail.com
Thu Oct 6 05:10:16 EDT 2005
On Oct 6, 2005, at 2:29 AM, James Allwyn wrote:
> On 04/10/05, James Allwyn <jamesallwyn at gmail.com> wrote:
>
>> Hello,
>>
>> I wish my users to be able to register various contact details. For
>> each, I would record the type (e.g. email, landline tel, mobile tel,
>> fax...), the value (e.g. test at email.com) and a True/False value on
>> whether it is to be visible on the site.
>
> I've tried to implement this zopeishly, and the stumbling block I've
> hit seems to be specifying the key and value_type pairs in the dict.
> So, for example:
[snip]
> This barfs when it hits the second value_type in the dict. Look at the
> zope.schema sources it seems I can only specify one value_type and one
> key_type. What I want to do is specify three pairs of keys and
> value_types - note, specifying the actual keys, not just their types.
> Is this possible? Or am I barking up the wrong tree!?
>
> Any hints gratefully received.
Hey James,
What you probably want to explore is the "Object" field. This lets you
define a "sub-schema", as it were, and use that in your "main" schema.
An example (untested)... maybe in yourproject/types/interfaces.py:
from zope.interface import Interface
from zope.schema import List, Text, TextLine, Int, Choice
from zope.schema import Object
from zope.i18nmessageid import MessageIDFactory
_ = MessageIDFactory('yourproj')
# sub-schema
class IContactData(Interface):
show = Bool(title = _(u"Show Data?"))
type = TextLine(title = _(u"Data Type"))
value = TextLine(title = _(u"Data Value"))
# main schema
class IUser(Interface)
name_first = TextLine(
title = _(u"First Name")
)
name_last = TextLine(
title = _(u"Last Name")
)
contact_info = List(
title = _(u"Contact Info"),
value_type = Object(
schema=IContactData,
),
)
Then (maybe in user.py, ):
...
class ContactData(object):
implements(IPageSection)
# and whatever else you might want to
# put in here
class User(PortalContent):
implements(IUser)
# and whatever else you might want to
# put in here
...
Then you're going to have to do some extra work with a custom widget (a
good place would be ./browser/userview.py):
from zope.app.form.browser import ObjectWidget
from zope.app.form.browser.editview import EditView
from zope.app.form import CustomWidgetFactory
from yourproject.types import ContactData
from yourproject.types.interfaces import IUser
parts_w = CustomWidgetFactory(ObjectWidget, ContactData)
class ContactDataEditView(EditView):
"""
View for editing a page section.
"""
__used_for__ = IUser
parts_widget = parts_w
In your browser/configure.zcml, your going to need something like this:
<browser:editform
schema="yourproject.types.interfaces.IUser"
class=".userview.ContactDataEditView"
label="Edit User"
name="edit.html"
menu="zmi_views"
title="Edit"
permission="zope.ManageContent" />
I may be forgetting something here... but this should certainly give
you a head start. There's a bunch of very good information on this in
these files:
zope/app/form/browser/widgets.txt
zope/app/form/browser/objectwidget.txt
Hmmm, looking through these again, these are really good examples. Pay
more attention to them than to what I wrote above ;-)
By the way, (and irrespective of the structure of the data) this data
you are adding seems to me a good candidate for annotations. You might
want to explore that...
Happy trails!
d
More information about the Zope3-users
mailing list