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
Example #2
0
    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
Example #3
0
def _get_title_from_context(context):
    title = None
    if IAlchemistContent.providedBy(context):
        if IDCDescriptiveProperties.providedBy(context):
            title = context.title
        else:
            props = IDCDescriptiveProperties(context, None)
            if props is not None:
                title = props.title
            else:
                ''' !+
AttributeError: 'GroupAddress' object has no attribute 'short_name':   File "/home/undesa/bungeni/cap_installs/bungeni_install/bungeni/releases/20100305100101/src/bungeni.main/bungeni/ui/viewlets/navigation.py", line 59, in _get_title_from_context
                #title = context.short_name 
So, we temporarily default the above to the context.__class__.__name__:
                '''
                title = getattr(context, "short_name",
                                context.__class__.__name__)
    elif IAlchemistContainer.providedBy(context):
        domain_model = context._class
        try:
            descriptor = queryModelDescriptor(domain_model)
        except:
            descriptor = None
            name = ""
        if descriptor:
            name = getattr(descriptor, 'container_name', None)
            if name is None:
                name = getattr(descriptor, 'display_name', None)
        if not name:
            name = getattr(context, '__name__', None)
        title = name
    elif ILocation.providedBy(context) and \
         IDCDescriptiveProperties.providedBy(context):
        title = context.title
    return title
def _get_title_from_context(context):
    title = None
    if IAlchemistContent.providedBy(context):
        if IDCDescriptiveProperties.providedBy(context):
            title = context.title
        else:
            props = IDCDescriptiveProperties(context, None)
            if props is not None:
                title = props.title
            else:
                """ !+
AttributeError: 'GroupAddress' object has no attribute 'short_name':   File "/home/undesa/bungeni/cap_installs/bungeni_install/bungeni/releases/20100305100101/src/bungeni.main/bungeni/ui/viewlets/navigation.py", line 59, in _get_title_from_context
                #title = context.short_name 
So, we temporarily default the above to the context.__class__.__name__:
                """
                title = getattr(context, "title", context.__class__.__name__)
    elif IWorkspaceContainer.providedBy(context):
        # WorkspaceContainer._class is not set (and not unique) and it breaks the
        # connection between Container -> ContentClass
        title = context.__name__
    elif IAlchemistContainer.providedBy(context):
        domain_model = context._class
        try:
            descriptor = utils.get_descriptor(domain_model)
        except KeyError, e:
            log.warn("TYPE_INFO: no descriptor for model %s " "[container=%s] [error=%s]" % (domain_model, context, e))
            descriptor = None
            name = ""
        if descriptor:
            name = getattr(descriptor, "container_name", None)
            if name is None:
                name = getattr(descriptor, "display_name", None)
        if not name:
            name = getattr(context, "__name__", None)
        title = name
    def expand_containers(self, items, containers, _url, chain=(), context=None):
        # seen_context = False
        _url = _url.rstrip("/")
        current = False

        for key, container in self._sort_containers(containers):
            assert IAlchemistContainer.providedBy(container)
            label = container.domain_model.__name__
            descriptor = utils.get_descriptor(container.domain_model)
            if descriptor:
                label = getattr(descriptor, "container_name", None) or getattr(descriptor, "display_name", None)

            if context is not None:
                current = container.__name__ == context.__name__
            selected = not len(chain) and current
            if current:
                # seen_context = True
                nodes = self.expand(chain)
            else:
                nodes = ()

            key_url = "%s/%s" % (_url, key)
            items.append(
                {
                    "id": self.get_nav_entry_id(key_url),
                    "label": translate(
                        label, target_language=get_request_language(request=self.request), domain="bungeni"
                    ),
                    "url": key_url,
                    "current": current,
                    "selected": selected,
                    "kind": "container",
                    "nodes": nodes,
                }
            )
Example #6
0
 def getMenuItems(self, context, request):
     results = []
     try:
         items = proxy.removeSecurityProxy(context.__parent__).items()
     except AttributeError:
         return results
     for key, item in items:
         if not IAlchemistContainer.providedBy(item): continue
         if not IScheduleText.implementedBy(item.domain_model): continue
         dc_adapter = IDCDescriptiveProperties(item, None)
         if dc_adapter:
             _title = dc_adapter.title
         else:
             _title = getattr(item, "title", "Unknown")
         results.append(dict(
             title=_title,
             description=_title,
             action = url.absoluteURL(item, request),
             selected=False,
             icon=None,
             extra={},
             submenu=None
             
         ))
     return results
Example #7
0
def filterFields(context, form_fields):
    omit_names = []
    if IAlchemistContent.providedBy(context):
        md = utils.get_descriptor(context.__class__)
        for field in form_fields:
            # field:zope.formlib.form.FormField
            try:
                can_write = security.canWrite(context, field.__name__)
                can_read = security.canAccess(context, field.__name__)
            except AttributeError:
                log.warn('filterFields: item [%s] has no field named "%s"',
                         context, field.__name__)
                can_write = can_read = False
            if can_write:
                continue
            if can_read:
                field.for_display = True
                field.custom_widget = md.get(field.__name__).view_widget
            else:
                omit_names.append(field.__name__)
    elif not IAlchemistContainer.providedBy(context):
        ctx = getattr(context, "context", None)
        if ctx:
            filterFields(ctx, form_fields)
        else:
            raise NotImplementedError
    return form_fields.omit(*omit_names)
Example #8
0
 def process_document_tree(root, context):
     """Iterate and optionally update children of provided root node.
     
     Rendering is based on type of node. Further calls to this function
     happen when a node with children exists - and so on.
     
     Only nodes with the bungeni namespace tags "br:type" are modified
     with content from the provided context.
     """
     iter_children = root.getchildren() or [root]
     if not (root in iter_children):
         root_typ = get_attr(root, "type")
         if root_typ:
             process_single_node(root, context, root_typ,
                                 get_attr(root, "source"))
     for child in iter_children:
         typ = get_attr(child, "type")
         src = get_attr(child, "source")
         children = child.getchildren()
         if len(children) == 0:
             if typ:
                 process_single_node(child, context, typ, src)
         else:
             if typ:
                 if typ == "listing":
                     clean_element(child)
                     children = child.getchildren()
                     listing = get_element_value(context,
                                                 src,
                                                 default=[])
                     if IAlchemistContainer.providedBy(listing):
                         listing = [
                             item for item in
                             common.list_container_items(listing)
                         ]
                     len_listing = len(listing)
                     expanded_children = [
                         deepcopy(children) for x in range(len_listing)
                     ]
                     empty_element(child)
                     if len(listing) == 0:
                         no_items_tag = "p"
                         if child.tag == "tr":
                             no_items_tag = "td"
                         no_items_node = etree.SubElement(
                             child, no_items_tag)
                         no_items_node.text = translate_i18n(
                             _(u"No items found"))
                     else:
                         for (index, item) in enumerate(listing):
                             for inner_element in expanded_children[
                                     index]:
                                 iroot = process_document_tree(
                                     inner_element, item)
                                 child.append(iroot)
                 else:
                     process_document_tree(child, context)
             else:
                 process_document_tree(child, context)
     return root
def _get_title_from_context(context):
    title = None
    if IAlchemistContent.providedBy(context):
        if IDCDescriptiveProperties.providedBy(context):
            title = context.title
        else:
            props = IDCDescriptiveProperties(context, None)
            if props is not None:
                title = props.title
            else:
                ''' !+
AttributeError: 'GroupAddress' object has no attribute 'short_name':   File "/home/undesa/bungeni/cap_installs/bungeni_install/bungeni/releases/20100305100101/src/bungeni.main/bungeni/ui/viewlets/navigation.py", line 59, in _get_title_from_context
                #title = context.short_name 
So, we temporarily default the above to the context.__class__.__name__:
                '''
                title = getattr(context, "short_name", 
                    context.__class__.__name__)
    elif IAlchemistContainer.providedBy(context):
        domain_model = context._class 
        try:
            descriptor = queryModelDescriptor(domain_model)
        except:
            descriptor = None
            name = ""
        if descriptor:
            name = getattr(descriptor, 'container_name', None)
            if name is None:
                name = getattr(descriptor, 'display_name', None)
        if not name:
            name = getattr(context, '__name__', None)
        title = name
    elif ILocation.providedBy(context) and \
         IDCDescriptiveProperties.providedBy(context):
        title = context.title
    return title
