zope.schema.Object input widget trouble with formlib

5 Messages Forum Options Options
Permalink
Andrija Prčić
zope.schema.Object input widget trouble with formlib
Reply Threaded More
Print post
Permalink
Hello, people!

I'm working on some custom content types for a university, and I have some trouble with the zope.schema.Object fields in an interface. No ArcheTypes, just pure formlib.

interfaces.py (was intentionaly created like this to make collaboration with other people easier, and to have less clashes when merging into code repository):

from Person import IPerson
from ResearchProject import IResearchProject

Person.py (it is a lot longer, but everything that is snipped are just some more TextLine fields):

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

class IPerson(Interface):
    """A person
    """

    title = TextLine(
            title=u"Name",
            description=u"Display name of the person",
            required=True,
            )

<--- snip --->

ResearchProject.py:

from zope.interface import Interface
from zope.schema import TextLine, Text, Choice, Int, Object, List
from interfaces import IPerson

class IResearchProject(Interface):
    """A research project
    """

    title = TextLine(
            title=u"Title",
            description=u"Title of the research project",
            required=True,
            )


    #
    # I want the staff field to be a list of people who are working on that research project. As far as I have seen some tutorials, this is the way to go.
    #
    staff = List(
            title=u"Staff",
            description=u"People working on the research project",
            required=False,
            value_type=Object(
                    title=u"Staff member",
                    schema=IPerson,
                    )
            )

As I said, I don't use ArcheTypes at all, just pure formlib, but haven't found any usefull tutorials about object input widgets and Plone. I did manage to find one in pure Zope, but it was not of much use. In the end, it again went kaboom, just with a different error, and the tutorial itself looked a bit strange (non Plone-ish) to me.

My best guess is that I'm just missing something like

form_fields['staff'].custom_widget = some_widget_I_need_to_import_and_set_here_but_I_don_t_know_which_one

in the edit form in browser/researchproject.py

Any help would be greatly appreciated. A link to some good tutorials about Plone and zope.schema.Object fields especially!

--
Andrija Prčić

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Plone-Users mailing list
Plone-Users@...
https://lists.sourceforge.net/lists/listinfo/plone-users
Israel Saeta Pérez
Re: zope.schema.Object input widget trouble with formlib
Reply Threaded More
Print post
Permalink
Hello Andrija,

On Thu, Jul 24, 2008 at 4:40 PM, Andrija Prčić <andrija.prcic@...> wrote:

> Hello, people!
>
> I'm working on some custom content types for a university, and I have some trouble with the zope.schema.Object fields in an interface. No ArcheTypes, just pure formlib.
>
> interfaces.py (was intentionaly created like this to make collaboration with other people easier, and to have less clashes when merging into code repository):
>
> from Person import IPerson
> from ResearchProject import IResearchProject
>
> Person.py (it is a lot longer, but everything that is snipped are just some more TextLine fields):
>
> from zope.interface import Interface
> from zope.schema import TextLine, Text
>
> class IPerson(Interface):
>    """A person
>    """
>
>    title = TextLine(
>            title=u"Name",
>            description=u"Display name of the person",
>            required=True,
>            )
>
> <--- snip --->
>
> ResearchProject.py:
>
> from zope.interface import Interface
> from zope.schema import TextLine, Text, Choice, Int, Object, List
> from interfaces import IPerson
>
> class IResearchProject(Interface):
>    """A research project
>    """
>
>    title = TextLine(
>            title=u"Title",
>            description=u"Title of the research project",
>            required=True,
>            )
>
>
>    #
>    # I want the staff field to be a list of people who are working on that research project. As far as I have seen some tutorials, this is the way to go.
>    #
>    staff = List(
>            title=u"Staff",
>            description=u"People working on the research project",
>            required=False,
>            value_type=Object(
>                    title=u"Staff member",
>                    schema=IPerson,
>                    )
>            )


Try instead:

    staff = List(
            title=u"Staff",
            description=u"People working on the research project",
            required=False,
            value_type=Choice(
                    title=u"Staff member",
                    vocabulary=People,
                    )
            )


You'd need to define a vocabulary:

from Products.CMFCore.utils import getToolByName
from zope.interface import alsoProvides
from zope.schema.vocabulary import SimpleVocabulary
from zope.schema.interfaces import IVocabularyFactory

def People(context):
    catalog = getToolByName(context, 'portal_catalog')
    brains = catalog(object_provides=IPerson.__identifier__)
    return SimpleVocabulary.fromValues([brain.Title for brain in brains])
alsoProvides(People, IVocabularyFactory)  # People isn't a class but a
factory function


I hope I don't miss anything...


> As I said, I don't use ArcheTypes at all, just pure formlib, but haven't found any usefull tutorials about object input widgets and Plone. I did manage to find one in pure Zope, but it was not of much use. In the end, it again went kaboom, just with a different error, and the tutorial itself looked a bit strange (non Plone-ish) to me.
>
> My best guess is that I'm just missing something like
>
> form_fields['staff'].custom_widget = some_widget_I_need_to_import_and_set_here_but_I_don_t_know_which_one
>
> in the edit form in browser/researchproject.py
>
> Any help would be greatly appreciated. A link to some good tutorials about Plone and zope.schema.Object fields especially!

