On Oct 6, 2005, at 2:29 AM, James Allwyn wrote:

On 04/10/05, James Allwyn <[EMAIL PROTECTED]> 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. [EMAIL PROTECTED]) 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

_______________________________________________
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users

Reply via email to