Example #10
0
 def process_document_tree(root, context):
     """Iterate and optionally update children of provided root node.
     
     Rendering is based on type of node. Further calls to this function
     happen when a node with children exists - and so on.
     
     Only nodes with the bungeni namespace tags "br:type" are modified
     with content from the provided context.
     """
     cond = get_attr(root, "condition")
     if cond and not check_exists(context, cond):
         return None
     iter_children = root.getchildren() or [root]
     if not (root in iter_children):
         root_typ = get_attr(root, "type")
         if root_typ:
             process_single_node(root, context, root_typ, get_attr(root, "source"))
     for child in iter_children:
         typ = get_attr(child, "type")
         src = get_attr(child, "source")
         cond = get_attr(child, "condition")
         if cond and not check_exists(context, cond):
             drop_element(child)
             continue
         children = child.getchildren()
         if len(children) == 0:
             if typ:
                 process_single_node(child, context, typ, src)
         else:
             if typ:
                 if typ == "listing":
                     clean_element(child)
                     children = child.getchildren()
                     listing = get_element_value(context, src, default=[])
                     if IAlchemistContainer.providedBy(listing):
                         listing = [item for item in common.list_container_items(listing)]
                     len_listing = len(listing)
                     expanded_children = [deepcopy(children) for x in range(len_listing)]
                     empty_element(child)
                     if len(listing) == 0:
                         no_items_tag = "p"
                         if child.tag == "tr":
                             no_items_tag = "td"
                         no_items_node = etree.SubElement(child, no_items_tag)
                         no_items_node.text = translate_i18n(_(u"No items found"))
                     else:
                         for (index, item) in enumerate(listing):
                             for inner_element in expanded_children[index]:
                                 iroot = process_document_tree(inner_element, item)
                                 if iroot is not None:
                                     child.append(iroot)
                 elif typ == "block" and src:
                     block_context = get_element_value(context, src, default=None)
                     process_document_tree(child, block_context)
                 else:
                     process_document_tree(child, context)
             else:
                 process_document_tree(child, context)
     clean_element(root)
     return root
Example #11
0
    def _searchresults(self):
        section = get_section_name()
        subqueries = []
        
        type_filter = ""
        
        if IAlchemistContainer.providedBy(self.context):
            for t in ALLOWED_TYPES["business"]:
                iface = resolve.resolve("bungeni.models.interfaces.I%sContainer"%t)
                if iface.providedBy(self.context):
                    type_filter = t
                    break
        
        if type_filter:
            type_query = self.searcher.query_field('object_type', type_filter)
        else:
            # Filter items allowed in current section
            for tq in ALLOWED_TYPES[section]:
                subqueries.append(self.searcher.query_field('object_type', tq))
                type_query = self.searcher.query_composite(self.searcher.OP_OR, 
                                                           subqueries)

        self.query = self.searcher.query_composite(self.searcher.OP_AND,
                                                   (self.query, type_query,))

        try:
            results = self.searcher.search(self.query, 0,
                self.searcher.get_doccount())
        except:
            results = []

        results = filter(self.authorized, results)

        return results
Example #12
0
def filterFields(context, form_fields):
    omit_names = []
    if IAlchemistContent.providedBy(context):
        md = utils.get_descriptor(context.__class__)
        for field in form_fields:
            # field:zope.formlib.form.FormField
            try:
                can_write = security.canWrite(context, field.__name__)
                can_read = security.canAccess(context, field.__name__)
            except AttributeError:
                log.warn('filterFields: item [%s] has no field named "%s"', context, field.__name__)
                can_write = can_read = False
            if can_write:
                continue
            if can_read:
                field.for_display = True
                field.custom_widget = md.get(field.__name__).view_widget
            else:
                omit_names.append(field.__name__)
    elif not IAlchemistContainer.providedBy(context):
        ctx = getattr(context, "context", None)
        if ctx:
            filterFields(ctx, form_fields)
        else:
            raise NotImplementedError
    return form_fields.omit(*omit_names)
Example #13
0
 def getMenuItems(self, context, request):
     results = []
     unproxied = proxy.removeSecurityProxy(context.__parent__)
     try:
         items = unproxied.items()
     except AttributeError:
         items = []
         for key, info in capi.iter_type_info():
             if IScheduleContent.implementedBy(info.domain_model):
                 name = naming.plural(key)
                 if hasattr(unproxied, name):
                     items.append((name, getattr(unproxied, name)))
     for key, item in items:
         if not IAlchemistContainer.providedBy(item): continue
         if not IScheduleContent.implementedBy(item.domain_model): continue
         type_info = capi.get_type_info(item.domain_model)
         permission = "bungeni.%s.Add" % (
             type_info.workflow_key
             or naming.type_key("model_name", item.domain_model.__name__))
         if not checkPermission(permission, context): continue
         dc_adapter = IDCDescriptiveProperties(item, None)
         if dc_adapter:
             _title = dc_adapter.title
         else:
             _title = getattr(item, "title", "Unknown")
         results.append(
             dict(title=_title,
                  description=_title,
                  action=url.absoluteURL(item, request),
                  selected=False,
                  icon=None,
                  extra={},
                  submenu=None))
     return results
Example #14
0
 def domain_model(self):
     unproxied = removeSecurityProxy(self.context)
     if IAlchemistContainer.providedBy(unproxied):
         return unproxied.domain_model
     elif IAlchemistContent.providedBy(unproxied):
         return unproxied.__class__
     else:
         raise AttributeError("Could not find domain model for context: %s", unproxied)
Example #15
0
def obj2dict(obj, depth, parent=None, include=[], exclude=[]):
    """ Returns dictionary representation of an object.
    """
    result = {}
    obj = removeSecurityProxy(obj)
    
    # Get additional attributes
    for name in include:
        value = getattr(obj, name, None)
        if value is None:
            continue
        if not name.endswith("s"):
            name += "s"
        if isinstance(value, collections.Iterable):
            res = []
            # !+ allowance for non-container-api-conformant alchemist containers
            if IAlchemistContainer.providedBy(value):
                value = value.values()
            for item in value:
                i = obj2dict(item, 0)
                if name == "versions":
                    permissions = get_head_object_state_rpm(item).permissions
                    i["permissions"] = get_permissions_dict(permissions)
                res.append(i)
            result[name] = res
        else:
            result[name] = value
    
    # Get mapped attributes
    for property in class_mapper(obj.__class__).iterate_properties:
        if property.key in exclude:
            continue
        value = getattr(obj, property.key)
        if value == parent:
            continue
        if value is None:
            continue
        
        if isinstance(property, RelationshipProperty) and depth > 0:
            if isinstance(value, collections.Iterable):
                result[property.key] = []
                for item in value:
                    result[property.key].append(obj2dict(item, depth-1, 
                            parent=obj,
                            include=[],
                            exclude=exclude + ["changes"]
                    ))
            else:
                result[property.key] = obj2dict(value, depth-1, 
                    parent=obj,
                    include=[],
                    exclude=exclude + ["changes"]
                )
        else:
            if isinstance(property, RelationshipProperty):
                continue
            result[property.key] = value
    return result
Example #16
0
 def domain_model(self):
     unproxied = removeSecurityProxy(self.context)
     if IAlchemistContainer.providedBy(unproxied):
         return unproxied.domain_model
     elif IAlchemistContent.providedBy(unproxied):
         return unproxied.__class__
     else:
         raise AttributeError("Could not find domain model for context: %s",
                              unproxied)