I wouldn't expect any kind of "Object widget" available. You can enter
numbers, textlines, text, select a value, etc. in a form, but you
can't enter "an object", you'd have to use its Title, id, etc.

I can be totally wrong, but I hope that will help you getting closer
to solve your problem. :-)



--
Israel Saeta Pérez
http://dukebody.com
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Plone-Users mailing list
Plone-Users@...
https://lists.sourceforge.net/lists/listinfo/plone-users
Israel Saeta Pérez
Andrija Prčić
Re: zope.schema.Object input widget trouble with formlib
Reply Threaded More
Print post
Permalink
Hello,

Thanks for pointing me in the right direction, but I still have trouble.

On Friday 25 July 2008 00.28:30 Israel Saeta Pérez wrote:

> >    # I want the staff field to be a list of people who are working on that research project. As far as I have seen some tutorials, this is the way to go.
> >    staff = List(
> >            title=u"Staff",
> >            description=u"People working on the research project",
> >            required=False,
> >            value_type=Object(
> >                    title=u"Staff member",
> >                    schema=IPerson,
> >                    )
> >            )
>
> Try instead:
>
>     staff = List(
>             title=u"Staff",
>             description=u"People working on the research project",
>             required=False,
>             value_type=Choice(
>                     title=u"Staff member",
>                     vocabulary=People,
>                     )
>             )

When I did that, I got an assertion error when starting Zope, without any pointers as to what might be wrong.

While digging around the internet, I found that vocabulary is always set as a string, so I put vocabulary="People" instead. This got me to being able to run Zope, and now I have an error when I add the ResearchProject type to the portal:
 
Exception traceback

Time    2008/07/25 16:54:09.076 GMT+2
User Name (User Id)     admin (admin)
Request URL    http://localhost:8080/infnine/stuff/+/infnine.data.ResearchProject
Exception Type    ComponentLookupError
Exception Value    (<InterfaceClass zope.schema.interfaces.IVocabularyFactory>, 'People')

Traceback (innermost last):
  Module ZPublisher.Publish, line 119, in publish
  Module ZPublisher.mapply, line 88, in mapply
  Module ZPublisher.Publish, line 42, in call_object
  Module zope.formlib.form, line 769, in __call__
  Module Products.Five.formlib.formbase, line 55, in update
  Module zope.formlib.form, line 732, in update
  Module infnine.data.browser.researchproject, line 28, in setUpWidgets
  Module zope.formlib.form, line 257, in setUpWidgets
  Module zope.schema._field, line 354, in bind
  Module zope.schema._field, line 243, in bind
  Module zope.app.schema.vocabulary, line 33, in get
  Module zope.component._api, line 207, in getUtility
ComponentLookupError: (<InterfaceClass zope.schema.interfaces.IVocabularyFactory>, 'People')

When I run ./bin/zopepy and try:
from zope.schema.interfaces import IVocabularyFactory
it works fine.

Any idea what might be wrong?
> I wouldn't expect any kind of "Object widget" available. You can enter
> numbers, textlines, text, select a value, etc. in a form, but you
> can't enter "an object", you'd have to use its Title, id, etc.

I expected to find some "Object widget" which would enable me to select objects by id, and present to the user the title fields of all objects that meet some criteria.

To the user -> list of names
Programatically -> list of object ids

--
Andrija Prčić

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Plone-Users mailing list
Plone-Users@...
https://lists.sourceforge.net/lists/listinfo/plone-users
Israel Saeta Pérez
zope.schema.Object input widget trouble with formlib
Reply Threaded More
Print post
Permalink
I always forget to use the "reply to all" function, sorry...


---------- Forwarded message ----------
From: Israel Saeta Pérez <dukebody@...>
Date: 2008/7/25
Subject: Re: [Plone-Users] zope.schema.Object input widget trouble with formlib
To: Andrija Prčić <andrija.prcic@...>


Hello Andrija,

2008/7/25 Andrija Prčić <andrija.prcic@...>:

> Hello,
>
> Thanks for pointing me in the right direction, but I still have trouble.
>
> On Friday 25 July 2008 00.28:30 Israel Saeta Pérez wrote:
>> >    # I want the staff field to be a list of people who are working on that research project. As far as I have seen some tutorials, this is the way to go.
>> >    staff = List(
>> >            title=u"Staff",
>> >            description=u"People working on the research project",
>> >            required=False,
>> >            value_type=Object(
>> >                    title=u"Staff member",
>> >                    schema=IPerson,
>> >                    )
>> >            )
>>
>> Try instead:
>>
>>     staff = List(
>>             title=u"Staff",
>>             description=u"People working on the research project",
>>             required=False,
>>             value_type=Choice(
>>                     title=u"Staff member",
>>                     vocabulary=People,
>>                     )
>>             )
>
> When I did that, I got an assertion error when starting Zope, without any pointers as to what might be wrong.
>
> While digging around the internet, I found that vocabulary is always set as a string, so I put vocabulary="People" instead.

