I'm using Plone 4.1.4 and I'm trying to get dynamic sources for a schema.Choice to work, I need to populate country list which in turn depends on the context object.
I'm using this example: http://plone.org/products/dexterity/documentation/manual/developer-manual/advanced/vocabularies
For IContextSourceBinder, example, an empty dictionary instead of actual context object is returned:
from zope import interface
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
from zope.schema.interfaces import IContextSourceBinder
import zope.schema
from z3c.form import form
class CountryGenerator(object):
interface.implements(IContextSourceBinder)
def __call__(self, context):
#context is == {}
import pdb; pdb.set_trace()
return SimpleVocabulary([
SimpleTerm(value="not_selected", title=_("Country Not Selected"))
])
class IStep(interface.Interface):
region = schema.Choice(title=_("Select your country"),
required=True,
source=CountryGenerator,
default="not_selected")
class Step(form.Form):
fields = field.Fields(IStep)
label = _("Step")
description = _("Select your country")
When debugging point is hit inside CountryGenerator.__call__() method and I examine context object, the latter turn out to be just an empty dictionary.
When I try to use named utility example in the article mentioned above, and the similar thing happens, context there is also {}.
Could anyone point me to what I might be doing wrong?
UPDATE
ZCML for the form wrapper that calls the form is
<browser:page
name="view"
for="Products.oldproduct.MyFolderishClass"
class=".file.RegionClass"
permission="zope2.View"
/>
Where RegionClass inherits from Form wrapper, could it be permission or traversal issue?
Because your source is a class, you need to instantiate it:
class IStep(interface.Interface):
region = schema.Choice(title=_("Select your country"),
required=True,
source=CountryGenerator(),
default="not_selected")
In certain circumstances, such as with using sub forms or complex form widgets (widget within a widget for list selections, etc), you need to follow the __parent__
pointers to a proper outer context for getting back to the Plone context.