Example #17
0
 def generate_tree(root, context):
     for element in root.getiterator():
         typ = get_attr(element, "type")
         src = get_attr(element, "source")
         if typ:
             if typ=="text":
                 clean_element(element)
                 element.text = get_element_value(context, src)
             elif typ=="link":
                 clean_element(element)
                 url_source = get_attr(element, "url")
                 if url_source:
                     link_url = get_element_value(context, url_source)
                 else:
                     link_url = url.absoluteURL(context, 
                         common.get_request()
                     )
                 element.attrib["href"] = link_url
                 if src:
                     element.text = get_element_value(context, src)
             elif typ=="html":
                 clean_element(element)
                 _html = u"<div>%s</div>" % get_element_value(context, 
                     src
                 )
                 new_html = element.insert(0, etree.fromstring(_html))
             elif typ=="listing":
                 listing = get_element_value(context, src, default=[])
                 
                 if IAlchemistContainer.providedBy(listing):
                     _listing = common.list_container_items(listing)
                     listing = [ item for item in _listing ]
                 
                 log.debug("[LISTING] %s @@ %s", src, listing)
                 listing_count = len(listing)
                 new_children = [
                     deepcopy(element.getchildren()) 
                     for x in range(listing_count) 
                 ]
                 empty_element(element)
                 clean_element(element)
                 
                 if listing_count == 0:
                     parent = element.getparent()
                     no_items_element = etree.SubElement(element, "p")
                     no_items_element.text = translate_i18n(
                         _(u"No items found")
                     )
                 else:
                     for (index, item) in enumerate(listing):
                         for child in new_children[index]:
                             generate_tree(child, item)
                     for children in new_children:
                         for descendant in children:
                             element.append(descendant)
                 break
     return etree.tostring(root)
Example #18
0
        def generate_tree(root, context):
            for element in root.getiterator():
                typ = get_attr(element, "type")
                src = get_attr(element, "source")
                if typ:
                    if typ == "text":
                        clean_element(element)
                        element.text = get_element_value(context, src)
                    elif typ == "link":
                        clean_element(element)
                        url_source = get_attr(element, "url")
                        if url_source:
                            link_url = get_element_value(context, url_source)
                        else:
                            link_url = url.absoluteURL(context,
                                                       common.get_request())
                        element.attrib["href"] = link_url
                        if src:
                            element.text = get_element_value(context, src)
                    elif typ == "html":
                        clean_element(element)
                        _html = u"<div>%s</div>" % get_element_value(
                            context, src)
                        new_html = element.insert(0, etree.fromstring(_html))
                    elif typ == "listing":
                        listing = get_element_value(context, src, default=[])

                        if IAlchemistContainer.providedBy(listing):
                            _listing = common.list_container_items(listing)
                            listing = [item for item in _listing]

                        log.debug("[LISTING] %s @@ %s", src, listing)
                        listing_count = len(listing)
                        new_children = [
                            deepcopy(element.getchildren())
                            for x in range(listing_count)
                        ]
                        empty_element(element)
                        clean_element(element)

                        if listing_count == 0:
                            parent = element.getparent()
                            no_items_element = etree.SubElement(element, "p")
                            no_items_element.text = translate_i18n(
                                _(u"No items found"))
                        else:
                            for (index, item) in enumerate(listing):
                                for child in new_children[index]:
                                    generate_tree(child, item)
                            for children in new_children:
                                for descendant in children:
                                    element.append(descendant)
                        break
            return etree.tostring(root)
Example #19
0
 def __call__(self, context):
     if IAlchemistContent.providedBy(context):
         ctx = context
     elif  IAlchemistContainer.providedBy(context):
         domain_model = removeSecurityProxy(context.domain_model)
         ctx = domain_model()
     workflow = interfaces.IWorkflow(ctx)
     items = []
     for status in workflow.states.keys():
         items.append(SimpleTerm(status, status, 
             _(workflow.get_state(status).title)))
     return SimpleVocabulary(items)
Example #20
0
    def expand_containers(self,
                          items,
                          containers,
                          _url,
                          chain=(),
                          context=None):
        #seen_context = False
        _url = _url.rstrip("/")
        current = False

        for key, container in containers:
            assert IAlchemistContainer.providedBy(container)
            label = container.domain_model.__name__
            descriptor = utils.get_descriptor(container.domain_model)
            order = 999
            if descriptor:
                order = descriptor.order
                label = getattr(descriptor, "container_name", None) or \
                    getattr(descriptor, "display_name", None)

            if context is not None:
                current = container.__name__ == context.__name__
            selected = not len(chain) and current
            if current:
                #seen_context = True
                nodes = self.expand(chain)
            else:
                nodes = ()

            key_url = "%s/%s" % (_url, key)
            items.append({
                "id":
                self.get_nav_entry_id(key_url),
                "order":
                order,
                "label":
                translate(
                    label,
                    target_language=get_request_language(request=self.request),
                    domain="bungeni"),
                "url":
                key_url,
                "current":
                current,
                "selected":
                selected,
                "kind":
                "container",
                "nodes":
                nodes,
            })
        items.sort(key=lambda item: (item['order'], item['label']))
Example #21
0
def get_group_for_context(context):
    """Return the "main" (as meaning of this for type) group for this context,
    or None if no such logical group can be determined.
    
    The group may be None if:
    - context is a user who is not a member of any group within any chamber
    - context is a core.interfaces.ISection or workspace Container, for which
      there is no "contextual" chamber is defined in the traversal hierarchy
    - context is an IAlchemistContainer that is not hierarchically contained
      within an IBungeniContent (no such instance in its __parent__ ancestry)
    
    !+ should this be shipped out as a domain_model.group property, or 
    interfaces organized in "how group is determined" categories?
    """
    group = None
    if interfaces.IGroup.providedBy(context):
        group = context
    elif interfaces.IEvent.providedBy(context):
        group = context.group or context.head.group
    elif (interfaces.IDoc.providedBy(context) or 
            interfaces.IGroupMember.providedBy(context) or
            interfaces.IGroupAddress.providedBy(context) or
            interfaces.ISitting.providedBy(context) or
            interfaces.ITitleType.providedBy(context) or
            interfaces.IEditorialNote.providedBy(context) or
            interfaces.IHeading.providedBy(context)
        ):
        group = context.group
    elif (IAlchemistContainer.providedBy(context) or
            ISection.providedBy(context) # !+group ALWAYS None?
        ):
        group = get_group_for_context(context.__parent__)
    elif (interfaces.IAttachment.providedBy(context) or
            interfaces.ISignatory.providedBy(context)
        ):
        group = context.head.group
    elif (interfaces.IMemberTitle.providedBy(context) or
            interfaces.IMemberRole.providedBy(context)
        ):
        group = context.member.group
    elif (interfaces.IDebateRecord.providedBy(context) or
            interfaces.ISittingAttendance.providedBy(context)
        ):
        group = context.sitting.group
    if group is None:
        #from bungeni.utils import probing
        #log.warn(probing.interfaces(context))
        log.warn("!+GROUP_FOR_CONTEXT Cannot determine group for context: %s", context)
        #raise ValueError, "No group for context: %s" % (context)
    return group
