This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
plone.formwidget.contenttree/plone/formwidget/contenttree/utils.py

49 lines
1.5 KiB
Python

from Acquisition import aq_base
from Products.CMFCore.interfaces import IContentish
from Products.CMFCore.interfaces import IFolderish
from zope.component.hooks import getSite
try:
from zope.globalrequest import getRequest
getRequest # pyflakes
except ImportError:
# Fake it
getRequest = object
def closest_content(context=None):
"""Try to find a usable context, with increasing agression"""
# Normally, we should be given a useful context (e.g the page)
c = context
c = _valid_context(c)
if c is not None:
return c
# Subforms (e.g. DataGridField) may not have a context set, find out
# what page is being published
c = getattr(getRequest(), 'PUBLISHED', None)
c = _valid_context(c)
if c is not None:
return c
# During widget traversal nothing is being published yet, use getSite()
c = getSite()
c = _valid_context(c)
if c is not None:
return c
raise ValueError('Cannot find suitable context to bind to source')
def _valid_context(context):
"""Walk up until finding a content item."""
# Avoid loops. The object id is used as context may not be hashable
seen = set()
while context is not None and id(aq_base(context)) not in seen:
seen.add(id(aq_base(context)))
if (IContentish.providedBy(context)
or IFolderish.providedBy(context)):
return context
parent = getattr(context, '__parent__', None)
if parent is None:
parent = getattr(context, 'context', None)
context = parent
return None