def __new__(cls, context, request, view, manager): chain = _get_context_chain(context) chain.pop() # bungeni_app top_section = chain.pop() if not chain: return # we require the tree to begin with a container object if not IReadContainer.providedBy(chain[-1]): return # remove any views from navigation tree if not (IAlchemistContent.providedBy(chain[0]) or IAlchemistContainer.providedBy(chain[0]) or ISection.providedBy(chain[0])): chain.pop(0) subcontext = chain[-1] if (len(chain) > 1 or IReadContainer.providedBy(subcontext) and not IAlchemistContainer.providedBy(subcontext) and len(subcontext)): inst = object.__new__(cls, context, request, view, manager) inst.chain = chain inst.top_section_url = url.absoluteURL(top_section, request) inst.id_prefix = "nav" return inst
def __new__(cls, context, request, view, manager): chain = _get_context_chain(context) chain.pop() # bungeni_app top_section = chain.pop() if not chain: return # we require the tree to begin with a container object if not IReadContainer.providedBy(chain[-1]): return # remove any views from navigation tree if not(IAlchemistContent.providedBy(chain[0]) or IAlchemistContainer.providedBy(chain[0]) or ISection.providedBy(chain[0]) ): chain.pop(0) subcontext = chain[-1] if (len(chain) > 1 or IReadContainer.providedBy(subcontext) and not IAlchemistContainer.providedBy(subcontext) and len(subcontext) ): inst = object.__new__(cls, context, request, view, manager) inst.chain = chain inst.top_section_url = url.absoluteURL(top_section, request) inst.id_prefix = "nav" return inst
def add_container_menu_items(self, context, container): request = self.request _url = url.absoluteURL(container, request) if IReadContainer.providedBy(container): #XXX should be the same in all containers ? container=proxy.removeSecurityProxy(container) for name, item in container.items(): if context is None: selected = False else: selected = url.same_path_names(context.__name__, name) item = proxy.removeSecurityProxy(item) if IDCDescriptiveProperties.providedBy(item): title = item.title else: props = IDCDescriptiveProperties(item) title = props.title # only items with valid title if title is not None: self.items.append(url.get_menu_item_descriptor( title, selected, _url, name)) default_view_name = queryDefaultViewName(container, self.request) default_view = component.queryMultiAdapter( (container, self.request), name=default_view_name) if hasattr(default_view, "title") and default_view.title is not None: self.items.insert(0, url.get_menu_item_descriptor( default_view.title, sameProxiedObjects(container, self.context), _url))
def subItems(self): """Collect all tree items for the given context.""" items = [] keys = [] append = items.append if IReadContainer.providedBy(self.context): try: keys = list(self.context.keys()) except(Unauthorized, Forbidden): return items else: return items counter = 1 for name in keys: # Only include items we can traverse to subItem = api.traverse(self.context, name, None) if subItem is not None: append((api.getName(subItem), subItem, self._hasSubItems(subItem))) counter += 1 if counter == self.maxItems: # add context which should support a item listing view with # batch lenght = len(keys) - self.maxItems default = '[%s more items...]' % lenght name = zope.i18n.translate( _('[${lenght} more items...]', mapping={'lenght':lenght}), context=self.request, default=default) append((name, self.context, False)) break return items
def publishTraverse(self, request, name): subob = self.traverse(name) if subob is not None: return safely_locate_maybe(subob, self.context, name) traversable_dict = traversable.bind().get(self.context) if traversable_dict: if name in traversable_dict: subob = getattr(self.context, traversable_dict[name]) if callable(subob): subob = subob() return safely_locate_maybe(subob, self.context, name) # XXX Special logic here to deal with containers. It would be # good if we wouldn't have to do this here. One solution is to # rip this out and make you subclass ContainerTraverser if you # wanted to override the traversal behaviour of containers. if IReadContainer.providedBy(self.context): item = self.context.get(name) if item is not None: return item view = component.queryMultiAdapter((self.context, request), name=name) if view is not None: return view raise NotFound(self.context, name, request)
def add_container_menu_items(self, context, container): request = self.request _url = url.absoluteURL(container, request) if IReadContainer.providedBy(container): #XXX should be the same in all containers ? container = proxy.removeSecurityProxy(container) for name, item in container.items(): if context is None: selected = False else: selected = url.same_path_names(context.__name__, name) item = proxy.removeSecurityProxy(item) if IDCDescriptiveProperties.providedBy(item): title = item.title else: props = IDCDescriptiveProperties(item) title = props.title # only items with valid title if title is not None: self.items.append( url.get_menu_item_descriptor(title, selected, _url, name)) default_view_name = queryDefaultViewName(container, self.request) default_view = component.queryMultiAdapter((container, self.request), name=default_view_name) if hasattr(default_view, "title") and default_view.title is not None: self.items.insert( 0, url.get_menu_item_descriptor( default_view.title, sameProxiedObjects(container, self.context), _url))
def update(self): request = self.request context = self.context chain = _get_context_chain(context) length = len(chain) self.items = [] if length < 2: # there must be at least: [top-level section, application] return # container is None else: # the penultimate context is the top-level container container = chain[-2] assert container.__name__ is not None if not IReadContainer.providedBy(container): return # container has no readable content assert container is not None # add container items if length > 2: context = chain[-3] else: context = None self.add_container_menu_items(context, container) # add any menu items from zcml self.add_zcml_menu_items(container)
def children_xmldoc(self): # If you need custom filter then reimplement this method. # Otherwise this implementation is generic and it is correct # for standard cases. try: rc = IReadContainer(self.context) except TypeError: return XMLDOC % u'' except Unauthorized: return XMLDOC % u'' specs = [queryMultiAdapter((value, self.request), IXML) for value in rc.values()] specs = filter(lambda x:x, specs) specs.sort(key = lambda x: x.sort_key()) nodes = [x.to_xml() for x in specs] return XMLDOC % u'\n'.join(nodes)
def getLengthOf(self, item): res = -1 if IReadContainer.providedBy(item): try: res = len(item) except (Unauthorized, Forbidden): pass return res
def __new__(cls, context, request, view, manager): # we have both primary and secondary navigation, so we won't # show the navigation tree unless we're at a depth > 2 chain = _get_context_chain(context)[:-2] if not chain: return # we require the tree to begin with a container object if not IReadContainer.providedBy(chain[-1]): return subcontext = chain[-1] if (len(chain) > 1 or IReadContainer.providedBy(subcontext) and not IAlchemistContainer.providedBy(subcontext) and len(subcontext)): inst = object.__new__(cls, context, request, view, manager) inst.chain = chain return inst
def singleBranchTree(self, root=''): parent = getParent(self.context) while parent is not None: if IReadContainer.providedBy(parent): view = queryMultiAdapter( (parent, self.request), name='singleBranchTree.xml') return view() else: parent = getParent(parent)
def children_xmldoc(self): # If you need custom filter then reimplement this method. # Otherwise this implementation is generic and it is correct # for standard cases. try: rc = IReadContainer(self.context) except TypeError: return XMLDOC % u'' except Unauthorized: return XMLDOC % u'' specs = [ queryMultiAdapter((value, self.request), IXML) for value in rc.values() ] specs = filter(lambda x: x, specs) specs.sort(key=lambda x: x.sort_key()) nodes = [x.to_xml() for x in specs] return XMLDOC % u'\n'.join(nodes)
def getObjectURL(ob, req): """Return the URL for the object `ob`. If the object is a container and the url doesn't end in slash '/' then append a slash to the url. """ url = zope.component.getMultiAdapter((ob, req), IAbsoluteURL)() if IReadContainer.providedBy(ob) and url[-1] != "/": url += "/" return url
def _hasSubItems(self, item): """This method allows us to decide if a sub item has items from the point of view of the context.""" res = False if IReadContainer.providedBy(item): try: if len(item) > 0: res = True except(Unauthorized, Forbidden): pass return res
def add_container_menu_items(self, context, container): request = self.request # add a menu item for each user workspace, if we are in an # IWorkspaceSectionLayer # !+ if user is logged in or if request.layer_data if interfaces.IWorkspaceSectionLayer.providedBy(request): try: workspaces = IAnnotations(request)["layer_data"].get( "workspaces") except: workspaces = [] log.info("%s got user workspaces: %s" % (self, workspaces)) base_url_path = "/workspace" for workspace in workspaces: log.info("appending menu item for user workspace: %s" % str(workspace)) self.items.append( url.get_menu_item_descriptor( workspace.full_name, pos_action_in_url( "/workspace/obj-%s" % workspace.group_id, request.getURL()), base_url_path, "obj-%s" % workspace.group_id)) _url = url.absoluteURL(container, request) if IReadContainer.providedBy(container): #XXX should be the same in all containers ? container = proxy.removeSecurityProxy(container) for name, item in container.items(): if context is None: selected = False else: selected = url.same_path_names(context.__name__, name) item = proxy.removeSecurityProxy(item) if IDCDescriptiveProperties.providedBy(item): title = item.title else: props = IDCDescriptiveProperties(item) title = props.title # only items with valid title if title is not None: self.items.append( url.get_menu_item_descriptor(title, selected, _url, name)) default_view_name = queryDefaultViewName(container, self.request) default_view = component.queryMultiAdapter((container, self.request), name=default_view_name) if hasattr(default_view, "title") and default_view.title is not None: self.items.insert( 0, url.get_menu_item_descriptor( default_view.title, sameProxiedObjects(container, self.context), _url))
def children_xmldoc(self): try: rc = IReadContainer(self.context) except TypeError: return XMLDOC % u'' except Unauthorized: return XMLDOC % u'' specs = [queryMultiAdapter((value, self.request), IXML) for value in rc.values()] specs = filter(lambda x:x, specs) specs.sort(key = lambda x: x.sort_key()) nodes = [x.to_xml() for x in specs] # add ++etc++site sm = self.context.getSiteManager() sm_spec = queryMultiAdapter((sm, self.request), IXML) nodes.append(sm_spec.to_xml()) return XMLDOC % u'\n'.join(nodes)
def _search_helper(id, obj, container, id_filters, object_filters, result): # check id filters if we get a match then return immediately for id_filter in id_filters: if id_filter.matches(id): result.append(obj) return # now check all object filters for object_filter in object_filters: if object_filter.matches(obj): result.append(obj) return # do we need to check sub containers? if not IReadContainer.providedBy(obj): return for key, value in obj.items(): _search_helper(key, value, obj, id_filters, object_filters, result)
def expand(self, chain, include_siblings=True): if len(chain) == 0: return () context = chain.pop() items = [] if IApplication.providedBy(context): items.extend(self.expand(chain)) elif IAlchemistContent.providedBy(context): _url = url.absoluteURL(context, self.request) selected = len(chain) == 0 if chain: nodes = self.expand(chain) else: containers = utils.get_managed_containers(context) nodes = [] self.expand_containers(nodes, containers, _url, chain, None) items.append({ "id": self.get_nav_entry_id(_url), "label": IDCDescriptiveProperties(context).title, "url": _url, "current": True, "selected": selected, "kind": "content", "nodes": nodes, }) elif IAlchemistContainer.providedBy(context): # loop through all managed containers of the parent # object, and include the present container as the # "current" node. parent = context.__parent__ assert parent is not None _url = url.absoluteURL(parent, self.request) # append managed containers as child nodes if include_siblings is True: if IApplication.providedBy(parent): containers = [ (name, parent[name]) for name in location.model_to_container_name_mapping.values() if name in parent ] elif IReadContainer.providedBy(parent): containers = list(parent.items()) else: containers = utils.get_managed_containers(parent) else: containers = [(context.__name__, context)] self.expand_containers(items, containers, _url, chain, context) elif ILocation.providedBy(context): # e.g. bungeni.core.content.Section, DisplayForm _url = url.absoluteURL(context, self.request) selected = len(chain) == 0 if selected and IReadContainer.providedBy(context): nodes = [] try: self.expand_containers( nodes, context.items(), _url, chain, context) except: pass else: nodes = self.expand(chain) _title = getattr(context, "title", None) or \ getattr(context, "page_title", "!+BungeniBrowserView.title") items.append({ "id": self.get_nav_entry_id(_url), # !+BungeniBrowserView.title "label": _title, #IDCDescriptiveProperties(context).title, "url": _url, "current": True, "selected": selected, "kind": "location", "nodes": nodes, }) elif IReadContainer.providedBy(context): #!+NavigationTreeViewlet-EXPAND-IReadContainer(mr, oct-2012) does this ever execute?! raise Exception("!+NavigationTreeViewlet-EXPAND-IReadContainer [%s]" % context) items.extend(self.expand(chain)) return items
def singleBranchTree(self, root=''): """Return an XML document with the siblings and parents of an object. There is only one branch expanded, in other words, the tree is filled with the object, its siblings and its parents with their respective siblings. """ result = 'selected' oldItem = self.context vh = self.request.getVirtualHostRoot() if vh: vhrootView = getMultiAdapter( (vh, self.request), name='absolute_url') baseURL = vhrootView() + '/' try: rootName = '[' + vh.__name__ + ']' except: # we got the containment root itself as the virtual host # and there is no name. rootName = _('[top]') parents = getParentsFromContextToObject(self.context, vh) else: rootName = _('[top]') baseURL = self.request.getApplicationURL() + '/' parents = getParents(self.context) rootName = translate(rootName, context=self.request, default=rootName) for item in parents: # skip skin if present #if item == oldItem: # continue subItems = [] if IReadContainer.providedBy(item): keys = list(item.keys()) if len(keys) >= 1000: keys = [] else: keys = [] # include the site manager keys.append(u'++etc++site') for name in keys: # Only include items we can traverse to subItem = traverse(item, name, None) iconUrl = self.getIconUrl(subItem) subitem_len = self.getLengthOf(subItem) if subitem_len >= 0: # the test below seems to be broken # with the ++etc++site case if subItem == oldItem: subItems.append(xmlEscapeWithCData( u'<collection name=%s length=%s ' u'icon_url=%s>%s</collection>', name, subitem_len, iconUrl, result)) else: subItems.append(xmlEscape( u'<collection name=%s length=%s ' u'icon_url=%s/>', name, subitem_len, iconUrl)) else: subItems.append(xmlEscape( u'<item name=%s icon_url=%s />', name, iconUrl)) result = u' '.join(subItems) oldItem = item # do not forget root folder iconUrl = self.getIconUrl(oldItem) result = xmlEscapeWithCData( u'<collection name=%s baseURL=%s length=%s ' u'icon_url=%s isroot="">%s</collection>', rootName, baseURL, len(oldItem), iconUrl, result) self.request.response.setHeader('Content-Type', 'text/xml') setNoCacheHeaders(self.request.response) title = translate(titleTemplate, context=self.request, default=titleTemplate) loading = translate(loadingMsg, context=self.request, default=loadingMsg) return xmlEscapeWithCData( u'<?xml version="1.0" ?>' u'<children title_tpl=%s loading_msg=%s>%s</children>', title, loading, result)
def is_container(self): # I recommend reimplement this and return IS_CONTAINER # or empty string directly return IReadContainer.providedBy(self.context) or u''
def expand(self, chain, include_siblings=True): if len(chain) == 0: return () context = chain.pop() items = [] if IApplication.providedBy(context): items.extend(self.expand(chain)) elif IAlchemistContent.providedBy(context): _url = url.absoluteURL(context, self.request) if IDCDescriptiveProperties.providedBy(context): title = context.title else: props = IDCDescriptiveProperties(context, None) if props is not None: title = props.title else: title = context.short_name selected = len(chain) == 0 if chain: nodes = self.expand(chain) else: kls = context.__class__ containers = [ (key, getattr(context, key)) for key, value in kls.__dict__.items() if isinstance(value, ManagedContainerDescriptor)] nodes = [] self.expand_containers(nodes, containers, _url, chain, None) items.append( {'title': title, 'url': _url, 'current': True, 'selected': selected, 'kind': 'content', 'nodes': nodes, }) elif IAlchemistContainer.providedBy(context): # loop through all managed containers of the parent # object, and include the present container as the # 'current' node. parent = context.__parent__ assert parent is not None _url = url.absoluteURL(parent, self.request) # append managed containers as child nodes kls = type(proxy.removeSecurityProxy(parent)) if include_siblings is True: if IApplication.providedBy(parent): containers = [ (name, parent[name]) for name in location.model_to_container_name_mapping.values() if name in parent ] elif IReadContainer.providedBy(parent): containers = list(parent.items()) else: containers = [ (key, getattr(parent, key)) for key, value in kls.__dict__.items() if isinstance(value, ManagedContainerDescriptor)] else: containers = [(context.__name__, context)] self.expand_containers(items, containers, _url, chain, context) elif ILocation.providedBy(context): _url = url.absoluteURL(context, self.request) #props = IDCDescriptiveProperties.providedBy(context) and \ # context or IDCDescriptiveProperties(context) if IDCDescriptiveProperties.providedBy(context): props = IDCDescriptiveProperties(context) else: props = context props = proxy.removeSecurityProxy(props) selected = len(chain) == 0 if selected and IReadContainer.providedBy(context): nodes = [] try: self.expand_containers( nodes, context.items(), _url, chain, context) except: pass else: nodes = self.expand(chain) i_id = getattr(props, 'id','N/A') items.append( {'title': getattr(props, 'title', i_id), 'url': _url, 'current': True, 'selected': selected, 'kind': 'location', 'nodes': nodes, }) elif IReadContainer.providedBy(context): items.extend(self.expand(chain)) return items
def matches(self, object): if not IReadContainer.providedBy(object): raise AssertionError("Expecting container") return len(object) == self._count
def __new__(cls, context, request, view, manager): inst = NavigationTreeViewlet.__new__(cls, context, request, view, manager) # we require the tree to begin with a container object if not IReadContainer.providedBy(inst.chain[-1]): return
def expand(self, chain, include_siblings=True): if len(chain) == 0: return () context = chain.pop() items = [] if IApplication.providedBy(context): items.extend(self.expand(chain)) elif IAlchemistContent.providedBy(context): _url = url.absoluteURL(context, self.request) selected = len(chain) == 0 if chain: nodes = self.expand(chain) else: containers = utils.get_managed_containers(context) nodes = [] self.expand_containers(nodes, containers, _url, chain, None) items.append({ "id": self.get_nav_entry_id(_url), "label": IDCDescriptiveProperties(context).title, "url": _url, "current": True, "selected": selected, "kind": "content", "nodes": nodes, }) elif IAlchemistContainer.providedBy(context): # loop through all managed containers of the parent # object, and include the present container as the # "current" node. parent = context.__parent__ assert parent is not None _url = url.absoluteURL(parent, self.request) # append managed containers as child nodes if include_siblings is True: if IApplication.providedBy(parent): containers = [ (name, parent[name]) for name in location.model_to_container_name_mapping.values() if name in parent ] elif IReadContainer.providedBy(parent): containers = list(parent.items()) else: containers = utils.get_managed_containers(parent) else: containers = [(context.__name__, context)] self.expand_containers(items, containers, _url, chain, context) elif ILocation.providedBy(context): # e.g. bungeni.core.content.Section, DisplayForm _url = url.absoluteURL(context, self.request) selected = len(chain) == 0 if selected and IReadContainer.providedBy(context): nodes = [] try: self.expand_containers(nodes, context.items(), _url, chain, context) except: pass else: nodes = self.expand(chain) _title = getattr(context, "title", None) or \ getattr(context, "page_title", "!+BungeniBrowserView.title") items.append({ "id": self.get_nav_entry_id(_url), # !+BungeniBrowserView.title "label": _title, #IDCDescriptiveProperties(context).title, "url": _url, "current": True, "selected": selected, "kind": "location", "nodes": nodes, }) elif IReadContainer.providedBy(context): #!+NavigationTreeViewlet-EXPAND-IReadContainer(mr, oct-2012) does this ever execute?! raise Exception( "!+NavigationTreeViewlet-EXPAND-IReadContainer [%s]" % context) items.extend(self.expand(chain)) return items
def matches(self, object): if IReadContainer.providedBy(object): return len(object) == self._count else: return False