def changedField(field, value, context=None): """Figure if a field's value changed Comparing the value of the context attribute and the given value""" if context is None: context = field.context if context is None: # IObjectWidget madness return True if IObject.providedBy(field): return True # Get the datamanager and get the original value dm = getMultiAdapter( (context, field), IDataManager) # now figure value chaged status # Or we can not get the original value, in which case we can not check # Or it is an Object, in case we'll never know try: test = dm.query() != value if test: return True except TypeError: return True if not dm.canAccess(): return True return False
def getTestimonialFolder(context, request=None): """Returns the testimonials folder located in the "nearest" INavigationRoot. If there is none, return the one located in the plonesite. returns None if no testimonals folder could be found. """ cat = getToolByName(context, 'portal_catalog') if request is None: request = context.REQUEST portal_state = getMultiAdapter((context, request), name=u'plone_portal_state') navigation_root_path = portal_state.navigation_root_path() folders = cat(path=navigation_root_path, object_provides='wm.testimonials.interfaces.ITestimonialFolder') # if no testimonial folder has been found we search within the plonesite # note that this implementation does not support multiple navigationroots within the acquisition chain if len(folders)==0: folders = cat(object_provides='wm.testimonials.interfaces.ITestimonialFolder') if len(folders)==0: return None return folders[0].getObject()
def getTestimonialFolder(context, request=None): """Returns the testimonials folder located in the "nearest" INavigationRoot. If there is none, return the one located in the plonesite. returns None if no testimonals folder could be found. """ cat = getToolByName(context, 'portal_catalog') if request is None: request = context.REQUEST portal_state = getMultiAdapter((context, request), name=u'plone_portal_state') navigation_root_path = portal_state.navigation_root_path() folders = cat( path=navigation_root_path, object_provides='wm.testimonials.interfaces.ITestimonialFolder') # if no testimonial folder has been found we search within the plonesite # note that this implementation does not support multiple navigationroots within the acquisition chain if len(folders) == 0: folders = cat( object_provides='wm.testimonials.interfaces.ITestimonialFolder') if len(folders) == 0: return None return folders[0].getObject()
def addPortletToContext(context, portlet, columnName="plone.rightcolumn"): if not portlet: return column = getUtility(IPortletManager, columnName) manager = getMultiAdapter((context, column), IPortletAssignmentMapping) chooser = INameChooser(manager) manager[chooser.chooseName(None, portlet)] = portlet
def __call__(self): widget = self.context if isinstance(self.context.form, DataGridFieldObjectSubForm): widget.context = self.context.__parent__.context effective_path = widget.request.get('start', None) if not effective_path: effective_path = widget.get_start_path() current_depth = len(effective_path.split('/')) results = self.search_catalog(widget, effective_path) results, batch_html = extend_with_batching(widget, results) selectable_types = get_selectable_types(widget) result = {'batching': batch_html, 'items': [], 'sortOnOptions': get_sort_options(self.request), 'sortOrderOptions': get_sort_order_options(self.request)} plone = getMultiAdapter((self.context, self.request), name="plone") for item in results: depth = len(item.getPath().split('/')) - current_depth if depth == 0: continue contenttype = item.portal_type.replace('.', '-').lower() label = item.Title or item.id label += ' (%s)' % plone.toLocalizedTime(item.start).encode('utf-8') if item.start else '' obj_dict = {'path': item.getPath(), 'id': item.id, 'title': label, 'folderish': item.is_folderish, 'traversable': is_traversable(widget, item), 'selectable': item.portal_type in selectable_types, 'content-type': 'contenttype-' + contenttype} result['items'].append(obj_dict) self.request.RESPONSE.setHeader("Content-type", "application/json") return json.dumps(result)
def changedField(field, value, context=None): """Figure if a field's value changed Comparing the value of the context attribute and the given value""" if context is None: context = field.context if context is None: # IObjectWidget madness return True if IObject.providedBy(field): return True # Get the datamanager and get the original value dm = getMultiAdapter((context, field), IDataManager) # now figure value chaged status # Or we can not get the original value, in which case we can not check # Or it is an Object, in case we'll never know try: test = dm.query() != value if test: return True except TypeError: return True if not dm.canAccess(): return True return False
def folderitems(self, full_objects = False): """ >>> portal = layer['portal'] >>> portal_url = portal.absolute_url() >>> from plone.app.testing import SITE_OWNER_NAME >>> from plone.app.testing import SITE_OWNER_PASSWORD Test page batching https://github.com/bikalabs/Bika-LIMS/issues/1276 When visiting the second page, the Water sampletype should be displayed: >>> browser = layer['getBrowser'](portal, loggedIn=True, username=SITE_OWNER_NAME, password=SITE_OWNER_PASSWORD) >>> browser.open(portal_url+"/bika_setup/bika_sampletypes/folder_view?", ... "list_pagesize=10&list_review_state=default&list_pagenumber=2") >>> browser.contents '...Water...' """ #self.contentsMethod = self.context.getFolderContents if not hasattr(self, 'contentsMethod'): self.contentsMethod = getToolByName(self.context, self.catalog) context = aq_inner(self.context) plone_layout = getMultiAdapter((context, self.request), name = u'plone_layout') plone_utils = getToolByName(context, 'plone_utils') plone_view = getMultiAdapter((context, self.request), name = u'plone') portal_properties = getToolByName(context, 'portal_properties') portal_types = getToolByName(context, 'portal_types') workflow = getToolByName(context, 'portal_workflow') site_properties = portal_properties.site_properties norm = getUtility(IIDNormalizer).normalize if self.request.get('show_all', '').lower() == 'true' \ or self.show_all == True \ or self.pagesize == 0: show_all = True else: show_all = False pagenumber = int(self.request.get('pagenumber', 1) or 1) pagesize = self.pagesize start = (pagenumber - 1) * pagesize end = start + pagesize - 1 if (hasattr(self, 'And') and self.And) \ or (hasattr(self, 'Or') and self.Or): # if contentsMethod is capable, we do an AdvancedQuery. if hasattr(self.contentsMethod, 'makeAdvancedQuery'): aq = self.contentsMethod.makeAdvancedQuery(self.contentFilter) if hasattr(self, 'And') and self.And: tmpAnd = And() for q in self.And: tmpAnd.addSubquery(q) aq &= tmpAnd if hasattr(self, 'Or') and self.Or: tmpOr = Or() for q in self.Or: tmpOr.addSubquery(q) aq &= tmpOr brains = self.contentsMethod.evalAdvancedQuery(aq) else: # otherwise, self.contentsMethod must handle contentFilter brains = self.contentsMethod(self.contentFilter) else: brains = self.contentsMethod(self.contentFilter) results = [] self.page_start_index = 0 current_index = -1 for i, obj in enumerate(brains): # we don't know yet if it's a brain or an object path = hasattr(obj, 'getPath') and obj.getPath() or \ "/".join(obj.getPhysicalPath()) if hasattr(obj, 'getObject'): obj = obj.getObject() # check if the item must be rendered or not (prevents from # doing it later in folderitems) and dealing with paging if not self.isItemAllowed(obj): continue # avoid creating unnecessary info for items outside the current # batch; only the path is needed for the "select all" case... # we only take allowed items into account current_index += 1 if not show_all and not (start <= current_index <= end): results.append(dict(path = path, uid = obj.UID())) continue uid = obj.UID() title = obj.Title() description = obj.Description() icon = plone_layout.getIcon(obj) url = obj.absolute_url() relative_url = obj.absolute_url(relative = True) fti = portal_types.get(obj.portal_type) if fti is not None: type_title_msgid = fti.Title() else: type_title_msgid = obj.portal_type url_href_title = '%s at %s: %s' % ( t(type_title_msgid), path, to_utf8(description)) modified = self.ulocalized_time(obj.modified()), # element css classes type_class = 'contenttype-' + \ plone_utils.normalizeString(obj.portal_type) state_class = '' states = {} for w in workflow.getWorkflowsFor(obj): state = w._getWorkflowStateOf(obj).id states[w.state_var] = state state_class += "state-%s " % state results_dict = dict( obj = obj, id = obj.getId(), title = title, uid = uid, path = path, url = url, fti = fti, item_data = json.dumps([]), url_href_title = url_href_title, obj_type = obj.Type, size = obj.getObjSize, modified = modified, icon = icon.html_tag(), type_class = type_class, # a list of lookups for single-value-select fields choices = {}, state_class = state_class, relative_url = relative_url, view_url = url, table_row_class = "", category = 'None', # a list of names of fields that may be edited on this item allow_edit = [], # a list of names of fields that are compulsory (if editable) required = [], # "before", "after" and replace: dictionary (key is column ID) # A snippet of HTML which will be rendered # before/after/instead of the table cell content. before = {}, # { before : "<a href=..>" } after = {}, replace = {}, ) try: self.review_state = workflow.getInfoFor(obj, 'review_state') state_title = workflow.getTitleForStateOnType( self.review_state, obj.portal_type) state_title = t(PMF(state_title)) except: self.review_state = 'active' state_title = None if self.review_state: results_dict['review_state'] = self.review_state for state_var, state in states.items(): if not state_title: state_title = workflow.getTitleForStateOnType( state, obj.portal_type) results_dict[state_var] = state results_dict['state_title'] = state_title # extra classes for individual fields on this item { field_id : "css classes" } results_dict['class'] = {} for name, adapter in getAdapters((obj, ), IFieldIcons): auid = obj.UID() if hasattr(obj, 'UID') and callable(obj.UID) else None if not auid: continue alerts = adapter() # logger.info(str(alerts)) if alerts and auid in alerts: if auid in self.field_icons: self.field_icons[auid].extend(alerts[auid]) else: self.field_icons[auid] = alerts[auid] # Search for values for all columns in obj for key in self.columns.keys(): if hasattr(obj, key): # if the key is already in the results dict # then we don't replace it's value if results_dict.has_key(key): continue value = getattr(obj, key) if callable(value): value = value() results_dict[key] = value results.append(results_dict) return results
def portal_state(self): return getMultiAdapter((self.context, self.request), name=u'plone_portal_state')
def folderitems(self, full_objects=False): #self.contentsMethod = self.context.getFolderContents if not hasattr(self, 'contentsMethod'): self.contentsMethod = getToolByName(self.context, self.catalog) context = aq_inner(self.context) #misc. tools plone_layout = getMultiAdapter((context, self.request), name=u'plone_layout') plone_utils = getToolByName(context, 'plone_utils') portal_types = getToolByName(context, 'portal_types') workflow = getToolByName(context, 'portal_workflow') show_all = False brains = self.contentsMethod(self.contentFilter) idx = 0 results = [] self.show_more = False for i, brain in enumerate(brains): # avoid creating unnecessary info for items outside the current # batch; only the path is needed for the "select all" case... # we only take allowed items into account if not show_all and idx >= self.pagesize: # Maximum number of items to be shown reached! self.show_more = True break obj = brain.getObject() if not obj or not self.isItemAllowed(obj): continue # we don't know yet if it's a brain or an object path = hasattr(obj, 'getPath') and obj.getPath() or \ "/".join(obj.getPhysicalPath()) uid = obj.UID() title = obj.Title() description = obj.Description() url = obj.absolute_url() relative_url = obj.absolute_url(relative=True) icon = plone_layout.getIcon(obj) fti = portal_types.get(obj.portal_type) if fti is not None: type_title_msgid = fti.Title() else: type_title_msgid = obj.portal_type url_href_title = '%s at %s: %s' % (t(type_title_msgid), path, to_utf8(description)) modified = api.portal.get_localized_time(obj.modified()) type_class = 'contenttype-' + \ plone_utils.normalizeString(obj.portal_type) state_class = '' states = {} results_dict = dict( obj=obj, id=obj.getId(), title=title, uid=uid, path=path, url=url, fti=fti, item_data=json.dumps([]), url_href_title=url_href_title, obj_type=obj.Type, size=obj.getObjSize, modified=modified, icon=icon.html_tag(), type_class=type_class, choices={}, state_class=state_class, relative_url=relative_url, view_url=url, table_row_class="", category='None', allow_edit=[], required=[], field={}, before={}, after={}, replace={}, ) # extra classes for individual fields on this item { field_id : "css classes" } results_dict['class'] = {} # Search for values for all columns in obj for key in self.columns.keys(): # if the key is already in the results dict # then we don't replace it's value value = results_dict.get(key, '') if key not in results_dict: attrobj = getFromString(obj, key) value = attrobj if attrobj else value # Custom attribute? Inspect to set the value # for the current column dinamically vattr = self.columns[key].get('attr', None) if vattr: attrobj = getFromString(obj, vattr) value = attrobj if attrobj else value results_dict[key] = value # Replace with an url? replace_url = self.columns[key].get('replace_url', None) if replace_url: attrobj = getFromString(obj, replace_url) if attrobj: results_dict['replace'][key] = \ '<a href="%s">%s</a>' % (attrobj, value) # The item basics filled. Delegate additional actions to folderitem # service. folderitem service is frequently overriden by child objects item = self.folderitem(obj, results_dict, idx) if item: results.append(item) idx += 1 return results
def folderitems(self, full_objects = False): """ """ #self.contentsMethod = self.context.getFolderContents if not hasattr(self, 'contentsMethod'): self.contentsMethod = getToolByName(self.context, self.catalog) context = aq_inner(self.context) plone_layout = getMultiAdapter((context, self.request), name = u'plone_layout') plone_utils = getToolByName(context, 'plone_utils') plone_view = getMultiAdapter((context, self.request), name = u'plone') portal_properties = getToolByName(context, 'portal_properties') portal_types = getToolByName(context, 'portal_types') workflow = getToolByName(context, 'portal_workflow') site_properties = portal_properties.site_properties norm = getUtility(IIDNormalizer).normalize show_all = self.request.get('show_all', '').lower() == 'true' pagenumber = int(self.request.get('pagenumber', 1) or 1) pagesize = self.pagesize start = (pagenumber - 1) * pagesize end = start + pagesize if (hasattr(self, 'And') and self.And) \ or (hasattr(self, 'Or') and self.Or): # if contentsMethod is capable, we do an AdvancedQuery. if hasattr(self.contentsMethod, 'makeAdvancedQuery'): aq = self.contentsMethod.makeAdvancedQuery(self.contentFilter) if hasattr(self, 'And') and self.And: tmpAnd = And() for q in self.And: tmpAnd.addSubquery(q) aq &= tmpAnd if hasattr(self, 'Or') and self.Or: tmpOr = Or() for q in self.Or: tmpOr.addSubquery(q) aq &= tmpOr brains = self.contentsMethod.evalAdvancedQuery(aq) else: # otherwise, self.contentsMethod must handle contentFilter brains = self.contentsMethod(self.contentFilter) else: brains = self.contentsMethod(self.contentFilter) results = [] self.page_start_index = "" for i, obj in enumerate(brains): # we don't know yet if it's a brain or an object path = hasattr(obj, 'getPath') and obj.getPath() or \ "/".join(obj.getPhysicalPath()) # avoid creating unnecessary info for items outside the current # batch; only the path is needed for the "select all" case... if not show_all and not start <= i < end: if hasattr(obj, 'getObject'): uid = obj.UID else: uid = obj.UID() results.append(dict(path = path, uid = uid)) continue if self.page_start_index == "": self.page_start_index = i if hasattr(obj, 'getObject'): obj = obj.getObject() uid = obj.UID() title = obj.Title() description = obj.Description() icon = plone_layout.getIcon(obj) url = obj.absolute_url() relative_url = obj.absolute_url(relative = True) fti = portal_types.get(obj.portal_type) if fti is not None: type_title_msgid = fti.Title() else: type_title_msgid = obj.portal_type url_href_title = u'%s at %s: %s' % \ (self.context.translate(type_title_msgid, context = self.request), path, safe_unicode(description)) modified = self.ulocalized_time(obj.modified()), # element css classes type_class = 'contenttype-' + \ plone_utils.normalizeString(obj.portal_type) state_class = '' states = {} for w in workflow.getWorkflowsFor(obj): state = w._getWorkflowStateOf(obj).id states[w.state_var] = state state_class += "state-%s " % state results_dict = dict( obj = obj, id = obj.getId, title = title, uid = uid, path = path, url = url, fti = fti, item_data = json.dumps([]), url_href_title = url_href_title, obj_type = obj.Type, size = obj.getObjSize, modified = modified, icon = icon.html_tag(), type_class = type_class, # a list of lookups for single-value-select fields choices = {}, state_class = state_class, relative_url = relative_url, view_url = url, table_row_class = "", # a list of names of fields that may be edited on this item allow_edit = [], # a list of names of fields that are compulsory (if editable) required = [], # "before", "after" and replace: dictionary (key is column ID) # A snippet of HTML which will be rendered # before/after/instead of the table cell content. before = {}, # { before : "<a href=..>" } after = {}, replace = {}, ) try: review_state = workflow.getInfoFor(obj, 'review_state') state_title = self.context.translate( PMF(workflow.getTitleForStateOnType(review_state, obj.portal_type))) except: review_state = 'active' state_title = None if review_state: results_dict['review_state'] = review_state for state_var, state in states.items(): if not state_title: state_title = workflow.getTitleForStateOnType( state, obj.portal_type) results_dict[state_var] = state results_dict['state_title'] = state_title # XXX add some kind of out-of-date indicator to bika listing ## if App.config.getConfiguration().debug_mode: ## from Products.CMFEditions.utilities import dereference ## pr = getToolByName(self.context, 'portal_repository') ## o = hasattr(obj, 'getObject') and obj.getObject() or obj ## if pr.isVersionable(o): ## pa = getToolByName(self.context, 'portal_archivist') ## history_id = str(dereference(o)[1]) ## version_id = hasattr(o, 'version_id') \ ## and str(o.version_id) or None ## if not 'version_id' in self.columns.keys(): ## self.columns['version_id'] = {'title':'version'} ## for x in range(len(self.review_states)): ## self.review_states[x]['columns'].append('version_id') ## results_dict['version_id'] = '%s/%s' % (version_id, history_id) # extra classes for individual fields on this item { field_id : "css classes" } results_dict['class'] = {} # Search for values for all columns in obj for key in self.columns.keys(): if hasattr(obj, key): # if the key is already in the results dict # then we don't replace it's value if results_dict.has_key(key): continue value = getattr(obj, key) if callable(value): value = value() results_dict[key] = value results.append(results_dict) return results
def helper(self): return getMultiAdapter((self.context, self.request), name=u'sl_helper')
def folderitems(self, full_objects=False): """ """ context = aq_inner(self.context) plone_layout = getMultiAdapter((context, self.request), name=u"plone_layout") plone_utils = getToolByName(context, "plone_utils") plone_view = getMultiAdapter((context, self.request), name=u"plone") portal_properties = getToolByName(context, "portal_properties") portal_types = getToolByName(context, "portal_types") workflow = getToolByName(context, "portal_workflow") site_properties = portal_properties.site_properties show_all = self.request.get("show_all", "").lower() == "true" pagenumber = int(self.request.get("pagenumber", 1) or 1) pagesize = self.pagesize start = (pagenumber - 1) * pagesize end = start + pagesize if not hasattr(self, "modified_contentFilter"): self.modified_contentFilter = self.contentFilter results = [] for i, obj in enumerate(self.contentsMethod(self.modified_contentFilter)): # we don't know yet if it's a brain or an object path = hasattr(obj, "getPath") and obj.getPath() or "/".join(obj.getPhysicalPath()) # avoid creating unnecessary info for items outside the current # batch; only the path is needed for the "select all" case... if not show_all and not start <= i < end: results.append(dict(path=path)) continue if hasattr(obj, "getObject"): obj = obj.getObject() uid = obj.UID() title = obj.Title() description = obj.Description() icon = plone_layout.getIcon(obj) url = obj.absolute_url() relative_url = obj.absolute_url(relative=True) fti = portal_types.get(obj.portal_type) if fti is not None: type_title_msgid = fti.Title() else: type_title_msgid = obj.portal_type url_href_title = u"%s at %s: %s" % ( translate(type_title_msgid, context=self.request), path, safe_unicode(description), ) modified = TimeOrDate(self.context, obj.ModificationDate, long_format=1) # Check for InterimFields attribute on our object, # XXX move interim/itemdata to analyses.py interim_fields = hasattr(obj, "getInterimFields") and obj.getInterimFields() or [] # element css classes type_class = "contenttype-" + plone_utils.normalizeString(obj.portal_type) if (i + 1) % 2 == 0: table_row_class = "draggable even" else: table_row_class = "draggable odd" state_class = "" states = {} for w in workflow.getWorkflowsFor(obj): state = w._getWorkflowStateOf(obj).id states[w.state_var] = state state_class += "state-%s " % state results_dict = dict( obj=obj, id=obj.getId, title=title, uid=uid, path=path, url=url, fti=fti, interim_fields=interim_fields, item_data=json.dumps(interim_fields), url_href_title=url_href_title, obj_type=obj.Type, size=obj.getObjSize, modified=modified, icon=icon.html_tag(), type_class=type_class, # a list of lookups for single-value-select fields choices={}, state_class=state_class, relative_url=relative_url, view_url=url, table_row_class=table_row_class, # a list of names of fields that may be edited on this item allow_edit=[], # "before", "after" and replace: dictionary (key is column ID) # A snippet of HTML which will be rendered # before/after/instead of the table cell content. before={}, # { before : "<a href=..>" } after={}, replace={}, ) try: review_state = workflow.getInfoFor(obj, "review_state") state_title = workflow.getTitleForStateOnType(review_state, obj.portal_type) except: review_state = "active" state_title = None if review_state: results_dict["review_state"] = review_state for state_var, state in states.items(): if not state_title: state_title = workflow.getTitleForStateOnType(state, obj.portal_type) results_dict[state_var] = state results_dict["state_title"] = state_title # XXX debug - add history_id column ## if App.config.getConfiguration().debug_mode: ## from Products.CMFEditions.utilities import dereference ## pr = getToolByName(self.context, 'portal_repository') ## o = hasattr(obj, 'getObject') and obj.getObject() or obj ## if pr.isVersionable(o): ## pa = getToolByName(self.context, 'portal_archivist') ## history_id = str(dereference(o)[1]) ## version_id = hasattr(o, 'version_id') \ ## and str(o.version_id) or None ## if not 'version_id' in self.columns.keys(): ## self.columns['version_id'] = {'title':'version'} ## for x in range(len(self.review_states)): ## if self.review_states[x]['id'] == 'all': ## self.review_states[x]['columns'].append('version_id') ## results_dict['version_id'] = '%s/%s' % (version_id, history_id) # extra classes for individual fields on this item { field_id : "css classes" } results_dict["class"] = {} # Search for values for all columns in obj for key in self.columns.keys(): if hasattr(obj, key): # if the key is already in the results dict # then we don't replace it's value if results_dict.has_key(key): continue value = getattr(obj, key) if callable(value): value = value() results_dict[key] = value results.append(results_dict) return results
def folderitems(self, full_objects=False): """ """ #self.contentsMethod = self.context.getFolderContents if not hasattr(self, 'contentsMethod'): self.contentsMethod = getToolByName(self.context, self.catalog) context = aq_inner(self.context) plone_layout = getMultiAdapter((context, self.request), name=u'plone_layout') plone_utils = getToolByName(context, 'plone_utils') plone_view = getMultiAdapter((context, self.request), name=u'plone') portal_properties = getToolByName(context, 'portal_properties') portal_types = getToolByName(context, 'portal_types') workflow = getToolByName(context, 'portal_workflow') site_properties = portal_properties.site_properties norm = getUtility(IIDNormalizer).normalize show_all = self.request.get('show_all', '').lower() == 'true' pagenumber = int(self.request.get('pagenumber', 1) or 1) pagesize = self.pagesize start = (pagenumber - 1) * pagesize end = start + pagesize if (hasattr(self, 'And') and self.And) \ or (hasattr(self, 'Or') and self.Or): # if contentsMethod is capable, we do an AdvancedQuery. if hasattr(self.contentsMethod, 'makeAdvancedQuery'): aq = self.contentsMethod.makeAdvancedQuery(self.contentFilter) if hasattr(self, 'And') and self.And: tmpAnd = And() for q in self.And: tmpAnd.addSubquery(q) aq &= tmpAnd if hasattr(self, 'Or') and self.Or: tmpOr = Or() for q in self.Or: tmpOr.addSubquery(q) aq &= tmpOr brains = self.contentsMethod.evalAdvancedQuery(aq) else: # otherwise, self.contentsMethod must handle contentFilter brains = self.contentsMethod(self.contentFilter) else: brains = self.contentsMethod(self.contentFilter) results = [] self.page_start_index = "" for i, obj in enumerate(brains): # we don't know yet if it's a brain or an object path = hasattr(obj, 'getPath') and obj.getPath() or \ "/".join(obj.getPhysicalPath()) # avoid creating unnecessary info for items outside the current # batch; only the path is needed for the "select all" case... if not show_all and not start <= i < end: if hasattr(obj, 'getObject'): uid = obj.UID else: uid = obj.UID() results.append(dict(path=path, uid=uid)) continue if self.page_start_index == "": self.page_start_index = i if hasattr(obj, 'getObject'): obj = obj.getObject() uid = obj.UID() title = obj.Title() description = obj.Description() icon = plone_layout.getIcon(obj) url = obj.absolute_url() relative_url = obj.absolute_url(relative=True) fti = portal_types.get(obj.portal_type) if fti is not None: type_title_msgid = fti.Title() else: type_title_msgid = obj.portal_type url_href_title = u'%s at %s: %s' % \ (self.context.translate(type_title_msgid, context = self.request), path, safe_unicode(description)) modified = self.ulocalized_time(obj.modified()), # element css classes type_class = 'contenttype-' + \ plone_utils.normalizeString(obj.portal_type) state_class = '' states = {} for w in workflow.getWorkflowsFor(obj): state = w._getWorkflowStateOf(obj).id states[w.state_var] = state state_class += "state-%s " % state results_dict = dict( obj=obj, id=obj.getId, title=title, uid=uid, path=path, url=url, fti=fti, item_data=json.dumps([]), url_href_title=url_href_title, obj_type=obj.Type, size=obj.getObjSize, modified=modified, icon=icon.html_tag(), type_class=type_class, # a list of lookups for single-value-select fields choices={}, state_class=state_class, relative_url=relative_url, view_url=url, table_row_class="", category='None', # a list of names of fields that may be edited on this item allow_edit=[], # a list of names of fields that are compulsory (if editable) required=[], # "before", "after" and replace: dictionary (key is column ID) # A snippet of HTML which will be rendered # before/after/instead of the table cell content. before={}, # { before : "<a href=..>" } after={}, replace={}, ) try: review_state = workflow.getInfoFor(obj, 'review_state') state_title = self.context.translate( PMF( workflow.getTitleForStateOnType( review_state, obj.portal_type))) except: review_state = 'active' state_title = None if review_state: results_dict['review_state'] = review_state for state_var, state in states.items(): if not state_title: state_title = workflow.getTitleForStateOnType( state, obj.portal_type) results_dict[state_var] = state results_dict['state_title'] = state_title # XXX add some kind of out-of-date indicator to bika listing ## if App.config.getConfiguration().debug_mode: ## from Products.CMFEditions.utilities import dereference ## pr = getToolByName(self.context, 'portal_repository') ## o = hasattr(obj, 'getObject') and obj.getObject() or obj ## if pr.isVersionable(o): ## pa = getToolByName(self.context, 'portal_archivist') ## history_id = str(dereference(o)[1]) ## version_id = hasattr(o, 'version_id') \ ## and str(o.version_id) or None ## if not 'version_id' in self.columns.keys(): ## self.columns['version_id'] = {'title':'version'} ## for x in range(len(self.review_states)): ## self.review_states[x]['columns'].append('version_id') ## results_dict['version_id'] = '%s/%s' % (version_id, history_id) # extra classes for individual fields on this item { field_id : "css classes" } results_dict['class'] = {} # Search for values for all columns in obj for key in self.columns.keys(): if hasattr(obj, key): # if the key is already in the results dict # then we don't replace it's value if results_dict.has_key(key): continue value = getattr(obj, key) if callable(value): value = value() results_dict[key] = value results.append(results_dict) return results
def folderitems(self, full_objects=False): """ >>> portal = layer['portal'] >>> portal_url = portal.absolute_url() >>> from plone.app.testing import SITE_OWNER_NAME >>> from plone.app.testing import SITE_OWNER_PASSWORD Test page batching https://github.com/bikalabs/Bika-LIMS/issues/1276 When visiting the second page, the Water sampletype should be displayed: >>> browser = layer['getBrowser'](portal, loggedIn=True, username=SITE_OWNER_NAME, password=SITE_OWNER_PASSWORD) >>> browser.open(portal_url+"/bika_setup/bika_sampletypes/folder_view?", ... "list_pagesize=10&list_review_state=default") >>> browser.contents '...Water...' """ #self.contentsMethod = self.context.getFolderContents if not hasattr(self, 'contentsMethod'): self.contentsMethod = getToolByName(self.context, self.catalog) context = aq_inner(self.context) plone_layout = getMultiAdapter((context, self.request), name=u'plone_layout') plone_utils = getToolByName(context, 'plone_utils') plone_view = getMultiAdapter((context, self.request), name=u'plone') portal_properties = getToolByName(context, 'portal_properties') portal_types = getToolByName(context, 'portal_types') workflow = getToolByName(context, 'portal_workflow') site_properties = portal_properties.site_properties norm = getUtility(IIDNormalizer).normalize if self.request.get('show_all', '').lower() == 'true' \ or self.show_all == True \ or self.pagesize == 0: show_all = True else: show_all = False if (hasattr(self, 'And') and self.And) \ or (hasattr(self, 'Or') and self.Or): # if contentsMethod is capable, we do an AdvancedQuery. if hasattr(self.contentsMethod, 'makeAdvancedQuery'): aq = self.contentsMethod.makeAdvancedQuery(self.contentFilter) if hasattr(self, 'And') and self.And: tmpAnd = And() for q in self.And: tmpAnd.addSubquery(q) aq &= tmpAnd if hasattr(self, 'Or') and self.Or: tmpOr = Or() for q in self.Or: tmpOr.addSubquery(q) aq &= tmpOr brains = self.contentsMethod.evalAdvancedQuery(aq) else: # otherwise, self.contentsMethod must handle contentFilter brains = self.contentsMethod(self.contentFilter) else: brains = self.contentsMethod(self.contentFilter) # idx increases one unit each time an object is added to the 'items' # dictionary to be returned. Note that if the item is not rendered, # the idx will not increase. idx = 0 results = [] self.show_more = False brains = brains[self.limit_from:] for i, obj in enumerate(brains): # avoid creating unnecessary info for items outside the current # batch; only the path is needed for the "select all" case... # we only take allowed items into account if not show_all and idx >= self.pagesize: # Maximum number of items to be shown reached! self.show_more = True break # we don't know yet if it's a brain or an object path = hasattr(obj, 'getPath') and obj.getPath() or \ "/".join(obj.getPhysicalPath()) # This item must be rendered, we need the object instead of a brain obj = obj.getObject() if hasattr(obj, 'getObject') else obj # check if the item must be rendered or not (prevents from # doing it later in folderitems) and dealing with paging if not obj or not self.isItemAllowed(obj): continue uid = obj.UID() title = obj.Title() description = obj.Description() icon = plone_layout.getIcon(obj) url = obj.absolute_url() relative_url = obj.absolute_url(relative=True) fti = portal_types.get(obj.portal_type) if fti is not None: type_title_msgid = fti.Title() else: type_title_msgid = obj.portal_type url_href_title = '%s at %s: %s' % (t(type_title_msgid), path, to_utf8(description)) modified = self.ulocalized_time(obj.modified()), # element css classes type_class = 'contenttype-' + \ plone_utils.normalizeString(obj.portal_type) state_class = '' states = {} for w in workflow.getWorkflowsFor(obj): state = w._getWorkflowStateOf(obj).id states[w.state_var] = state state_class += "state-%s " % state results_dict = dict( obj=obj, id=obj.getId(), title=title, uid=uid, path=path, url=url, fti=fti, item_data=json.dumps([]), url_href_title=url_href_title, obj_type=obj.Type, size=obj.getObjSize, modified=modified, icon=icon.html_tag(), type_class=type_class, # a list of lookups for single-value-select fields choices={}, state_class=state_class, relative_url=relative_url, view_url=url, table_row_class="", category='None', # a list of names of fields that may be edited on this item allow_edit=[], # a list of names of fields that are compulsory (if editable) required=[], # a dict where the column name works as a key and the value is # the name of the field related with the column. It is used # when the name given to the column and the content field it # represents diverges. bika_listing_table_items.pt defines an # attribute for each item, this attribute is named 'field' and # the system fills it taking advantage of this dictionary or # the name of the column if it isn't defined in the dict. field={}, # "before", "after" and replace: dictionary (key is column ID) # A snippet of HTML which will be rendered # before/after/instead of the table cell content. before={}, # { before : "<a href=..>" } after={}, replace={}, ) try: rs = workflow.getInfoFor(obj, 'review_state') st_title = workflow.getTitleForStateOnType(rs, obj.portal_type) st_title = t(PMF(st_title)) except: rs = 'active' st_title = None if rs: results_dict['review_state'] = rs for state_var, state in states.items(): if not st_title: st_title = workflow.getTitleForStateOnType( state, obj.portal_type) results_dict[state_var] = state results_dict['state_title'] = st_title # extra classes for individual fields on this item { field_id : "css classes" } results_dict['class'] = {} for name, adapter in getAdapters((obj, ), IFieldIcons): auid = obj.UID() if hasattr(obj, 'UID') and callable( obj.UID) else None if not auid: continue alerts = adapter() # logger.info(str(alerts)) if alerts and auid in alerts: if auid in self.field_icons: self.field_icons[auid].extend(alerts[auid]) else: self.field_icons[auid] = alerts[auid] # Search for values for all columns in obj for key in self.columns.keys(): # if the key is already in the results dict # then we don't replace it's value value = results_dict.get(key, '') if key not in results_dict: attrobj = getFromString(obj, key) value = attrobj if attrobj else value # Custom attribute? Inspect to set the value # for the current column dinamically vattr = self.columns[key].get('attr', None) if vattr: attrobj = getFromString(obj, vattr) value = attrobj if attrobj else value results_dict[key] = value # Replace with an url? replace_url = self.columns[key].get('replace_url', None) if replace_url: attrobj = getFromString(obj, replace_url) if attrobj: results_dict['replace'][key] = \ '<a href="%s">%s</a>' % (attrobj, value) # The item basics filled. Delegate additional actions to folderitem # service. folderitem service is frequently overriden by child objects item = self.folderitem(obj, results_dict, idx) if item: results.append(item) idx += 1 # Need manual_sort? # Note that the order has already been set in contentFilter, so # there is no need to reverse if self.manual_sort_on: results.sort(lambda x, y: cmp(x.get(self.manual_sort_on, ''), y.get(self.manual_sort_on, ''))) return results