[BlueBream] registering utilities to dynamically populate List field/Choice vocabularies
Thierry Florac
tflorac at ulthar.net
Sun Sep 5 02:56:36 EDT 2010
______________________________________________________________________
Le samedi 4 septembre,
Jonah Crawford <jonah at tweetsprout.com> a écrit :
> I'm registering a utility which I would like to list a folder's
> contents so as to populate a drop down or multi select widget;
>
> problem is the utility gets called from the content type's
> interface/schema definition and there seems to be no way to pass it a
> context either for getSiteManager's lookups, or simply traversing to
> the desired folder and listing its contents.
>
> Naturally my example cod below doesn't work but it should shed some
> light on my (so far) unsuccessful approach..
>
>
> class IGroupIds(Interface):
> """Lists a group folder's items"""
>
> def getGroupIds():
> """go get'em"""
>
> class GroupIds:
> implements(IGroupIds)
>
> def getGroupIds(self, context):
> root = getParents(context)[-2]
> return [item for item in root['groups'].keys()]
>
>
> ### register it as a utility
>
> def register_groupids_util(context, event):
> sm = getSiteManager(context)
> groupids = GroupIds()
> sm.registerUtility(groupids, IGroupIds, 'groupids')
>
> ### access it from a content type's interfaces which gets called by
> the form render
>
> client_specified_groups = component.queryUtility(IGroupIds,
> 'groupids').getGroupIds(context)
>
>
> class INeedTheGroupListing(IContainer):
> groups = List(
> value_type=Choice( title= u'Client
> generated groups', values=client_specified_groups,),
> required=True
> )
______________________________________________________________________
Hi,
I think you should better use a vocabulary to define such a dynamic
list of values, as a vocabulary can be dynamic and have a context.
Something like that:
from zope.dublincore.interfaces import IZopeDublinCore as IDC
from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
class GroupsVocabulary(SimpleVocabulary):
classProvides(IVocabularyFactory)
def __init__(self, context):
root = getParents(context)[-2]
terms = [SimpleTerm(name,name,title)
for name,title in ((zapi.getName(item),IDC(item).title)
for item in root.values())]
super(GroupsVocabulary,self).__init__(terms)
Registering is done like that in ZCML:
<utility
name="groupids"
component=".GroupsVocabulary" />
or in Python code in the same way ; and the interface is modified as
follow:
class INeedTheGroupListing(IContainer):
groups = List(value_type=Choice(title=u'Client generated groups',
vocabulary='groupids'),
required=True)
Hope this helps,
Thierry
More information about the bluebream
mailing list