Plone: RelationChoice & ContentTreeFieldWidget mit dynamischem Path-Filter
Im folgenden werden mittels eigenem ObjPathSourceBinder für ein RelationChoice field die anzuzeigenden Elemente im ContentTreeFieldWidget gefiltert.
Im einfachen Fall, dass man den Pfad festlegen kann, funktioniert auch folgende Konfiguration des ObjPathSourceBinder:
related_obj = RelationChoice( title=_(u"Referenziertes Objekt"), source=ObjPathSourceBinder( portal_type="MyRelatedObjType", navigation_tree_query=dict( portal_type=["MyRelatedObjType",], path={ "query": '/ub/ub-db' }) ), required=False, )
Will man aber den Pfad zur Laufzeit ermitteln, dann kann man nicht wie oben beschrieben vorgehen. Wir bauen uns deshalb einen angepassten ObjPathSourceBinder welcher
from Acquisition import aq_parent, aq_inner from plone.formwidget.contenttree import ObjPathSourceBinder from plone.formwidget.contenttree.utils import closest_content from zope.interface import implementer from zope.schema.interfaces import IVocabularyFactory def get_librarydb(context): """Get the most local 'Library Database'.""" parent = context if not parent: return None while parent.portal_type != 'LibraryDB': parent = aq_parent(aq_inner(parent)) if getattr(parent, 'portal_type', None) is None: return None return parent @implementer(IVocabularyFactory) class RelatedObjPathSourceBinder(ObjPathSourceBinder): """Provide available related objects.""" def __call__(self, context): if 'path' not in self.navigation_tree_query: db = get_librarydb(context) if db: path = '/'.join(db.getPhysicalPath()) self.navigation_tree_query["path"] = {"query": path} return self.path_source( closest_content(context), selectable_filter=self.selectable_filter, navigation_tree_query=self.navigation_tree_query) RelatedObjPathSourceBinderFactory = RelatedObjPathSourceBinder()
Der neue RelatedObjPathSourceBinder kann wie folgt verwendet werden.
related_obj = RelationChoice( title=_(u"Referenziertes Objekt"), source=RelatedObjPathSourceBinder( portal_type="MyRelatedObjType", navigation_tree_query=dict( portal_type=["MyRelatedObjType",]) ), required=False, )