Example #22
0
 def expand_containers(self, items, containers, _url, chain=(), context=None):
     #seen_context = False
     _url = _url.rstrip("/")
     current = False
     
     for key, container in containers:
         assert IAlchemistContainer.providedBy(container)
         
         # do not include doc containers for docs who do not specifically 
         # declare the parent group instance as a workspace.group_name
         if IDoc.implementedBy(container.domain_model):
             group = get_group_for_context(container)
             assert IGroup.providedBy(group)
             doc_type_key = naming.polymorphic_identity(container.domain_model)
             if not group.is_type_workspaced(doc_type_key):
                 continue
         
         label = container.domain_model.__name__
         descriptor = utils.get_descriptor(container.domain_model)
         order = 999
         if descriptor:
             order = descriptor.order
             label = getattr(descriptor, "container_name", None) or \
                 getattr(descriptor, "display_name", None)
         
         if context is not None:
             current = container.__name__ == context.__name__
         selected = not len(chain) and current
         if current:
             #seen_context = True
             nodes = self.expand(chain)
         else:
             nodes = ()
         
         key_url = "%s/%s" % (_url, key)
         items.append({
                 "id": self.get_nav_entry_id(key_url),
                 "order": order,
                 "label": translate(label, 
                     target_language=get_default_language(),
                     domain="bungeni"),
                 "url": key_url,
                 "current": current,
                 "selected": selected,
                 "kind": "container",
                 "nodes": nodes,
             })
     items.sort(key=lambda item:(item['order'], item['label']))
Example #23
0
    def form_name(self):
        parent = self.context.__parent__
        if IAlchemistContainer.providedBy(parent):
            descriptor = queryModelDescriptor(parent.domain_model)
        elif IAlchemistContent.providedBy(self.context):
            descriptor = queryModelDescriptor(self.context.__class__)
        else:
            raise RuntimeError("Unsupported object: %s." % repr(self.context))

        if descriptor:
            name = getattr(descriptor, "display_name", None)

        if name is None:
            name = self.context.__class__.__name__

        return name
Example #24
0
    def form_name(self):
        parent = self.context.__parent__
        if IAlchemistContainer.providedBy(parent):
            descriptor = queryModelDescriptor(parent.domain_model)
        elif IAlchemistContent.providedBy(self.context):
            descriptor = queryModelDescriptor(self.context.__class__)
        else:
            raise RuntimeError("Unsupported object: %s." % repr(self.context))

        if descriptor:
            name = getattr(descriptor, "display_name", None)

        if name is None:
            name = self.context.__class__.__name__

        return name
Example #25
0
 def getter(item_user, formatter):
     related_user = _get_related_user(item_user, related_user_attribute_name)
     request = common.get_request()
     # !+ replace with: bungeni.ui.widgets._render_link_to_mp_or_user ?
     if IAdminSectionLayer.providedBy(request):
         # under admin, we link to the natural "view" of the schema relation
         parent = item_user
         while parent and not IAlchemistContainer.providedBy(parent):
             parent = removeSecurityProxy(parent.__parent__)
         item_user.__parent__ = parent
         href = url.absoluteURL(item_user, request)
     else:
         return related_user.combined_name
     return zope.formlib.widget.renderElement("a",
         contents=related_user.combined_name,  # User.combined_name derived property
         href=href
     )
Example #26
0
    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
Example #27
0
    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
Example #28
0
    def expand_containers(self,
                          items,
                          containers,
                          _url,
                          chain=(),
                          context=None):
        #seen_context = False
        current = False

        for key, container in containers:
            if IAlchemistContainer.providedBy(container):
                descriptor = queryModelDescriptor(
                    proxy.removeSecurityProxy(container).domain_model)
                if descriptor:
                    name = getattr(descriptor, "container_name", None)
                    if name is None:
                        name = getattr(descriptor, "display_name", None)

                if not name:
                    name = container.domain_model.__name__
            else:
                assert IDCDescriptiveProperties.providedBy(container)
                container = proxy.removeSecurityProxy(container)
                name = container.title

            if context is not None:
                current = container.__name__ == context.__name__

            selected = len(chain) == 0 and current

            if current:
                #seen_context = True
                nodes = self.expand(chain)
            else:
                nodes = ()

            items.append({
                "title": name,
                "url": "%s/%s" % (_url.rstrip("/"), key),
                "current": current,
                "selected": selected,
                "kind": "container",
                "nodes": nodes,
            })
Example #29
0
    def expand_containers(self,
                          items,
                          containers,
                          _url,
                          chain=(),
                          context=None):
        #seen_context = False
        current = False

        for key, container in containers:
            if IAlchemistContainer.providedBy(container):
                descriptor = queryModelDescriptor(
                    proxy.removeSecurityProxy(container).domain_model)
                if descriptor:
                    name = getattr(descriptor, 'container_name', None)
                    if name is None:
                        name = getattr(descriptor, 'display_name', None)

                if not name:
                    name = container.domain_model.__name__
            else:
                assert IDCDescriptiveProperties.providedBy(container)
                container = proxy.removeSecurityProxy(container)
                name = container.title

            if context is not None:
                current = container.__name__ == context.__name__

            selected = len(chain) == 0 and current

            if current:
                #seen_context = True
                nodes = self.expand(chain)
            else:
                nodes = ()

            items.append({
                'title': name,
                'url': "%s/%s" % (_url.rstrip('/'), key),
                'current': current,
                'selected': selected,
                'kind': 'container',
                'nodes': nodes,
            })
Example #30
0
 def getter(item_user, formatter):
     related_user = _get_related_user(item_user,
                                      related_user_attribute_name)
     request = common.get_request()
     # !+ replace with: bungeni.ui.widgets._render_link_to_mp_or_user ?
     if IAdminSectionLayer.providedBy(request):
         # under admin, we link to the natural "view" of the schema relation
         parent = item_user
         while parent and not IAlchemistContainer.providedBy(parent):
             parent = removeSecurityProxy(parent.__parent__)
         item_user.__parent__ = parent
         href = url.absoluteURL(item_user, request)
     else:
         return related_user.combined_name
     return zope.formlib.widget.renderElement(
         "a",
         contents=related_user.
         combined_name,  # User.combined_name derived property
         href=href)
Example #31
0
def cascade_modifications(obj):
    """Cascade modify events on an object to the direct parent.
    !+NAMING(mr, nov-2012) why cascade (implies down?!) instead of bubble (up, usually)?
    Plus, we are not cascading *modifications* anyway, we are just notifying of such... !
    !+EVENT_CONSUMER_ISSUE(mr, nov-2012) why fire new events off the ancestor if 
    the descendent has presumably already fired off its own modified event? 
    If anything it should be a new specialized type of event, with a pointer to 
    the original trigger object (descendent that was modified), so that the 
    consumer can know it is a "derived" event and maybe act accordingly... as
    it is, all modified event handlers registerd will execute, e.g. auditing of 
    the change if the ancestor is auditable, but the change had already been 
    audited on the originator modified descendent object.
    """
    if not ILocation.providedBy(obj):
        return
    if IAlchemistContainer.providedBy(obj.__parent__):
        if IAlchemistContent.providedBy(obj.__parent__.__parent__):
            notify(ObjectModifiedEvent(obj.__parent__.__parent__))
    elif IAlchemistContent.providedBy(obj.__parent__):
        notify(ObjectModifiedEvent(obj.__parent__))
Example #32
0
 def getter(item_user, formatter):
     related_user = _get_related_user(item_user, related_user_attribute_name)
     request = common.get_request()
     # !+ replace with: bungeni.ui.widgets._render_link_to_mp_or_user ?
     if IAdminSectionLayer.providedBy(request):
         # under admin, we link to the natural "view" of the schema relation
         parent = item_user
         while parent and not IAlchemistContainer.providedBy(parent):
             parent = removeSecurityProxy(parent.__parent__)
         item_user.__parent__ = parent
         href = url.absoluteURL(item_user, request)
     else:
         #!+BUSINESS(mb, feb-2013) is deprecated
         # else we link direct to the MP's "public" view
         # mp = get_member_of_parliament(related_user.user_id)
         # href = "/members/current/obj-%s/" % (mp.membership_id)
         return related_user.combined_name
     return zope.formlib.widget.renderElement(
         "a", contents=related_user.combined_name, href=href  # User.combined_name derived property
     )