Hmmm, I have a project where I've set the vocabulary field to a
SimpleVocabulary instance, but it was Plone 2.5, I guess the new Zopes
have added new (good) restrictions.

Anyways,

> This got me to being able to run Zope, and now I have an error when I add the ResearchProject type to the portal:
>
> Exception traceback
>
> Time    2008/07/25 16:54:09.076 GMT+2
> User Name (User Id)     admin (admin)
> Request URL    http://localhost:8080/infnine/stuff/+/infnine.data.ResearchProject
> Exception Type    ComponentLookupError
> Exception Value    (<InterfaceClass zope.schema.interfaces.IVocabularyFactory>, 'People')
>
> Traceback (innermost last):
>  Module ZPublisher.Publish, line 119, in publish
>  Module ZPublisher.mapply, line 88, in mapply
>  Module ZPublisher.Publish, line 42, in call_object
>  Module zope.formlib.form, line 769, in __call__
>  Module Products.Five.formlib.formbase, line 55, in update
>  Module zope.formlib.form, line 732, in update
>  Module infnine.data.browser.researchproject, line 28, in setUpWidgets
>  Module zope.formlib.form, line 257, in setUpWidgets
>  Module zope.schema._field, line 354, in bind
>  Module zope.schema._field, line 243, in bind
>  Module zope.app.schema.vocabulary, line 33, in get
>  Module zope.component._api, line 207, in getUtility
> ComponentLookupError: (<InterfaceClass zope.schema.interfaces.IVocabularyFactory>, 'People')
>
> When I run ./bin/zopepy and try:
> from zope.schema.interfaces import IVocabularyFactory
> it works fine.
>
> Any idea what might be wrong?

this error means Zope couldn't find any utility named 'People'
providing zope.schema.interfaces.IVocabularyFactory. You have to
register it in your configure.zcml. Assuming the People utility is
defined in a vocabularies.py file in the same folder of your
configure.zcml,

<utility
   component=".vocabularies.People"
   name="People"
   />

And that's all, it should work now.

>> I wouldn't expect any kind of "Object widget" available. You can enter
>> numbers, textlines, text, select a value, etc. in a form, but you
>> can't enter "an object", you'd have to use its Title, id, etc.
>
> I expected to find some "Object widget" which would enable me to select objects by id, and present to the user the title fields of all objects that meet some criteria.
>
> To the user -> list of names
> Programatically -> list of object ids

When creating the vocabulary, you can use
SimpleVocabulary.fromItems({id1:name1, id2:name2, etc.}) to do that.
In theory. :-)


--
Israel Saeta Pérez
http://dukebody.com



--
Israel Saeta Pérez
http://dukebody.com
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Plone-Users mailing list
Plone-Users@...
https://lists.sourceforge.net/lists/listinfo/plone-users
Israel Saeta Pérez
Andrija Prčić
Re: zope.schema.Object input widget trouble with formlib
Reply Threaded More
Print post
Permalink
Getting closer, but still not there...

The add form shows up fine, the selection widget shows me people correctly, but I get this error trace when I click save:

Exception traceback

Time 2008/07/27 00:03:41.580 GMT+2
User Name (User Id) admin (admin)
Request URL http://localhost:8080/infnine/stuff/+/infnine.data.ResearchProject
Exception Type AttributeError
Exception Value portal_catalog

Traceback (innermost last):

    * Module ZPublisher.Publish, line 119, in publish
    * Module ZPublisher.mapply, line 88, in mapply
    * Module ZPublisher.Publish, line 42, in call_object
    * Module zope.formlib.form, line 769, in __call__
    * Module Products.Five.formlib.formbase, line 55, in update
    * Module zope.formlib.form, line 750, in update
    * Module zope.formlib.form, line 594, in success
    * Module plone.app.form.base, line 27, in handle_save_action
    * Module zope.formlib.form, line 866, in createAndAdd
    * Module infnine.data.browser.researchproject, line 33, in create
    * Module zope.formlib.form, line 526, in applyChanges
    * Module zope.schema._bootstrapfields, line 171, in get
    * Module zope.schema.fieldproperty, line 43, in __get__
    * Module zope.schema._field, line 354, in bind
    * Module zope.schema._field, line 243, in bind
    * Module zope.app.schema.vocabulary, line 34, in get
    * Module infnine.data.ResearchProject, line 9, in People
    * Module Products.CMFCore.utils, line 123, in getToolByName

AttributeError: portal_catalog

I inserted import pdb; pdb.set_trace() into the vocabulary function to follow it around, and it gets called several times: 2 times when the add form is showing up, and 2 times when I click on save. On the 4th call, it blows up with the forementioned error trace. Any ideas as to where the portal_catalog disappears, and why is the vocabulary function called so many times?

--
Andrija Prčić

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Plone-Users mailing list
Plone-Users@...
https://lists.sourceforge.net/lists/listinfo/plone-users