We use IContextSourceBinder frequently e.g.
form.widget("gl_refs_my_onkopedia", SelectWidget, multiple="multiple")
gl_refs_my_onkopedia = schema.List(
title=_("References to My-Onkopedia"),
description=_("References to My-Onkopedia"),
required=False,
value_type=schema.Choice(
source=OnkopediaPathBinder(["my-onkopedia", "mein-onkopedia"])
),
default=[],
)
with
@implementer(IContextSourceBinder)
class OnkopediaPathBinder(object):
""" Returns all linkable objects in a given subarea of Onkopedia"""
def __init__(self, areas, subpath="guidelines", drug_assessment=False):
super(OnkopediaPathBinder, self).__init__()
assert isinstance(areas, (list, tuple)), "areas must be tuple or list"
self.areas = areas
self.subpath = subpath
self.drug_assessment = drug_assessment
def __call__(self, context):
items = list()
portal = plone.api.portal.get()
uuids_seen = set()
for area in self.areas:
language = (
"de" if "/onkopedia/de" in "/".join(context.getPhysicalPath()) else "en"
)
path = "{}/{}".format(language, area)
if self.subpath:
path += "/{}".format(self.subpath)
target_folder = portal.restrictedTraverse(path, None)
if target_folder is not None:
for brain in target_folder.getFolderContents():
if brain.UID in uuids_seen:
continue
if self.drug_assessment:
title = safe_unicode(brain.Title)
title += " (" + safe_unicode(brain.topic_str)
if brain.specifications_str:
title += ", {}".format(
safe_unicode(brain.specifications_str)
)
if brain.specifications2_str:
title += ", {}".format(
safe_unicode(brain.specifications2_str)
)
title += ")"
items.append(SimpleTerm(brain.UID, brain.UID, title))
else:
items.append(SimpleTerm(brain.UID, brain.UID, brain.Title))
uuids_seen.add(brain.UID)
items = sorted(items, key=operator.attrgetter("title"))
return VocabularyWrapper(SimpleVocabulary(items))
class VocabularyWrapper(object):
""" Wraps a SimpleVocabulary into a searchable source """
def __init__(self, vocabulary):
self.vocabulary = vocabulary
def getTermByToken(self, token):
return self.vocabulary.getTermByToken(token)
def __contains__(self, name):
return name in self.vocabulary
def getTerm(self, term):
return self.vocabulary.getTerm(term)
def __iter__(self):
for item in self.vocabulary:
yield item
def search(self, query_string):
items = []
for term in self.vocabulary:
if query_string.lower() in term.title.lower():
items.append(term)
return items
~