Example #33
0
def cascade_modifications(obj):
    """Cascade modify events on an object to the direct parent.
    !+NAMING(mr, nov-2012) why cascade (implies down?!) instead of bubble (up, usually)?
    Plus, we are not cascading *modifications* anyway, we are just notifying of such... !
    !+EVENT_CONSUMER_ISSUE(mr, nov-2012) why fire new events off the ancestor if 
    the descendent has presumably already fired off its own modified event? 
    If anything it should be a new specialized type of event, with a pointer to 
    the original trigger object (descendent that was modified), so that the 
    consumer can know it is a "derived" event and maybe act accordingly... as
    it is, all modified event handlers registerd will execute, e.g. auditing of 
    the change if the ancestor is auditable, but the change had already been 
    audited on the originator modified descendent object.
    """
    if not ILocation.providedBy(obj):
        return
    if IAlchemistContainer.providedBy(obj.__parent__):
        if IAlchemistContent.providedBy(obj.__parent__.__parent__):
            notify(ObjectModifiedEvent(obj.__parent__.__parent__))
    elif IAlchemistContent.providedBy(obj.__parent__):
        notify(ObjectModifiedEvent(obj.__parent__))
Example #34
0
 def getMenuItems(self, context, request):
     results = []
     unproxied = proxy.removeSecurityProxy(context.__parent__)
     items = []
     for key, info in capi.iter_type_info():
         if IScheduleContent.implementedBy(info.domain_model):
             name = naming.plural(key)
             traverser = component.getMultiAdapter((unproxied, request),
                 IPublishTraverse)
             try:
                 item = traverser.publishTraverse(request, name)
                 items.append((name, item))
             except NotFound:
                 continue
     for key, item in items:
         if not IAlchemistContainer.providedBy(item):
             continue
         if not IScheduleContent.implementedBy(item.domain_model):
             continue
         type_info = capi.get_type_info(item.domain_model)
         permission = "bungeni.%s.Add" % (
             type_info.workflow_key or 
             naming.type_key("model_name", item.domain_model.__name__)
         )
         if not checkPermission(permission, context):
             continue
         dc_adapter = IDCDescriptiveProperties(item, None)
         if dc_adapter:
             _title = dc_adapter.title
         else:
             _title = getattr(item, "title", "Unknown")
         results.append(dict(
             title=_title,
             description=_title,
             action = url.absoluteURL(item, request),
             selected=False,
             icon=None,
             extra={"id": "nav_calendar_content_%s" % key},
             submenu=None,
         ))
     return results
Example #35
0
 def getMenuItems(self, context, request):
     results = []
     unproxied = proxy.removeSecurityProxy(context.__parent__)
     items = []
     for key, info in capi.iter_type_info():
         if IScheduleContent.implementedBy(info.domain_model):
             name = naming.plural(key)
             traverser = component.getMultiAdapter((unproxied, request),
                                                   IPublishTraverse)
             try:
                 item = traverser.publishTraverse(request, name)
                 items.append((name, item))
             except NotFound:
                 continue
     for key, item in items:
         if not IAlchemistContainer.providedBy(item):
             continue
         if not IScheduleContent.implementedBy(item.domain_model):
             continue
         type_info = capi.get_type_info(item.domain_model)
         permission = "bungeni.%s.Add" % (
             type_info.workflow_key
             or naming.type_key("model_name", item.domain_model.__name__))
         if not checkPermission(permission, context):
             continue
         dc_adapter = IDCDescriptiveProperties(item, None)
         if dc_adapter:
             _title = dc_adapter.title
         else:
             _title = getattr(item, "title", "Unknown")
         results.append(
             dict(
                 title=_title,
                 description=_title,
                 action=url.absoluteURL(item, request),
                 selected=False,
                 icon=None,
                 extra={"id": "nav_calendar_content_%s" % key},
                 submenu=None,
             ))
     return results
Example #36
0
    def form_name(self):
        parent = self.context.__parent__
        # DESCRIPTOR(miano, June 2011) This originally first checked the parent's
        # descriptor then the item's descriptor. Why???
        # This was causing an error in the display pages of items in the
        # workspace since the workspace containers have no descriptor
        # defined for them.
        if IAlchemistContent.providedBy(self.context):
            descriptor = utils.get_descriptor(self.context.__class__)
        elif IAlchemistContainer.providedBy(parent):
            descriptor = utils.get_descriptor(parent.domain_model)
        else:
            raise RuntimeError("Unsupported object: %s." % repr(self.context))

        if descriptor:
            name = getattr(descriptor, "display_name", None)

        if name is None:
            name = self.context.__class__.__name__

        return name
Example #37
0
    def form_name(self):
        parent = self.context.__parent__
        #DESCRIPTOR(miano, June 2011) This originally first checked the parent's
        #descriptor then the item's descriptor. Why???
        #This was causing an error in the display pages of items in the
        #workspace since the workspace containers have no descriptor
        #defined for them.
        if IAlchemistContent.providedBy(self.context):
            descriptor = queryModelDescriptor(self.context.__class__)
        elif IAlchemistContainer.providedBy(parent):
            descriptor = queryModelDescriptor(parent.domain_model)
        else:
            raise RuntimeError("Unsupported object: %s." % repr(self.context))

        if descriptor:
            name = getattr(descriptor, "display_name", None)

        if name is None:
            name = self.context.__class__.__name__

        return name
Example #38
0
 def getter(item_user, formatter):
     related_user = _get_related_user(item_user, related_user_attribute_name)
     request = common.get_request()
     # !+ replace with: bungeni.ui.widgets._render_link_to_mp_or_user ?
     if IAdminSectionLayer.providedBy(request):
         # under admin, we link to the natural "view" of the schema relation
         parent = item_user
         while parent and not IAlchemistContainer.providedBy(parent):
             parent = removeSecurityProxy(parent.__parent__)
         item_user.__parent__ = parent
         href = url.absoluteURL(item_user, request)
     else:
         #!+BUSINESS(mb, feb-2013) is deprecated
         # else we link direct to the MP's "public" view
         #mp = get_member_of_parliament(related_user.user_id)
         #href = "/members/current/obj-%s/" % (mp.membership_id)
         return related_user.combined_name
     return zope.formlib.widget.renderElement("a",
         contents=related_user.combined_name,  # User.combined_name derived property
         href=href
     )
Example #39
0
    def expand_containers(self, items, containers, _url, chain=(), context=None):
        # seen_context = False
        current = False

        for key, container in containers:
            if IAlchemistContainer.providedBy(container):
                descriptor = queryModelDescriptor(proxy.removeSecurityProxy(container).domain_model)
                if descriptor:
                    name = getattr(descriptor, "container_name", None)
                    if name is None:
                        name = getattr(descriptor, "display_name", None)

                if not name:
                    name = container.domain_model.__name__
            else:
                assert IDCDescriptiveProperties.providedBy(container)
                container = proxy.removeSecurityProxy(container)
                name = container.title

            if context is not None:
                current = container.__name__ == context.__name__

            selected = len(chain) == 0 and current

            if current:
                # seen_context = True
                nodes = self.expand(chain)
            else:
                nodes = ()

            items.append(
                {
                    "title": name,
                    "url": "%s/%s" % (_url.rstrip("/"), key),
                    "current": current,
                    "selected": selected,
                    "kind": "container",
                    "nodes": nodes,
                }
            )
Example #40
0
    def expand_containers(self, items, containers, _url, chain=(), context=None):
        #seen_context = False
        current = False
        
        for key, container in containers:
            if IAlchemistContainer.providedBy(container):
                descriptor = queryModelDescriptor(
                    proxy.removeSecurityProxy(container).domain_model)
                if descriptor:
                    name = getattr(descriptor, 'container_name', None)
                    if name is None:
                        name = getattr(descriptor, 'display_name', None)
                        
                if not name:
                    name = container.domain_model.__name__
            else:
                assert IDCDescriptiveProperties.providedBy(container)
                container = proxy.removeSecurityProxy(container)
                name = container.title

            if context is not None:
                current = container.__name__ == context.__name__

            selected = len(chain) == 0 and current

            if current:
                #seen_context = True
                nodes = self.expand(chain)
            else:
                nodes = ()

            items.append(
                {'title': name,
                 'url': "%s/%s" % (_url.rstrip('/'), key),
                 'current': current,
                 'selected': selected,
                 'kind': 'container',
                 'nodes': nodes,
                 })
