def upgrade_to_1004_daterange_widget(context): from eea.facetednavigation.subtypes.interfaces import IFacetedNavigable from eea.facetednavigation.layout.interfaces import IFacetedLayout from eea.facetednavigation.interfaces import ICriteria from eea.facetednavigation.widgets.storage import Criterion brains = api.content.find(object_provides=IFacetedNavigable.__identifier__) layouts = ("faceted-agenda-ungrouped-view-items", "faceted-agenda-view-items") for brain in brains: obj = brain.getObject() if IFacetedLayout(obj).layout not in layouts: continue criterion = ICriteria(obj) for key, criteria in criterion.items(): if criteria.get("widget") != "daterange": continue if criteria.get("usePloneDateFormat") is True: continue logger.info("Upgrade daterange widget for faceted {0}".format(obj)) position = criterion.criteria.index(criteria) values = criteria.__dict__ values["usePloneDateFormat"] = True criterion.criteria[position] = Criterion(**values) criterion.criteria._p_changed = 1
def migrate_autocomplete_widget(context): """ As in version 8.4 we added selection of the autocomplete suggestion view. To maintain backward compatibility we will set the value of this 'autocomplete_view' field to solr suggestions view. """ ctool = getToolByName(context, 'portal_catalog') iface = interfaceToName(context, IFacetedNavigable) brains = ctool.unrestrictedSearchResults(object_provides=iface) count = 0 for brain in brains: doc = brain.getObject() settings = ICriteria(doc) for criterion in settings.values(): if criterion.widget == 'autocomplete': criterion.autocomplete_view = u'solr-autocomplete-suggest' logger.info( 'Set defaut autocomplete view of widget: %s', criterion.title ) count += 1 logger.info('Migrated %s autocomplete widgets', count)
def add_sorting_widget(context): """ As in version 7.1 we removed default sorting by effective date, in order to maintain backward compatibility we will add a sorting widget, hidden for all faceted navigable items where this widget is not present """ ctool = getToolByName(context, 'portal_catalog') iface = interfaceToName(context, IFacetedNavigable) brains = ctool.unrestrictedSearchResults(object_provides=iface) count = 0 for brain in brains: try: doc = brain.getObject() settings = ICriteria(doc) sorting = [criterion for criterion in settings.values() if criterion.widget == 'sorting'] if sorting: continue settings.add( 'sorting', 'right', title='Sort on', default='effective(reverse)', hidden=True ) except Exception, err: logger.exception(err) else: logger.info('Added sorting widget for: %s', doc.absolute_url()) count += 1
def edit(self, cid, **kwargs): """ See IFacetedCriterionHandler """ criteria = ICriteria(self.context) widget = criteria.widget(cid=cid) criterion = criteria.get(cid) if kwargs.pop('__new__', False): criterion = criterion.__class__(cid='c0') widget = widget(self.context, self.request, criterion) wid = kwargs.pop('widget', None) properties = self.extractData(widget, **kwargs) if wid: properties['widget'] = wid update = {} for prop, value in properties.items(): form_key = 'faceted.%s.%s' % (cid, prop) if form_key not in kwargs and value is None: continue update[prop] = value if update: criteria.edit(cid, **update) if widget.hidden: notify(FacetedGlobalSettingsChangedEvent(self.context)) elif set(['hidden', 'operator']).intersection(update.keys()): notify(FacetedGlobalSettingsChangedEvent(self.context)) return self._redirect('Changes saved')
def query(self, cid, **kwargs): """ Count catalog items """ # Cleanup query kwargs.pop('sort_on', None) kwargs.pop('sort_order', None) kwargs.pop(cid, None) self.request.form.pop(cid, None) # jQuery >= 1.4 adds type to params keys # $.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4" # Let's fix this kwargs.pop(cid + '[]', None) self.request.form.pop(cid + '[]', None) criteria = ICriteria(self.context) criterion = criteria.get(cid) start = time.time() # Query catalog handler = getMultiAdapter((self.context, self.request), name=u'faceted_query') if criterion.get('index', '') == 'Language': kwargs['_language_count_'] = True brains = handler.query(batch=False, sort=False, **kwargs) # Get index widget = criteria.widget(cid=cid)(self.context, self.request, criterion) res = widget.count(brains) logger.debug('Benchmark %s: %s', cid, time.time() - start) return res
def add_sorting_widget(context): """ As in version 7.1 we removed default sorting by effective date, in order to maintain backward compatibility we will add a sorting widget, hidden for all faceted navigable items where this widget is not present """ ctool = getToolByName(context, 'portal_catalog') iface = interfaceToName(context, IFacetedNavigable) brains = ctool.unrestrictedSearchResults(object_provides=iface) count = 0 for brain in brains: try: doc = brain.getObject() settings = ICriteria(doc) sorting = [ criterion for criterion in settings.values() if criterion.widget == 'sorting' ] if sorting: continue settings.add('sorting', 'right', title='Sort on', default='effective(reverse)', hidden=True) except Exception, err: logger.exception(err) else: logger.info('Added sorting widget for: %s', doc.absolute_url()) count += 1
def language_present(self): """ Is there any widget for Language index? """ criteria = ICriteria(self.context) for criterion in criteria.values(): if criterion.get('index', None) == 'Language': if not criterion.hidden: return True return False
def _updateFacetedFilters(self): """Update vocabulary used for "Taken over by". Make sure the default for contacts 'c5' widget is not a list.""" logger.info( "Updating faceted filter \"Taken over by\" for every MeetingConfigs..." ) for cfg in self.tool.objectValues('MeetingConfig'): obj = cfg.searches.searches_items # update vocabulary for relevant filters criteria = ICriteria(obj) criteria.edit( 'c12', **{ 'vocabulary': 'Products.PloneMeeting.vocabularies.creatorswithnobodyforfacetedfiltervocabulary' }) criteria.edit( 'c27', **{ 'vocabulary': 'Products.PloneMeeting.vocabularies.associatedgroupsvocabulary' }) logger.info('Done.') logger.info("Updating faceted filter \"Defined in\" for 'c5' " "criterion of contacts/orgs-searches...") obj = self.portal.contacts.get('orgs-searches') # as default is not correct (a string instead a list, we can not use edit or it fails to validate) criteria = ICriteria(obj) criterion = criteria.get('c5') criterion.default = u'collective.contact.plonegroup.interfaces.IPloneGroupContact' logger.info('Done.')
def get_widgets(self, position='', section=''): """ Get all widgets """ criteria = ICriteria(self.context) for criterion in criteria.values(): if position and criterion.get('position', 'right') != position: continue if section and criterion.get('section', 'default') != section: continue widget = criteria.widget(wid=criterion.get('widget')) yield widget(self.context, self.request, criterion)
def perPage(self): num_per_page = 20 criteria = ICriteria(self.context) for cid, criterion in criteria.items(): widgetclass = criteria.widget(cid=cid) widget = widgetclass(self.context, self.request, criterion) if widget.widget_type == 'resultsperpage': kwargs = dict((key.replace('[]', ''), val) for key, val in self.request.form.items()) num_per_page = widget.results_per_page(kwargs) return num_per_page
def get_widgets(self, position="", section=""): """ Get all widgets """ criteria = ICriteria(self.context) for criterion in criteria.values(): if position and criterion.get("position", "right") != position: continue if section and criterion.get("section", "default") != section: continue widget = criteria.widget(wid=criterion.get("widget")) yield widget(self.context, self.request, criterion)
def add(self, **kwargs): """ See IFacetedCriterionHandler """ kwargs = self._request_form(kwargs) wid = kwargs.pop('wtype', None) position = kwargs.pop('wposition', 'right') section = kwargs.pop('wsection', 'default') criteria = ICriteria(self.context) cid = criteria.add(wid, position, section) return self.edit(cid, **kwargs)
def query(self, batch=True, sort=False, **kwargs): """ Search using given criteria """ if self.request: kwargs.update(self.request.form) kwargs.pop('sort[]', None) kwargs.pop('sort', None) # jQuery >= 1.4 adds type to params keys # $.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4" # Let's fix this kwargs = dict( (key.replace('[]', ''), val) for key, val in kwargs.items()) #fix for unicode error in indexes for key, val in kwargs.items(): if isinstance(val, str): kwargs[key] = val.decode('utf-8') query = self.criteria(sort=sort, **kwargs) # We don't want to do an unnecessary sort for a counter query counter_query = kwargs.pop('counter_query', False) if counter_query: query.pop('sort_on', None) query.pop('sort_order', None) catalog = getUtility(IFacetedCatalog) num_per_page = 20 criteria = ICriteria(self.context) brains_filters = [] for cid, criterion in criteria.items(): widgetclass = criteria.widget(cid=cid) widget = widgetclass(self.context, self.request, criterion) if widget.widget_type == 'resultsperpage': num_per_page = widget.results_per_page(kwargs) brains_filter = queryAdapter(widget, IWidgetFilterBrains) if brains_filter: brains_filters.append(brains_filter) b_start = safeToInt(kwargs.get('b_start', 0)) orphans = num_per_page * 20 / 100 # orphans = 20% of items per page if batch and not brains_filters: # add b_start and b_size to query to use better sort algorithm query['b_start'] = b_start query['b_size'] = num_per_page + orphans try: brains = catalog(self.context, **query) except Exception, err: logger.exception(err) return Batch([], 20, 0)
def add(self, **kwargs): """ See IFacetedCriterionHandler """ wid = kwargs.pop('wtype', self.request.get('wtype', None)) position = kwargs.pop('wposition', self.request.get('wposition', 'right')) section = kwargs.pop('wsection', self.request.get('wsection', 'default')) criteria = ICriteria(self.context) cid = criteria.add(wid, position, section) return self.edit(cid, __new__=True, **kwargs)
def criteria(self, sort=False, **kwargs): """ Process catalog query """ if self.request: kwargs.update(self.request.form) # jQuery >= 1.4 adds type to params keys # $.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4" # Let's fix this kwargs = dict((key.replace('[]', ''), val) for key, val in kwargs.items()) logger.debug("REQUEST: %r", kwargs) # Generate the catalog query criteria = ICriteria(self.context) query = {} for cid, criterion in criteria.items(): widget = criteria.widget(cid=cid) widget = widget(self.context, self.request, criterion) widget_query = widget.query(kwargs) if getattr(widget, 'faceted_field', False): widget_index = widget.data.get('index', '') if ('facet.field' in query and widget_index not in query['facet.field']): query['facet.field'].append(widget_index) else: query['facet.field'] = [widget_index] query.update(widget_query) # Handle language widgets if criterion.get('index', '') == 'Language': language_widget = queryMultiAdapter((widget, self.context), ILanguageWidgetAdapter) if not language_widget: continue query.update(language_widget(kwargs)) # Add default sorting criteria if sort and not query.has_key('sort_on'): query['sort_on'] = 'effective' query['sort_order'] = 'reverse' # Add default language. # Also make sure to return language-independent content. lang = self.language if lang: lang = [lang, ''] query.setdefault('Language', lang) logger.debug('QUERY: %s', query) return query
def criteria(self, sort=False, **kwargs): """ Process catalog query """ if self.request: kwargs.update(self.request.form) # jQuery >= 1.4 adds type to params keys # $.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4" # Let's fix this kwargs = dict((key.replace('[]', ''), val) for key, val in kwargs.items()) logger.debug("REQUEST: %r", kwargs) # Generate the catalog query criteria = ICriteria(self.context) query = {} for cid, criterion in criteria.items(): widget = criteria.widget(cid=cid) widget = widget(self.context, self.request, criterion) widget_query = widget.query(kwargs) if getattr(widget, 'faceted_field', False): widget_index = widget.data.get('index', '') if ('facet.field' in query and widget_index not in query['facet.field']): query['facet.field'].append(widget_index) else: query['facet.field'] = [widget_index] query.update(widget_query) # Handle language widgets if criterion.get('index', '') == 'Language': language_widget = queryMultiAdapter((widget, self.context), ILanguageWidgetAdapter) if not language_widget: continue query.update(language_widget(kwargs)) # Add default sorting criteria if sort and 'sort_on' not in query: query['sort_on'] = 'effective' query['sort_order'] = 'reverse' # Add default language. # Also make sure to return language-independent content. lang = self.language if lang: lang = [lang, ''] query.setdefault('Language', lang) logger.debug('QUERY: %s', query) return query
def _updateFacetedFilters(self): """Update vocabulary used for "Taken over by".""" logger.info( "Updating faceted filter \"Taken over by\" for every MeetingConfigs..." ) for cfg in self.tool.objectValues('MeetingConfig'): criteria = ICriteria(cfg.searches.searches_items) criteria.edit( 'c12', **{ 'vocabulary': 'Products.PloneMeeting.vocabularies.creatorswithnobodyforfacetedfiltervocabulary' }) logger.info('Done.')
def criteria(self, sort=True, **kwargs): """ Process catalog query """ if self.request: kwargs.update(self.request.form) # jQuery >= 1.4 adds type to params keys # $.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4" # Let's fix this kwargs = dict((key.replace('[]', ''), val) for key, val in kwargs.items()) logger.debug("REQUEST: %r", kwargs) # Generate the catalog query mtool = getToolByName(self.context, 'portal_membership', None) criteria = ICriteria(self.context) query = {} if mtool.isAnonymousUser(): query['review_state'] = 'published' for cid, criterion in criteria.items(): widget = criteria.widget(cid=cid) widget = widget(self.context, self.request, criterion) query.update(widget.query(kwargs)) # Handle language widgets if criterion.get('index', '') == 'Language': language_widget = queryMultiAdapter((widget, self.context), ILanguageWidgetAdapter) if not language_widget: continue query.update(language_widget(kwargs)) # Add default sorting criteria if sort and not query.has_key('sort_on'): query['sort_on'] = 'effective' query['sort_order'] = 'reverse' # Add default language. # Also make sure to return language-independent content. lang = self.language if lang: lang = [lang, ''] query.setdefault('Language', lang) logger.debug('QUERY: %s', query) return query
def edit(self, **kwargs): """ See IFacetedCriteriaHandler """ criteria = ICriteria(self.context) handler = getMultiAdapter((self.context, self.request), name=u'faceted_update_criterion') for cid in criteria.keys(): properties = {} for key, value in kwargs.items(): if not key.startswith(cid): continue key = key[len(cid) + 1:] properties[key] = value handler.edit(cid, **properties) return self._redirect('Changes saved', to=self.redirect)
def upgrade_to_3(context): catalog = api.portal.get_tool('portal_catalog') brains = catalog(object_provides=IFacetedNavigable.__identifier__) for brain in brains: obj = brain.getObject() criterias = ICriteria(obj) changes = False for cid, crit in criterias.items(): if crit.get('vocabulary', u'') in (u'imio.dashboard.conditionawarecollectionvocabulary', u'imio.dashboard.cachedcollectionvocabulary'): crit.vocabulary = u'collective.eeafaceted.collectionwidget.cachedcollectionvocabulary' changes = True logger.info('Criterion {} updated on object {}'.format(cid, brain.getPath())) if changes: criterias.criteria._p_changed = 1
def query(self, batch=True, sort=False, **kwargs): """ Search using given criteria """ if self.request: kwargs.update(self.request.form) kwargs.pop('sort[]', None) kwargs.pop('sort', None) # jQuery >= 1.4 adds type to params keys # $.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4" # Let's fix this kwargs = dict((key.replace('[]', ''), val) for key, val in kwargs.items()) query = self.criteria(sort=sort, **kwargs) # We don't want to do an unnecessary sort for a counter query counter_query = kwargs.pop('counter_query', False) if counter_query: query.pop('sort_on', None) query.pop('sort_order', None) catalog = getUtility(IFacetedCatalog) num_per_page = 20 criteria = ICriteria(self.context) brains_filters = [] for cid, criterion in criteria.items(): widgetclass = criteria.widget(cid=cid) widget = widgetclass(self.context, self.request, criterion) if widget.widget_type == 'resultsperpage': num_per_page = widget.results_per_page(kwargs) brains_filter = queryAdapter(widget, IWidgetFilterBrains) if brains_filter: brains_filters.append(brains_filter) b_start = safeToInt(kwargs.get('b_start', 0)) orphans = num_per_page * 20 / 100 # orphans = 20% of items per page if batch and not brains_filters: # add b_start and b_size to query to use better sort algorithm query['b_start'] = b_start query['b_size'] = num_per_page + orphans try: brains = catalog(self.context, **query) except Exception, err: logger.exception(err) return Batch([], 20, 0)
def test_get_generation_context_filtered_query(self): """ If a filter is used in the facetedQuery, elements displayed in the dashboard are correctly given to the template. """ faceted_query = self.folder.restrictedTraverse('@@faceted_query') # for now 3 elements self.assertEquals(len(faceted_query.query()), 3) # filter on text, 'Folder 2' self.assertEquals(ICriteria(self.folder).get('c2').index, u'SearchableText') self.request.form['c2[]'] = 'Folder 2' self.assertEquals(len(faceted_query.query()), 1) # generation context respect query self.request.form['facetedQuery'] = '' gen_context = self.view._get_generation_context(self.helper, self.dashboardtemplate) self.assertEquals(len(gen_context['uids']), 1) # facetedQuery is passed to the generation context as json # reset query, back to 3 elements found self.request.form = {} self.assertEquals(len(faceted_query.query()), 3) self.request.form['facetedQuery'] = '' gen_context = self.view._get_generation_context(self.helper, self.dashboardtemplate) self.assertEquals(len(gen_context['uids']), 3) # 'facetedQuery' is received as a serialized JSON of query criteria self.request.form['facetedQuery'] = '{"c2":"Folder 2"}' gen_context = self.view._get_generation_context(self.helper, self.dashboardtemplate) self.assertEquals(len(gen_context['uids']), 1)
def delete(self, cid, **kwargs): """ See IFacetedCriterionHandler """ try: ICriteria(self.context).delete(cid) except (TypeError, KeyError), err: msg = err
def query(self, cid, **kwargs): """ Count catalog items """ # Cleanup query kwargs.pop('sort_on', None) kwargs.pop('sort_order', None) kwargs.pop(cid, None) self.request.form.pop(cid, None) criteria = ICriteria(self.context) criterion = criteria.get(cid) # Query catalog handler = getMultiAdapter((self.context, self.request), name=u'faceted_query') if criterion.get('index', '') == 'Language': kwargs['_language_count_'] = True brains = handler.query(batch=False, sort=False, **kwargs) # Get index widget = criteria.widget(cid=cid)(self.context, self.request, criterion) vocabulary = dict((key, value) for key, value, count in widget.vocabulary(oll=True) if key not in ("", "all")) # Count count = getattr(widget, 'count', lambda brains, sequence: {}) res = count(brains, sequence=vocabulary.keys()) res.pop("", 0) oll = res.pop('all', 0) res = res.items() res.sort(key=operator.itemgetter(1), reverse=True) maxitems = widget.maxitems if maxitems: res = res[:maxitems] res.sort(key=operator.itemgetter(0), cmp=compare) # Return a of list of three items tuples (key, label, count) res = [(key, vocabulary.get(key, key), value) for key, value in res] res.insert(0, ('all', 'All', oll)) for item in res: yield item
def update(self, **kwargs): """ Update position by given slots """ logger.debug(kwargs) kwargs = self._request_form(kwargs) ICriteria(self.context).position(**kwargs) return self._redirect('Position changed')
def __init__(self, context, request, data=None): super(CollectionWidget, self).__init__(context, request, data) # real context could not be current context but some distant context # look in eea.facetednavigation.criteria.handler.Criteria self.criteria = ICriteria(self.context) self.context = self.criteria.context # display the fieldset around the widget when rendered? self.display_fieldset = True
def _exportNode(self): """Export the object as a DOM node. """ node = self._getObjectNode('object') criteria = ICriteria(self.context) exporter = queryMultiAdapter((criteria, self.environ), IBody) node.appendChild(exporter.node) return node
def __call__(self, **kwargs): if self.request: kwargs.update(self.request.form) # Calling self.index() will set cache headers for varnish self.index() cid = kwargs.pop('cid', None) if not cid: return {} res = self.query(cid, **kwargs) criteria = ICriteria(self.context) criterion = criteria.get(cid) widget = criteria.widget(cid=cid)(self.context, self.request, criterion) return widget(vocabulary=res)
def _importNode(self, node): """Import the object from the DOM node. """ criteria = ICriteria(self.context) for child in node.childNodes: if child.nodeName != 'criteria': continue importer = queryMultiAdapter((criteria, self.environ), IBody) importer.node = child
def __init__(self, context, request): # TODO: update this to new workings of collection facet (now that we have a custom portal_type) super(DatasetsCollectionListView, self).__init__(context, request) self.datasets_url = self.context.absolute_url() self.criteria = ICriteria(self.context, {}) self.defaults = {} self.criterion = None for criterion in self.criteria.values(): if criterion.widget == 'pathselect': self.criterion = criterion if criterion.widget == 'sorting': default = criterion.default if not default: continue if '(reverse)' in default: default = default.replace('(reverse)', '', 1) self.defaults['reversed'] = True self.defaults[criterion.getId()] = default
def delete(self, cid, **kwargs): """ See IFacetedCriterionHandler """ try: ICriteria(self.context).delete(cid) except (TypeError, KeyError) as err: msg = err else: msg = _(u'Filter deleted') return self._redirect(msg=msg)
def add(self, **kwargs): """ See IFacetedCriteriaHandler """ wid = kwargs.pop('wtype', None) position = kwargs.pop('wposition', 'right') section = kwargs.pop('wsection', 'default') try: ICriteria(self.context).add(wid, position, section) except NameError, err: msg = err
def test_enableFacetedDashboardFor(self): """This method will enable the faceted navigation for a given folder.""" # faceted can be enabled using the default widgets catalog = self.portal.portal_catalog folder2_id = self.portal.invokeFactory('Folder', 'folder2', title='Folder2') folder2 = getattr(self.portal, folder2_id) folder2.reindexObject() folder2UID = folder2.UID() # not enabled for now self.assertFalse(IFacetedNavigable.providedBy(folder2)) self.assertTrue(catalog(UID=folder2UID)) self.assertFalse(catalog(UID=folder2UID, object_provides=IFacetedNavigable.__identifier__)) enableFacetedDashboardFor(folder2) # several things are done : # faceted is enabled self.assertTrue(IFacetedNavigable.providedBy(folder2)) # used faceted layout is 'faceted-table-items' self.assertEquals(IFacetedLayout(folder2).layout, 'faceted-table-items') # left portlets are shown self.assertFalse(IHidePloneLeftColumn.providedBy(folder2)) # folder2 was reindexed, especially provided interfaces self.assertTrue(catalog(UID=folder2UID, object_provides=IFacetedNavigable.__identifier__)) # redirect is swallowed, indeed enabling faceted on a folder redirects to it self.assertEquals(self.portal.REQUEST.RESPONSE.status, 200) # a xmlpath parameter can be passed to use a specific widgets xml file # calling this on an already enabled faceted will do nothing xmlpath = os.path.dirname(__file__) + '/faceted_conf/testing_widgets.xml' enableFacetedDashboardFor(folder2, xmlpath=xmlpath) # only one 'c44' widget in testing_widgets.xml, not added here self.assertFalse(ICriteria(folder2).get('c44')) # create a new folder and apply faceted with xmlpath to it folder3_id = self.portal.invokeFactory('Folder', 'folder3', title='Folder3') folder3 = getattr(self.portal, folder3_id) folder3.reindexObject() # an Exception is raised if xmlpath does not exist wrong_xmlpath = os.path.dirname(__file__) + '/faceted_conf/wrong_testing_widgets.xml' self.assertRaises(Exception, enableFacetedDashboardFor, folder3, wrong_xmlpath) # apply correct xmlpath enableFacetedDashboardFor(folder3, xmlpath=xmlpath) # same things are done except that the widgets are taken from the given xmlpath self.assertEquals(len(ICriteria(folder3).criteria), 1) self.assertTrue(ICriteria(folder3).get('c44'))
def defaultForVocabulary(self, vocabulary): """ return the faceted nav default for a particular criteria """ for criterion in ICriteria(self.context).criteria: if criterion.vocabulary == vocabulary: return criterion.default return None
def query(self, form): """ Get value from form and return a catalog dict query """ query = {} # import ipdb; ipdb.set_trace() index = self.data.get("index", "") moreorless = self.data.get("moreorless", "") index = index.encode("utf-8", "replace") value = None if not index: return query if self.hidden: value = self.default else: value = form.get(self.data.getId(), "") if not value: return query # check if there are other criteria with same index second_value = None second_moreorless = None criteria = ICriteria(self.context) for cid, criterion in criteria.items(): if cid in form.keys() and cid != self.data.getId(): if criterion.index == index: second_value = form.get(cid) second_moreorless = criterion.moreorless value = int(value) # portal_catalog({'price':{'query':[2,1000],'range':'min:max'}}) if moreorless == u"more" and not second_value: range = "min" elif moreorless == u"less" and not second_value: range = "max" else: range = "min:max" if second_moreorless == u"more": value = [int(second_value), value] query[index] = {"query": value, "range": range} return query
def test_get_generation_context(self): """ Changes are about 'uids' and 'brains' that are added to the pod template generation context if possible if nothing particular is done, every elements of the displayed dashboard are added to the template generation context. """ # document-generator view is called outside dashboard from base viewlet gen_context = self.view._get_generation_context(self.helper, self.dashboardtemplate) self.assertIn('view', gen_context) self.assertNotIn('facetedQuery', gen_context) self.assertIn('details', gen_context) # document-generator view is called from dashboard viewlet self.request.form['facetedQuery'] = '' # order is respected so sort_on created # Date catalog queries are 1 minute sensitive... # make sure self.folder created is really older than self.folder2 self.folder.creation_date = DateTime('2015/01/01 12:00') self.folder.reindexObject() self.assertEquals(ICriteria(self.folder).get('c0').widget, u'sorting') self.request.form['c0[]'] = 'created' self.assertEqual(self.dashboardtemplate.max_objects, 500) gen_context = self.view._get_generation_context(self.helper, self.dashboardtemplate) self.assertTrue('uids' in gen_context) self.assertEquals(len(gen_context['uids']), 3) self.assertTrue('brains' in gen_context) self.assertEquals(len(gen_context['brains']), 3) self.dashboardtemplate.max_objects = 2 gen_context = self.view._get_generation_context(self.helper, self.dashboardtemplate) self.assertEquals(len(gen_context['uids']), 2) self.assertEquals(len(gen_context['brains']), 2) self.dashboardtemplate.max_objects = 3 gen_context = self.view._get_generation_context(self.helper, self.dashboardtemplate) self.assertEquals(len(gen_context['uids']), 3) self.assertEquals(len(gen_context['brains']), 3) self.assertEqual(gen_context['details'], '1') # brains are sorted according to uids list self.assertEquals(gen_context['uids'], [brain.UID for brain in gen_context['brains']]) # we have 3 elements in the dashboard : self.folder and self.folder2 self.assertListEqual(['Folder', 'Folder 2', 'Dashboard template'], [brain.Title for brain in gen_context['brains']]) # order of query is kept in brains self.request.form['reversed'] = 'on' gen_context = self.view._get_generation_context(self.helper, self.dashboardtemplate) self.assertListEqual(['Dashboard template', 'Folder 2', 'Folder'], [brain.Title for brain in gen_context['brains']])
def query(self, cid, **kwargs): """ Count catalog items """ # Cleanup query kwargs.pop('sort_on', None) kwargs.pop('sort_order', None) kwargs.pop('sort[]', None) kwargs.pop('sort', None) kwargs.pop('reversed[]', None) oid = '%s-operator' % cid operator = kwargs.pop(oid, kwargs.pop(oid + '[]', None)) if not operator or operator != 'and': kwargs.pop(cid, None) self.request.form.pop(cid, None) # jQuery >= 1.4 adds type to params keys # $.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4" # Let's fix this kwargs.pop(cid + '[]', None) self.request.form.pop(cid + '[]', None) criteria = ICriteria(self.context) criterion = criteria.get(cid) start = time.time() # Query catalog handler = getMultiAdapter((self.context, self.request), name=u'faceted_query') if criterion.get('index', '') == 'Language': kwargs['_language_count_'] = True kwargs['counter_query'] = True brains = handler.query(batch=False, sort=False, **kwargs) # Get index widget = criteria.widget(cid=cid)(self.context, self.request, criterion) count = getattr(widget, 'count', lambda brains: {}) res = count(brains) logger.debug('Benchmark %s: %s', cid, time.time() - start) return res
def _removeGroupsOfMatter(self): """Remove MeetingCategory.groupsOfMatter field and related.""" logger.info('Removing MeetingCategory.groupsOfMatter...') brains = self.portal.portal_catalog(meta_type='MeetingCategory') for brain in brains: cat = brain.getObject() if hasattr(cat, 'groupsOfMatter'): cat.setGroupsInCharge(cat.groupsOfMatter) delattr(cat, 'groupsOfMatter') else: self._already_migrated() return # remove portal_catalog index 'groupsOfMatter' self.removeUnusedIndexes(indexes=['groupsOfMatter']) # remove faceted filter for cfg in self.tool.objectValues('MeetingConfig'): # enable includeGroupsInChargeDefinedOnCategory so indexed groupsInCharge is correct cfg.setIncludeGroupsInChargeDefinedOnCategory(True) obj = cfg.searches.searches_items # update vocabulary for relevant filters criteria = ICriteria(obj) if criteria.get('c50'): criteria.delete('c50') # unselect 'c50' from dashboard filters and select 'c23' dashboardItemsListingsFilters = list(cfg.getDashboardItemsListingsFilters()) if 'c50' in dashboardItemsListingsFilters: dashboardItemsListingsFilters.remove('c50') dashboardItemsListingsFilters.append('c23') cfg.setDashboardItemsListingsFilters(dashboardItemsListingsFilters) dashboardMeetingAvailableItemsFilters = list(cfg.getDashboardMeetingAvailableItemsFilters()) if 'c50' in dashboardMeetingAvailableItemsFilters: dashboardMeetingAvailableItemsFilters.remove('c50') dashboardMeetingAvailableItemsFilters.append('c23') cfg.setDashboardMeetingAvailableItemsFilters(dashboardMeetingAvailableItemsFilters) dashboardMeetingLinkedItemsFilters = list(cfg.getDashboardMeetingLinkedItemsFilters()) if 'c50' in dashboardMeetingLinkedItemsFilters: dashboardMeetingLinkedItemsFilters.remove('c50') dashboardMeetingLinkedItemsFilters.append('c23') cfg.setDashboardMeetingLinkedItemsFilters(dashboardMeetingLinkedItemsFilters) logger.info('Done.')
def update_dashboards(self): # update daterange criteria brains = api.content.find( object_provides=IFacetedNavigable.__identifier__) for brain in brains: obj = brain.getObject() criterion = ICriteria(obj) for key, criteria in criterion.items(): if criteria.get("widget") != "daterange": continue if criteria.get("usePloneDateFormat") is True: continue logger.info( "Upgrade daterange widget for faceted {0}".format(obj)) position = criterion.criteria.index(criteria) values = criteria.__dict__ values["usePloneDateFormat"] = True values["labelStart"] = u'Start date' values["labelEnd"] = u'End date' criterion.criteria[position] = Criterion(**values) criterion.criteria._p_changed = 1
def query(self, cid, **kwargs): """ Count catalog items """ # Cleanup query kwargs.pop("sort_on", None) kwargs.pop("sort_order", None) kwargs.pop("sort[]", None) kwargs.pop("sort", None) kwargs.pop("reversed[]", None) oid = "%s-operator" % cid operator = kwargs.pop(oid, kwargs.pop(oid + "[]", None)) if not operator or operator != "and": kwargs.pop(cid, None) self.request.form.pop(cid, None) # jQuery >= 1.4 adds type to params keys # $.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4" # Let's fix this kwargs.pop(cid + "[]", None) self.request.form.pop(cid + "[]", None) criteria = ICriteria(self.context) criterion = criteria.get(cid) start = time.time() # Query catalog handler = getMultiAdapter((self.context, self.request), name=u"faceted_query") if criterion.get("index", "") == "Language": kwargs["_language_count_"] = True brains = handler.query(batch=False, sort=False, **kwargs) # Get index widget = criteria.widget(cid=cid)(self.context, self.request, criterion) count = getattr(widget, "count", lambda brains: {}) res = count(brains) logger.debug("Benchmark %s: %s", cid, time.time() - start) return res
def edit(self, cid, **kwargs): """ See IFacetedCriterionHandler """ kwargs = self._request_form(kwargs) criteria = ICriteria(self.context) widget = criteria.widget(cid=cid) fields = widget.edit_schema.keys()[:] update = {} for prop in fields: new_value = kwargs.get(prop, None) if new_value is None: continue update[prop] = new_value if update: criteria.edit(cid, **update) if widget.hidden: notify(FacetedGlobalSettingsChangedEvent(self.context)) elif set(['hidden', 'operator']).intersection(update.keys()): notify(FacetedGlobalSettingsChangedEvent(self.context)) return self._redirect('Changes saved')
class DatasetsCollectionListView(BrowserView): title = u"Collections" def __init__(self, context, request): # TODO: update this to new workings of collection facet (now that we have a custom portal_type) super(DatasetsCollectionListView, self).__init__(context, request) self.datasets_url = self.context.absolute_url() self.criteria = ICriteria(self.context, {}) self.defaults = {} self.criterion = None for criterion in self.criteria.values(): if criterion.widget == 'pathselect': self.criterion = criterion if criterion.widget == 'sorting': default = criterion.default if not default: continue if '(reverse)' in default: default = default.replace('(reverse)', '', 1) self.defaults['reversed'] = True self.defaults[criterion.getId()] = default def categories(self): for term in getUtility(IVocabularyFactory, 'collection_category_source')(self.context): yield term def get_browse_link(self, uuid): # return link into datasets facetedview to filter given collection collection = uuidToCatalogBrain(uuid) if not collection: return self.datasets_url params = dict(self.defaults) if self.criterion: params[self.criterion.getId()] = collection.UID return "{}#{}".format(self.datasets_url, urlencode(params)) # fallback to original datasets_listing_view groupid = collection.getObject().__parent__.getId() params['datasets.filter.source:list'] = '{}-{}'.format(self.datesets_url, groupid, collection.getId) return "{}/?{}" . format(self.datasets_url, urlencode(params))
def installFacetedNavigation(obj, event): if not ISecretomeFolder.providedBy(obj): return factory = getToolByName(obj, 'portal_factory') if factory.isTemporary(obj): return request = obj.REQUEST subtyper = getMultiAdapter((obj, request), name=u'faceted_subtyper') if subtyper.is_faceted or not subtyper.can_enable: return subtyper.enable() criteria = ICriteria(obj) for cid in criteria.keys(): criteria.delete(cid) criteria.add('resultsperpage', 'bottom', 'default', title='Results per page', hidden=True, start=0, end=50, step=5, default=20) criteria.add( 'checkbox', 'bottom', 'default', title='Obj provides', hidden=True, index='object_provides', operator='or', vocabulary=u'eea.faceted.vocabularies.ObjectProvides', default=[IGeneProtein.__identifier__], count=False, maxitems=0, sortreversed=False, hidezerocount=False ) criteria.add('debug', 'top', 'default', title='Debug Criteria', user='******') criteria.add( 'checkbox', 'left', 'default', title=u'Databases', hidden=False, index='databaseNames', operator='or', vocabulary=u'eke.secretome.DatabaseNamesVocabulary', count=False, maxitems=0, sortreversed=False, hidezerocount=False ) IFacetedLayout(obj).update_layout(u'faceted_secretome_view') noLongerProvides(obj, IHidePloneLeftColumn)
def setFacetedNavigation(folder, request, force=False): subtyper = getMultiAdapter((folder, request), name=u'faceted_subtyper') if (subtyper.is_faceted or not subtyper.can_enable) and not force: return subtyper.enable() urlTool = plone.api.portal.get_tool(name='portal_url') path = '/' + '/'.join(urlTool.getRelativeContentPath(folder)) criteria = ICriteria(folder) for cid in criteria.keys(): criteria.delete(cid) criteria.add( 'checkbox', 'left', 'default', title=u'Organ', hidden=False, index='indicatedBodySystems', operator='or', vocabulary=u'eke.biomarker.IndicatedOrgansVocabulary', count=False, maxitems=0, sortreversed=False, hidezerocount=False, ) criteria.add('resultsperpage', 'bottom', 'default', title='Results per page', hidden=True, start=0, end=50, step=5, default=20) criteria.add('sorting', 'bottom', 'default', title='Sort on', hidden=True, default='sortable_title') criteria.add( 'checkbox', 'bottom', 'default', title='Obj provides', hidden=True, index='object_provides', operator='or', vocabulary=u'eea.faceted.vocabularies.ObjectProvides', default=[IBiomarker.__identifier__], count=False, maxitems=0, sortreversed=False, hidezerocount=False ) criteria.add('path', 'bottom', 'default', title='Path Search', hidden=True, index='path', default=path) criteria.add('text', 'top', 'default', title=u'Search', hidden=False, index='SearchableText', count=False, onlyallelements=True) IFacetedLayout(folder).update_layout('faceted_biomarkers_view') noLongerProvides(folder, IHidePloneLeftColumn) noLongerProvides(folder, IHidePloneRightColumn)
def setFacetedNavigation(folder, request): subtyper = getMultiAdapter((folder, request), name=u'faceted_subtyper') if subtyper.is_faceted or not subtyper.can_enable: return subtyper.enable() urlTool = getToolByName(folder, 'portal_url') path = '/' + '/'.join(urlTool.getRelativeContentPath(folder)) criteria = ICriteria(folder) for cid in criteria.keys(): criteria.delete(cid) criteria.add('resultsperpage', 'bottom', 'default', title='Results per page', hidden=True, start=0, end=50, step=5, default=20) criteria.add('sorting', 'bottom', 'default', title='Sort on', hidden=True, default='sortable_title') criteria.add( 'checkbox', 'left', 'default', title='System', hidden=False, index='getSystemName', operator='or', vocabulary=u'eke.specimens.vocab.SystemNames', count=False, maxitems=0, sortreversed=False, hidezerocount=False, ) criteria.add( 'checkbox', 'left', 'default', title='Diagnosis', hidden=False, index='diagnosis', operator='or', vocabulary=u'eke.specimens.vocab.Diagnoses', count=False, maxitems=0, sortreversed=False, hidezerocount=False, ) criteria.add( 'checkbox', 'left', 'default', title='Storage', hidden=False, index='getStorageType', operator='or', vocabulary=STORAGE_VOCAB_NAME, count=False, maxitems=5, sortreversed=False, hidezerocount=False, ) criteria.add( 'checkbox', 'left', 'default', title='Collection Type', hidden=False, index='collectionType', operator='or', vocabulary=COLLECTION_VOCAB_NAME, count=False, maxitems=5, sortreversed=False, hidezerocount=False, ) criteria.add( 'checkbox', 'left', 'default', title='Site', hidden=False, index='siteName', operator='or', vocabulary=u'eke.specimens.vocab.SitesWithSpecimens', count=False, maxitems=5, sortreversed=False, hidezerocount=False, ) criteria.add( 'checkbox', 'bottom', 'default', title='Obj provides', hidden=True, index='object_provides', operator='or', vocabulary=u'eea.faceted.vocabularies.ObjectProvides', default=[ISpecimenSet.__identifier__], count=False, maxitems=0, sortreversed=False, hidezerocount=False ) criteria.add( 'text', 'center', 'default', title='Open Search', hidden=False, index='SearchableText', ) criteria.add('path', 'bottom', 'default', title='Path Search', hidden=True, index='path', default=path) IFacetedLayout(folder).update_layout('faceted_specimens_view') alsoProvides(folder, IHidePloneRightColumn)
class CollectionWidget(RadioWidget): """A widget listing collections used as base query.""" widget_type = 'collection-link' widget_label = 'Collection Link' faceted_field = False index = ViewPageTemplateFile('widget.pt') css_class = 'faceted-tagscloud-collection-widget' category_vocabulary = ( 'collective.eeafaceted.collectionwidget.collectioncategoryvocabulary' ) def __init__(self, context, request, data=None): super(CollectionWidget, self).__init__(context, request, data) # real context could not be current context but some distant context # look in eea.facetednavigation.criteria.handler.Criteria self.criteria = ICriteria(self.context) self.context = self.criteria.context # display the fieldset around the widget when rendered? self.display_fieldset = True def update(self): """Remove fields 'index' and 'catalog', unused.""" super(CollectionWidget, self).update() default_group = self.groups[0] if 'index' in default_group.fields: del default_group.fields['index'] if 'catalog' in default_group.widgets: del default_group.fields['catalog'] if 'index' in default_group.widgets: del default_group.widgets['index'] if 'catalog' in default_group.widgets: del default_group.widgets['catalog'] def _initialize_widget(self): """ """ self.grouped_vocabulary = self._generate_vocabulary() def __call__(self, **kwargs): # compute the vocabulary used in the widget self._initialize_widget() return super(CollectionWidget, self).__call__(**kwargs) def query(self, form): """ Get value from form and return a catalog dict query """ # we receive the UID of the selected Collection # get the collection, compute the query and return it collection_uid = form.get(self.data.__name__, '') if collection_uid and not collection_uid == 'all': # get the collection and compute the query catalog = getToolByName(self.context, 'portal_catalog') brains = catalog(UID=collection_uid) collection = brains[0].getObject() query = queryparser.parseFormquery(collection, collection.query) # use sort_on defined on the collection if it is # not already in the request.form # get the sort_on criterion and look in the request.form if it is used sort_on_is_used = False for criterion_id, criterion in self.criteria.items(): if criterion.widget == SortingWidget.widget_type: # criterion id in the request.form is like c0[] if "{0}[]".format(criterion_id) in self.request.form: sort_on_is_used = True break if not sort_on_is_used: if collection.sort_on: query['sort_on'] = collection.sort_on if collection.sort_reversed: query['sort_order'] = collection.sort_reversed and 'descending' or '' return query return {} def count(self, brains, sequence=None): """ """ res = {} if not sequence: sequence = [term.token for term in self.vocabulary()] catalog = getToolByName(self.context, 'portal_catalog') for value in sequence: if not value: res[value] = len(brains) continue res[value] = len( catalog(self.query(form={self.data.__name__: value}))) return res @property @memoize def default(self): """Return the default value""" default = super(CollectionWidget, self).default if not default: # it is possible to not select a default, it will have # same behaviour as selecting option "All" return default # call an adapter to get the correct value return self.adapter_default_value @property def adapter_default_value(self): adapter = queryMultiAdapter((self.context, self.request, self), IWidgetDefaultValue) if adapter: return adapter.value @property def default_term_value(self): idx = self.sortreversed and -1 or 0 terms = self.portal_vocabulary() if len(terms) > 0: return terms[idx][0] def kept_criteria_as_json(self, collection_uid): '''Given a p_collectionUID, get indexes managed by the collection.''' adapter = queryMultiAdapter((self.context, self), IKeptCriteria) res = adapter.compute(collection_uid) # DateTime are not json serializable, we convert them before for k, v in res.iteritems(): if isinstance(v, DateTime): res[k] = v.ISO() return json.dumps(res) @property def advanced_criteria(self): '''Returns a dict containing advanced criteria, the key is the criterion id and the value is the managed index.''' faceted_config = queryMultiAdapter((self.context, self.request), name='configure_faceted.html') advanced_criteria = {} for criterion in faceted_config.get_criteria(): if criterion.section == u'advanced': advanced_criteria[criterion.getId()] = criterion.index return advanced_criteria @property def advanced_criteria_as_json(self): return json.dumps(self.advanced_criteria.keys()) @property def sortreversed(self): return bool(int(getattr(self.data, 'sortreversed', u'0') or u'0')) @property def hidealloption(self): return bool(int(getattr(self.data, 'hidealloption', u'0') or u'0')) @property @memoize def categories(self): factory = getUtility(IVocabularyFactory, self.category_vocabulary) voc = factory(self.context) return voc def vocabulary(self): voc_id = self.data.get('vocabulary', None) voc = queryUtility(IVocabularyFactory, voc_id, None) if voc is None: return [] return list(voc(self.context)) def _generate_vocabulary(self): voc = OrderedDict() # empty category voc[''] = {'collections': []} for term in self.categories: voc[term.token] = {'term': term, 'collections': []} categories_token = [term.token for term in self.categories] for term in self.vocabulary(): parent = aq_parent(term.value) # collections directly added to context, no intermediate category if parent == self.context and parent.UID() not in categories_token: category = '' elif parent.UID() in categories_token: category = parent.UID() else: # parent is not visible, a subfolder private for current user continue voc[category]['collections'].append(term) # remove empty categories res = OrderedDict() for k, v in voc.items(): if v['collections']: res[k] = v return res
def test_with_sub_faceted(self): """Test behaviour of the vocabulary when we have subfolders with activated faceted navigation.""" # add collection to self.folder c1 = api.content.create( id='collection1', type='DashboardCollection', title='Collection 1', container=self.folder, tal_condition=u'', roles_bypassing_talcondition=[], ) c2 = api.content.create( id='collection2', type='DashboardCollection', title='Collection 2', container=self.folder, tal_condition=u'', roles_bypassing_talcondition=[], ) # create a subfolder, add collections into it api.content.create( id='subfolder', type='Folder', title='Subfolder', container=self.folder ) c3 = api.content.create( id='collection3', type='DashboardCollection', title='Collection 3', container=self.folder.subfolder, tal_condition=u'', roles_bypassing_talcondition=[], ) c4 = api.content.create( id='collection4', type='DashboardCollection', title='Collection 4', container=self.folder.subfolder, tal_condition=u'', roles_bypassing_talcondition=[], ) # for now, faceted navigation is not enabled on subfolder, # it behaves like a normal category vocabulary = CollectionVocabularyFactory(self.folder) folderCatVocabulary = CollectionCategoryVocabularyFactory(self.folder) subfolderCatVocabulary = CollectionCategoryVocabularyFactory(self.folder.subfolder) self.assertTrue(folderCatVocabulary.by_token.keys() == subfolderCatVocabulary.by_token.keys()) # redirect_to is not filled self.assertFalse(vocabulary.getTermByToken(c1.UID()).title[1]) self.assertFalse(vocabulary.getTermByToken(c2.UID()).title[1]) self.assertFalse(vocabulary.getTermByToken(c3.UID()).title[1]) self.assertFalse(vocabulary.getTermByToken(c4.UID()).title[1]) # now enable faceted navigation for subfolder subtyper = getMultiAdapter((self.folder.subfolder, self.request), name=u'faceted_subtyper') subtyper.enable() # change the CollectionWidget id to "c44" so we are sure that # the generated link is the one to this widget collection_widget = ICriteria(self.folder.subfolder).get('c1') self.assertEquals(collection_widget.widget, CollectionWidget.widget_type) collection_widget.__name__ = u'c44' vocabulary = CollectionVocabularyFactory(self.folder) folderCatVocabulary = CollectionCategoryVocabularyFactory(self.folder) subfolderCatVocabulary = CollectionCategoryVocabularyFactory(self.folder.subfolder) self.assertTrue(folderCatVocabulary.by_token.keys() == subfolderCatVocabulary.by_token.keys()) # as we are getting the vocabulary on self.folder, # redirect_to is filled for collections of subfolder # while generating links to specific sub faceted, a 'no_redirect' is added # so the user is not redirected to the faceted using the default self.assertFalse(vocabulary.getTermByToken(c1.UID()).title[1]) self.assertFalse(vocabulary.getTermByToken(c2.UID()).title[1]) self.assertEquals(vocabulary.getTermByToken(c3.UID()).title[1], '{0}?no_redirect=1#c44={1}'.format(self.folder.subfolder.absolute_url(), c3.UID()) ) self.assertEquals(vocabulary.getTermByToken(c4.UID()).title[1], '{0}?no_redirect=1#c44={1}'.format(self.folder.subfolder.absolute_url(), c4.UID()) ) # if we get vocabulary from subfolder, it works the other way round # but moreover, we have a no_redirect=1 that avoid to redirect if we # are sending the user to the root folder of the faceted navigation vocabulary = CollectionVocabularyFactory(self.folder.subfolder) folderCatVocabulary = CollectionCategoryVocabularyFactory(self.folder) subfolderCatVocabulary = CollectionCategoryVocabularyFactory(self.folder.subfolder) self.assertTrue(folderCatVocabulary.by_token.keys() == subfolderCatVocabulary.by_token.keys()) self.assertEquals(vocabulary.getTermByToken(c1.UID()).title[1], '{0}?no_redirect=1#c1={1}'.format(self.folder.absolute_url(), c1.UID()) ) self.assertEquals(vocabulary.getTermByToken(c2.UID()).title[1], '{0}?no_redirect=1#c1={1}'.format(self.folder.absolute_url(), c2.UID()) ) self.assertFalse(vocabulary.getTermByToken(c3.UID()).title[1]) self.assertFalse(vocabulary.getTermByToken(c4.UID()).title[1]) # test the generated link when having a faceted using a sorting index reversed or not data = {'default': u'effective(reverse)'} sortingCriterionId = ICriteria(self.folder).add('sorting', 'bottom', **data) vocabulary = CollectionVocabularyFactory(self.folder.subfolder) self.assertEquals(vocabulary.getTermByToken(c1.UID()).title[1], '{0}?no_redirect=1#c1={1}&c5=effective&reversed=on'.format(self.folder.absolute_url(), c1.UID())) data = {'default': u'effective'} ICriteria(self.folder).edit(sortingCriterionId, **data) vocabulary = CollectionVocabularyFactory(self.folder.subfolder) self.assertEquals(vocabulary.getTermByToken(c1.UID()).title[1], '{0}?no_redirect=1#c1={1}&c5=effective'.format(self.folder.absolute_url(), c1.UID())) # test that other default values are kept also, add a 'resultsperpage' widget data = {'default': u'20'} ICriteria(self.folder).add('resultsperpage', 'bottom', **data) vocabulary = CollectionVocabularyFactory(self.folder.subfolder) self.assertEquals(vocabulary.getTermByToken(c1.UID()).title[1], '{0}?no_redirect=1#c1={1}&c5=effective&c6=20'.format(self.folder.absolute_url(), c1.UID()))
def createMembersListSearchPage(portal): '''Create the members list page''' # New in profile version 1 (software version 1.0.2): request = portal.REQUEST if 'members-list' in portal.objectIds(): portal.manage_delObjects('members-list') membersList = portal[portal.invokeFactory('Folder', 'members-list')] membersList.setTitle('Members List') membersList.setDescription('A directory of the people that comprise EDRN.') membersList.setExcludeFromNav(True) _doPublish(membersList, getToolByName(portal, 'portal_workflow')) subtyper = getMultiAdapter((membersList, request), name=u'faceted_subtyper') subtyper.enable() layout = IFacetedLayout(membersList) layout.update_layout('folder_listing') criteria = ICriteria(membersList) for cid in criteria.keys(): criteria.delete(cid) criteria.add('resultsperpage', 'bottom', 'default', title='Results per page', hidden=True, start=0, end=50, step=5, default=20) criteria.add('sorting', 'bottom', 'default', title='Sort on', hidden=True, default='sortable_title') criteria.add( 'checkbox', 'bottom', 'default', title='Obj provides', hidden=True, index='object_provides', operator='or', vocabulary=u'eea.faceted.vocabularies.ObjectProvides', default=[IPerson.__identifier__], count=False, maxitems=0, sortreversed=False, hidezerocount=False ) criteria.add( 'checkbox', 'left', 'default', title='Investigator', hidden=False, index='piUID', operator='or', vocabulary=u'eke.site.PrincipalInvestigators', count=False, maxitems=4, sortreversed=False, hidezerocount=False ) criteria.add( 'checkbox', 'left', 'default', title='Type', index='investigatorStatus', operator='or', vocabulary=u'eke.site.NotPeons', count=True, maxitems=0, sortreversed=False, hidezerocount=False ) criteria.add( 'checkbox', 'left', 'default', title='Institution', hidden=False, index='siteName', operator='or', vocabulary=u'eke.site.SitesNames', count=True, maxitems=4, sortreversed=False, hidezerocount=False ) criteria.add( 'checkbox', 'left', 'default', title='Member Type', hidden=False, index='memberType', operator='or', vocabulary=u'eke.site.MemberType', count=True, maxitems=20, sortreversed=False, hidezerocount=False ) criteria.add('criteria', 'top', 'default', title='Current Search') membersList.reindexObject()