Example #41
0
 def getMenuItems(self, context, request):
     results = []
     try:
         items = proxy.removeSecurityProxy(context.__parent__).items()
     except AttributeError:
         return results
     for key, item in items:
         if not IAlchemistContainer.providedBy(item): continue
         if not IScheduleText.implementedBy(item.domain_model): continue
         dc_adapter = IDCDescriptiveProperties(item, None)
         if dc_adapter:
             _title = dc_adapter.title
         else:
             _title = getattr(item, "title", "Unknown")
         results.append(
             dict(title=_title,
                  description=_title,
                  action=url.absoluteURL(item, request),
                  selected=False,
                  icon=None,
                  extra={},
                  submenu=None))
     return results
Example #42
0
 def getMenuItems(self, context, request):
     results = []
     unproxied = proxy.removeSecurityProxy(context.__parent__)
     try:
         items = unproxied.items()
     except AttributeError:
         items = []
         for key, info in capi.iter_type_info():
             if IScheduleContent.implementedBy(info.domain_model):
                 name = naming.plural(key)
                 if hasattr(unproxied, name):
                     items.append((name, getattr(unproxied, name)))
     for key, item in items:
         if not IAlchemistContainer.providedBy(item): continue
         if not IScheduleContent.implementedBy(item.domain_model): continue
         type_info = capi.get_type_info(item.domain_model)
         permission = "bungeni.%s.Add" % (
             type_info.workflow_key or 
             naming.type_key("model_name", item.domain_model.__name__)
         )
         if not checkPermission(permission, context): continue
         dc_adapter = IDCDescriptiveProperties(item, None)
         if dc_adapter:
             _title = dc_adapter.title
         else:
             _title = getattr(item, "title", "Unknown")
         results.append(dict(
             title=_title,
             description=_title,
             action = url.absoluteURL(item, request),
             selected=False,
             icon=None,
             extra={},
             submenu=None
             
         ))
     return results
Example #43
0
def _get_title_from_context(context):
    title = None
    if IAlchemistContent.providedBy(context):
        if IDCDescriptiveProperties.providedBy(context):
            title = context.title
        else:
            props = IDCDescriptiveProperties(context, None)
            if props is not None:
                title = props.title
            else:
                ''' !+
AttributeError: 'GroupAddress' object has no attribute 'short_name':   File "/home/undesa/bungeni/cap_installs/bungeni_install/bungeni/releases/20100305100101/src/bungeni.main/bungeni/ui/viewlets/navigation.py", line 59, in _get_title_from_context
                #title = context.short_name 
So, we temporarily default the above to the context.__class__.__name__:
                '''
                title = getattr(context, "title", context.__class__.__name__)
    elif IWorkspaceContainer.providedBy(context):
        # WorkspaceContainer._class is not set (and not unique) and it breaks the
        # connection between Container -> ContentClass
        title = context.__name__
    elif IAlchemistContainer.providedBy(context):
        domain_model = context._class 
        try:
            descriptor = utils.get_descriptor(domain_model)
        except KeyError, e:
            log.warn("TYPE_INFO: no descriptor for model %s "
                    "[container=%s] [error=%s]" % (
                        domain_model, context, e))
            descriptor = None
            name = ""
        if descriptor:
            name = getattr(descriptor, "container_name", None)
            if name is None:
                name = getattr(descriptor, "display_name", None)
        if not name:
            name = getattr(context, "__name__", None)
        title = name
Example #44
0
def filterFields(context, form_fields):
    omit_names = []
    if IAlchemistContent.providedBy(context):
        md = queryModelDescriptor(context.__class__)
        for field in form_fields:
            try:
                can_write = security.canWrite(context, field.__name__)
                can_read = security.canAccess(context, field.__name__)
            except AttributeError:
                can_write = can_read = False
            if can_write:
                continue
            if can_read:
                field.for_display = True
                field.custom_widget = md.get(field.__name__).view_widget
            else:
                omit_names.append(field.__name__)
    elif not IAlchemistContainer.providedBy(context):
        ctx = getattr(context, "context", None)
        if ctx:
            filterFields(ctx, form_fields)
        else:
            raise NotImplementedError
    return form_fields.omit(*omit_names)
Example #45
0
def filterFields(context, form_fields):
    omit_names = []
    if IAlchemistContent.providedBy(context):
        md = queryModelDescriptor(context.__class__)
        for field in form_fields:
            try:
                can_write = security.canWrite(context, field.__name__)
                can_read = security.canAccess(context, field.__name__)
            except AttributeError:
                can_write = can_read = False
            if can_write:
                continue
            if can_read:
                field.for_display = True
                field.custom_widget = md.get(field.__name__).view_widget
            else:
                omit_names.append(field.__name__)
    elif not IAlchemistContainer.providedBy(context):
        ctx = getattr(context, "context", None)
        if ctx:
            filterFields(ctx, form_fields)
        else:
            raise NotImplementedError
    return form_fields.omit(*omit_names)
Example #46
0
    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
Example #47
0
def obj2dict(obj, depth, parent=None, include=[], exclude=[], lang=None, root_key=None):
    """ Returns dictionary representation of a domain object.
    """
    if lang is None:
        lang = getattr(obj, "language", capi.default_language)
    result = {}
    obj = zope.security.proxy.removeSecurityProxy(obj)
    descriptor = None
    if IAlchemistContent.providedBy(obj):
        try:
            descriptor = utils.get_descriptor(obj)
        except KeyError:
            log.error("Could not get descriptor for IAlchemistContent %r", obj)
        
        if parent is not None and IWorkflowed.providedBy(obj):
            permissions = get_object_state_rpm(obj).permissions
            result["permissions"] = get_permissions_dict(permissions)
            result["tags"] = IStateController(obj).get_state().tags
        
    # Get additional attributes
    for name in include:
        value = getattr(obj, name, None)
        if value is None:
            continue
        if not name.endswith("s"):
            name += "s"
        if isinstance(value, collections.Iterable):
            res = []
            # !+ allowance for non-container-api-conformant alchemist containers
            if IAlchemistContainer.providedBy(value):
                value = value.values()
            for item in value:
                i = obj2dict(item, 0, lang=lang, root_key=root_key)
                res.append(i)
            result[name] = res
        else:
            result[name] = value
    
    # Get mapped attributes
    mapper = class_mapper(obj.__class__)
    for property in mapper.iterate_properties:
        if property.key in exclude:
            continue
        value = getattr(obj, property.key)
        if value == parent:
            continue
        if value is None:
            continue
        
        if isinstance(property, RelationshipProperty) and depth > 0:
            if isinstance(value, collections.Iterable):
                result[property.key] = []
                for item in value:
                    result[property.key].append(obj2dict(item, 1, 
                            parent=obj,
                            include=[],
                            exclude=exclude + INNER_EXCLUDES,
                            lang=lang,
                            root_key=root_key
                    ))
            else:
                result[property.key] = obj2dict(value, depth-1, 
                    parent=obj,
                    include=[],
                    exclude=exclude + INNER_EXCLUDES,
                    lang=lang,
                    root_key=root_key
                )
        else:
            if isinstance(property, RelationshipProperty):
                continue
            elif isinstance(property, ColumnProperty):
                columns = property.columns
                if len(columns) == 1:
                    if is_column_binary(columns[0]):
                        if (parent and 
                            interfaces.ISerializable.providedBy(obj)):
                            #skip serialization of binary fields
                            #that have already been serialized elsewhere
                            continue
                        #save files
                        result[columns[0].key] = dict(
                            saved_file=PersistFiles.store_file(
                                obj, columns[0], root_key
                            )
                        )
                        continue
            if descriptor:
                columns = property.columns
                is_foreign = False
                if len(columns) == 1:
                    if len(columns[0].foreign_keys):
                        is_foreign = True
                if (not is_foreign) and (property.key in descriptor.keys()):
                    field = descriptor.get(property.key)
                    if (field and field.property and
                        (schema.interfaces.IChoice.providedBy(field.property)
                            or IVocabularyTextField.providedBy(field.property))
                        ):
                                factory = (field.property.vocabulary or 
                                    field.property.source
                                )
                                if factory is None:
                                    vocab_name = getattr(field.property, 
                                        "vocabularyName", None)
                                    factory = zope.component.getUtility(
                                        schema.interfaces.IVocabularyFactory,
                                        vocab_name
                                    )
                                # !+VOCABULARIES(mb, aug-2012)some vocabularies
                                # expect an interaction to generate values
                                # todo - update these vocabularies to work 
                                # with no request e.g. in notification threads
                                display_name = None
                                try:
                                    vocabulary = factory(obj)                             
                                    #handle vdex hierarchical terms
                                    if ITreeVocabulary.providedBy(factory):
                                        values = value.splitlines()
                                        term_values = []
                                        for val in values:
                                            term_values.append(dict(
                                                name=property.key,
                                                value=val,
                                                displayAs=factory.vdex.getTermCaption(
                                                    factory.getTermById(val),
                                                    lang
                                                )
                                            ))
                                        result[property.key] = term_values
                                        continue
                                    term = vocabulary.getTerm(value)
                                    if lang:
                                        if hasattr(factory, "vdex"):
                                            display_name = (
                                                factory.vdex.getTermCaption(
                                                factory.getTermById(value), 
                                                lang
                                            ))
                                        else:
                                            display_name = translate(
                                                (term.title or term.value),
                                                target_language=lang,
                                                domain="bungeni"
                                            )
                                    else:
                                        display_name = term.title or term.value
                                except zope.security.interfaces.NoInteraction:
                                    log.error("This vocabulary %s expects an"
                                        "interaction to generate terms.",
                                        factory
                                    )
                                    # try to use dc adapter lookup
                                    try:
                                        _prop = mapper.get_property_by_column(
                                            property.columns[0])
                                        _prop_value = getattr(obj, _prop.key)
                                        dc = IDCDescriptiveProperties(
                                            _prop_value, None)
                                        if dc:
                                            display_name = (
                                                IDCDescriptiveProperties(
                                                    _prop_value).title
                                            )
                                    except KeyError:
                                        log.warn("No display text found for %s" 
                                            " on object %s. Unmapped in orm.",
                                            property.key, obj
                                        )
                                except Exception, e:
                                    log.error("Could not instantiate"
                                        " vocabulary %s. Exception: %s",
                                        factory, e
                                    )
                                finally:
                                    # fallback we cannot look up vocabularies/dc
                                    if display_name is None:
                                        if not isinstance(value, unicode):
                                            display_name = unicode(value)
                                if display_name is not None:
                                    result[property.key] = dict(
                                        name=property.key,
                                        value=value,
                                        displayAs=display_name
                                    )
                                    continue
Example #48
0
    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
Example #49
0
def obj2dict(obj, depth, parent=None, include=[], exclude=[], lang=None, root_key=None):
    """ Returns dictionary representation of a domain object.
    """
    if lang is None:
        lang = getattr(obj, "language", capi.default_language)
    result = {}
    obj = zope.security.proxy.removeSecurityProxy(obj)
    descriptor = None
    if IAlchemistContent.providedBy(obj):
        try:
            descriptor = utils.get_descriptor(obj)
        except KeyError:
            log.error("Could not get descriptor for IAlchemistContent %r", obj)
        
        if parent is not None and IWorkflowed.providedBy(obj):
            permissions = get_object_state_rpm(obj).permissions
            result["permissions"] = get_permissions_dict(permissions)
            result["tags"] = IStateController(obj).get_state().tags
        
    # Get additional attributes
    for name in include:
        value = getattr(obj, name, None)
        if value is None:
            continue
        if not name.endswith("s"):
            name += "s"
        if isinstance(value, collections.Iterable):
            res = []
            # !+ allowance for non-container-api-conformant alchemist containers
            if IAlchemistContainer.providedBy(value):
                value = value.values()
            for item in value:
                i = obj2dict(item, 0, lang=lang, root_key=root_key)
                res.append(i)
            result[name] = res
        else:
            result[name] = value
    
    # Get mapped attributes
    seen_keys = []
    mapper = class_mapper(obj.__class__)
    for mproperty in mapper.iterate_properties:
        if mproperty.key.startswith("_vp"):
            #skip vertical props
            continue
        if mproperty.key in exclude:
            continue
        seen_keys.append(mproperty.key)
        value = getattr(obj, mproperty.key)
        if value == parent:
            continue
        if value is None:
            continue
        
        if isinstance(mproperty, RelationshipProperty) and depth > 0:
            if isinstance(value, collections.Iterable):
                result[mproperty.key] = []
                for item in value:
                    # !+DEPTH(ah, 2014-09-19) depth was set to 1 here, this causes 
                    # a very deep branching for upper level groups like legislature and chamber
                    # and legislature times out occasionally. Doesnt seem neccessary to go depth=1
                    # for child objects, because they get serialized independently anyway, changing
                    # depth to depth-1 so all dependent objects are iterated 1 level lower than the 
                    # parent.
                    # UPDATE(ah, 2014-11-03) Item Schedule is an exceptional case of an object 
                    # whose context is within a parent container but is not visible outside of the sitting
                    # it is not a type defined in types.xml and does not have its own 
                    # wokflow so we need to handle that in a unique way
                    # we don't decrement the depth and instead process it as is 
                    active_depth = depth
                    if item.__class__.__name__ == "ItemSchedule":
                        active_depth = depth
                    else:
                        active_depth = depth-1
                    result[mproperty.key].append(
                         obj2dict(
                            item,
                            active_depth, 
                            parent=obj,
                            include=["owner", "item_schedule", "item_schedule_discussion"],
                            exclude=exclude + INNER_EXCLUDES,
                            lang=lang,
                            root_key=root_key
                         )
                    )
            else:
                result[mproperty.key] = obj2dict(value, depth-1, 
                    parent=obj,
                    include=["owner"],
                    exclude=exclude + INNER_EXCLUDES,
                    lang=lang,
                    root_key=root_key
                )
        else:
            if isinstance(mproperty, RelationshipProperty):
                continue
            elif isinstance(mproperty, ColumnProperty):
                columns = mproperty.columns
                if len(columns) == 1:
                    if is_column_binary(columns[0]):
                        fname = PersistFiles.store_file(obj, parent, 
                            columns[0].key, root_key)
                        if fname:
                            result[columns[0].key] = dict(saved_file=fname)
                        continue
            if descriptor:
                columns = mproperty.columns
                is_foreign = False
                if len(columns) == 1:
                    if len(columns[0].foreign_keys):
                        is_foreign = True
                if (not is_foreign) and (mproperty.key in descriptor.keys()):
                    field = descriptor.get(mproperty.key)
                    if (field and field.property and
                            (schema.interfaces.IChoice.providedBy(field.property) or
                                IVocabularyTextField.providedBy(field.property))
                        ):
                        factory = field.property.vocabulary or field.property.source
                        if factory is None:
                            vocab_name = getattr(field.property, "vocabularyName", None)
                            factory = get_vocabulary(vocab_name)
                        # !+VOCABULARIES(mb, aug-2012)some vocabularies
                        # expect an interaction to generate values
                        # todo - update these vocabularies to work 
                        # with no request e.g. in notification threads
                        display_name = None
                        try:
                            vocabulary = factory(obj)                             
                            # handle vdex hierarchical terms
                            if ITreeVocabulary.providedBy(factory):
                                values = value.splitlines()
                                term_values = []
                                for val in values:
                                    term_values.append(dict(
                                            name=mproperty.key,
                                            value=val,
                                            displayAs=factory.getTermCaption(
                                                factory.getTermById(val), lang=lang)))
                                result[mproperty.key] = term_values
                                continue
                            term = vocabulary.getTerm(value)
                            if lang:
                                if hasattr(factory, "getTermCaption"):
                                    display_name = factory.getTermCaption(
                                            factory.getTermById(value), lang=lang)
                                else:
                                    display_name = translate(
                                        term.title or term.value,
                                        target_language=lang,
                                        domain="bungeni")
                            else:
                                display_name = term.title or term.value
                        except zope.security.interfaces.NoInteraction:
                            log.error("This vocabulary %s expects an interaction "
                                "to generate terms.", factory)
                            # try to use dc adapter lookup
                            try:
                                _prop = mapper.get_property_by_column(
                                    mproperty.columns[0])
                                _prop_value = getattr(obj, _prop.key)
                                dc = IDCDescriptiveProperties(_prop_value, None)
                                if dc:
                                    display_name = IDCDescriptiveProperties(
                                            _prop_value).title
                            except KeyError:
                                log.warn("No display text found for %s on " 
                                    "object %s. Unmapped in orm.",
                                    property.key, obj)
                        except Exception, e:
                            log.error("Could not instantiate vocabulary %s. "
                                "Exception: %s", factory, e)
                        finally:
                            # fallback we cannot look up vocabularies/dc
                            if display_name is None:
                                if not isinstance(value, unicode):
                                    display_name = unicode(value)
                        if display_name is not None:
                            result[mproperty.key] = dict(
                                name=mproperty.key,
                                value=value,
                                displayAs=display_name)
                            continue
Example #50
0
 def process_document_tree(root, context):
     """Iterate and optionally update children of provided root node.
     
     Rendering is based on type of node. Further calls to this function
     happen when a node with children exists - and so on.
     
     Only nodes with the bungeni namespace tags "br:type" are modified
     with content from the provided context.
     """
     cond = get_attr(root, "condition")
     if cond and not check_exists(context, cond):
         return None
     iter_children = root.getchildren() or [root]
     if not (root in iter_children):
         root_typ = get_attr(root, "type")
         if root_typ:
             process_single_node(root, context, root_typ,
                                 get_attr(root, "source"))
     for child in iter_children:
         typ = get_attr(child, "type")
         src = get_attr(child, "source")
         cond = get_attr(child, "condition")
         if cond and not check_exists(context, cond):
             drop_element(child)
             continue
         children = child.getchildren()
         if len(children) == 0:
             if typ:
                 process_single_node(child, context, typ, src)
         else:
             if not typ:
                 process_document_tree(child, context)
             elif typ == "listing":
                 child = clean_element(child)
                 children = child.getchildren()
                 listing = get_element_value(context, src, default=[])
                 if IAlchemistContainer.providedBy(listing):
                     listing = [
                         item for item in common.list_container_items(
                             listing)
                     ]
                 len_listing = len(listing)
                 if not len_listing:
                     add_empty_listing_node(child)
                 else:
                     expanded_children = [
                         deepcopy(children) for x in range(len_listing)
                     ]
                     empty_element(child)
                     for i, item in enumerate(listing):
                         for inner_element in expanded_children[i]:
                             iroot = process_document_tree(
                                 inner_element, item)
                             if iroot is not None:
                                 child.append(iroot)
             elif typ == "block" and src:
                 block_context = get_element_value(context,
                                                   src,
                                                   default=None)
                 process_document_tree(child, block_context)
             else:
                 process_document_tree(child, context)
     return clean_element(root)
Example #51
0
    def getMenuItems(self, context, request):
        results = []
        _url = url.absoluteURL(context, request)
        if IFeatureDownload.providedBy(context):
            doc_templates = self.documentTemplates(request.locale)
            for doc_type in document_types:
                if doc_templates:
                    for template in doc_templates:
                        i18n_title = translate_i18n(globals()["i18n_%s" %
                                                              doc_type])
                        results.append(
                            dict(title="%s [%s]" %
                                 (i18n_title, template.get("title")),
                                 description="",
                                 action="%s/%s?template=%s" %
                                 (_url, doc_type, template.get("location")),
                                 selected=False,
                                 extra={
                                     "id":
                                     "download-%s-%s" %
                                     (doc_type,
                                      misc.slugify(template.get("location"))),
                                     "class":
                                     "download-document"
                                 },
                                 icon=None,
                                 submenu=None))

                else:
                    results.append(
                        dict(title=doc_type,
                             description=doc_type,
                             action="%s/%s" % (_url, doc_type),
                             selected=False,
                             icon=None,
                             extra={},
                             submenu=None))
        if interfaces.IRSSRepresentationLayer.providedBy(request):
            for doc_type in xml_types:
                if doc_type == TYPE_AKOMANTOSO:
                    if IAlchemistContainer.providedBy(context):
                        if not IFeatureDownload.implementedBy(
                                context.domain_model):
                            continue
                elif doc_type == TYPE_RSS:
                    # rss for content types only availble for auditables
                    if (IFeatureDownload.providedBy(context)
                            and not IFeatureAudit.providedBy(context)):
                        continue
                    elif (IAlchemistContainer.providedBy(context)
                          and not IFeatureAudit.implementedBy(
                              context.domain_model)):
                        continue
                results.append(
                    dict(title=globals()["i18n_%s" % doc_type],
                         description="",
                         action="%s/feed.%s" % (_url, doc_type),
                         selected=False,
                         icon=None,
                         extra={"id": "download-%s" % doc_type},
                         submenu=None))
        return results
Example #52
0
    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
Example #53
0
 def getMenuItems(self, context, request):
     results = []
     _url = url.absoluteURL(context, request)
     if IFeatureDownload.providedBy(context):
         doc_templates = self.documentTemplates(request.locale)
         for doc_type in document_types:
             if doc_templates:
                 for template in doc_templates:
                     i18n_title = translate_i18n(globals()["i18n_%s" % doc_type])
                     results.append(dict(
                         title="%s [%s]" % (i18n_title,template.get("title")),
                         description="",
                         action="%s/%s?template=%s" % (_url, doc_type, 
                             template.get("location")),
                         selected=False,
                         extra = {
                             "id": "download-%s-%s" %(doc_type,
                                 misc.slugify(template.get("location"))
                             ),
                             "class": "download-document"
                         },
                         icon=None,
                         submenu=None
                     ))
                 
             else:
                 results.append(dict(
                     title = doc_type,
                     description=doc_type,
                     action = "%s/%s" %(_url, doc_type),
                     selected=False,
                     icon=None,
                     extra={},
                     submenu=None
                 ))
     if interfaces.IRSSRepresentationLayer.providedBy(request):
         for doc_type in xml_types:
             if doc_type == TYPE_AKOMANTOSO:
                 if IAlchemistContainer.providedBy(context):
                     if not IFeatureDownload.implementedBy(
                             context.domain_model
                         ):
                         continue
             elif doc_type == TYPE_RSS:
                 # rss for content types only availble for auditables
                 if (IFeatureDownload.providedBy(context) and not
                         IFeatureAudit.providedBy(context)
                     ):
                     continue
                 elif (IAlchemistContainer.providedBy(context) and not 
                         IFeatureAudit.implementedBy(context.domain_model)
                     ):
                     continue
             results.append(dict(
                     title = globals()["i18n_%s" % doc_type],
                     description="",
                     action = "%s/feed.%s" %(_url, doc_type),
                     selected=False,
                     icon=None,
                     extra={
                         "id": "download-%s" % doc_type
                     },
                     submenu=None
             ))
     return results
Example #54
0
 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