def marshall(self): """Marshall properties, contained items and related items.""" self.marshall_myself() content_type = self.structure.portal_type if self.context.portal_type == content_type: logger.info('Portal type provided by Object') context = [self.context] else: context = [] logger.info('Portal type not provided by Object. Find Subelements') if IFolderish.providedBy(self.context): for id, item in self.context.contentItems(): context.append(item) logger.info('Found {title}'.format(title=item.title)) for element in context: self.marshall_properties(element) self.marshall_references(element) self.marshall_contained(element) try: ICollection(element) self.marshall_collection(element) except TypeError: pass self.resource.update() self.resource.save()
def tabular_fields(self): """Returns a list of all metadata fields from the catalog that were selected. """ context = aq_inner(self.context) fields = ICollection(context).selectedViewFields() fields = [field[0] for field in fields] return fields
def test_migrate_topic_fields(self): self.portal.topic.setText('<p>Hello</p>') self.portal.topic.setLimitNumber(True) self.portal.topic.setItemCount(42) self.portal.topic.setCustomViewFields(('Title', 'Type')) applyProfile(self.portal, 'plone.app.contenttypes:default') self.run_migration() new = ICollection(self.portal.topic) self.assertEqual(self.portal.topic.portal_type, 'Collection') self.assertEqual(new.limit, 42) self.assertEqual(new.customViewFields, ('Title', 'Type'))
def migrate_schema_fields(self): # migrate the richtext super(CollectionMigrator, self).migrate_schema_fields() # migrate the rest of the schema into the behavior wrapped = ICollection(self.new) wrapped.query = self.old.query wrapped.sort_on = self.old.sort_on wrapped.sort_reversed = self.old.sort_reversed wrapped.limit = self.old.limit wrapped.customViewFields = self.old.customViewFields
def migrate_schema_fields(self): migrate_richtextfield(self.old, self.new, 'text', 'text') wrapped_new = ICollection(self.new) # using migrate_simplefield on 'query' returns the ContentListing obj wrapped_new.query = self.old.query migrate_simplefield(self.old, wrapped_new, 'sort_on', 'sort_on') migrate_simplefield(self.old, wrapped_new, 'sort_reversed', 'sort_reversed') migrate_simplefield(self.old, wrapped_new, 'limit', 'limit') migrate_simplefield(self.old, wrapped_new, 'customViewFields', 'customViewFields')
def tabular_fields(self): """ Returns a list of all metadata fields from the catalog that were selected. """ context = aq_inner(self.context) wrapped = ICollection(context) fields = wrapped.selectedViewFields() fields = [field[0] for field in fields] fields.append('report_url') return fields
def results(self, **kwargs): """ Helper to get the results from the collection-behavior. The template collectionvew.pt calls the standard_view of collections as a macro and standard_view uses python:view.results(b_start=b_start) to get the reusults. When used as a macro 'view' is this view instead of the CollectionView. """ if COLLECTION_IS_BEHAVIOR: context = aq_inner(self.context) wrapped = ICollection(context) return wrapped.results(**kwargs) else: return self.context.results(**kwargs)
def __init__(self, context): """Adapt either collections or contentlisting tile. The name is sorted content selector""" self.context = context self.selectContent("") # get first tile if self.tile is None: # Could still be a ILayoutAware collection try: self.collection = ICollection(self.context) except TypeError: self.collection = None else: self.collection = self.tile # to get properties
def test_migrate_simple_topic(self): self.assertEqual(self.portal.topic.portal_type, 'Topic') self.assertEqual(self.portal.topic.getLayout(), 'atct_topic_view') self.assertEqual(self.portal.topic.getLimitNumber(), False) self.assertEqual(self.portal.topic.getItemCount(), 0) self.assertEqual(self.portal.topic.getCustomViewFields(), ('Title',)) applyProfile(self.portal, 'plone.app.contenttypes:default') self.run_migration() new = ICollection(self.portal.topic) self.assertEqual(self.portal.topic.portal_type, 'Collection') self.assertEqual(self.portal.topic.getLayout(), 'listing_view') self.assertEqual(new.sort_on, None) self.assertEqual(new.sort_reversed, None) self.assertEqual(new.limit, 1000) self.assertEqual(new.customViewFields, ('Title',))
def locations(self): custom_query = {} # Additional query to filter the collection collection = uuidToObject(self.settings.target_collection) if not collection: return None # Recursively transform all to unicode request_params = safe_decode(self.top_request.form or {}) # Get all collection results with additional filter # defined by urlquery custom_query = base_query(request_params) custom_query = make_query(custom_query) return ICollection(collection).results(batch=False, brains=True, custom_query=custom_query)
def marshall_collection(self, context): """Get content from the collection behavior and marshall it""" collection = ICollection(context) for entry in collection.results(): item = entry.getObject() collection_marshaller = queryMultiAdapter( (item, self.marshall_target), interface=IMarshallSource, default=DX2Any(item, self.marshall_target), ) if collection_marshaller: collection_marshaller.marshall() rdf_type = IStructure(item).predicate self.marshall_target.set_link( self.resource, rdf_type, collection_marshaller.resource, )
def migrate_criteria(self): """Migrate old style to new style criteria. Plus handling for some special fields. """ # The old Topic has boolean limitNumber and integer itemCount, # where the new Collection only has limit. adapted = ICollection(self.new) if self.old.getLimitNumber(): adapted.limit = self.old.getItemCount() adapted.customViewFields = self.old.getCustomViewFields() # Get the old data stored by the beforeChange_criteria method. if self._collection_sort_reversed is not None: adapted.sort_reversed = self._collection_sort_reversed if self._collection_sort_on is not None: adapted.sort_on = self._collection_sort_on if self._collection_query is not None: adapted.query = self._collection_query
def __init__(self, context, request): super(EventListing, self).__init__(context, request) self.now = now = localized_now(context) # Try to get the default page default = getDefaultPage(context) self.default_context = context[default] if default else context self.is_collection = False if ICollection: self.is_collection = ICollection.providedBy(self.default_context) # Request parameter req = self.request.form b_size = int(req.get('b_size', 0)) if not b_size and self.is_collection: collection_behavior = ICollection(self.default_context) b_size = getattr(collection_behavior, 'item_count', 0) self.b_size = b_size or 10 self.b_start = int(req.get('b_start', 0)) self.orphan = int(req.get('orphan', 1)) self.mode = req.get('mode', None) self._date = req.get('date', None) self.tags = req.get('tags', None) self.searchable_text = req.get('SearchableText', None) self.path = req.get('path', None) day = int(req.get('day', 0)) or None month = int(req.get('month', 0)) or None year = int(req.get('year', 0)) or None if not self._date and day or month or year: self._date = date(year or now.year, month or now.month, day or now.day).isoformat() if self.mode is None: self.mode = 'day' if self._date else 'future' self.uid = None # Used to get all occurrences from a single event. Overrides all other settings # noqa
def update(self): slider_type = self.context.slider_type self.slider_title = self.context.slider_title related = [] if slider_type == u'criteria': related = ICollection(self.context).results() elif slider_type == u'related': related = [ o.to_object for o in self.context.relatedItems if not o.isBroken() ] def getUid(obj): uid = getattr(obj, 'UID', None) if callable(uid): uid = uid() return uid this_uid = self.context.UID() self.related_content = [r for r in related if getUid(r) != this_uid]
def __init__(self, context): self.context = context self.collection = ICollection(self.context)
def __init__(self, *args, **kwargs): super(CollectionView, self).__init__(*args, **kwargs) context = aq_inner(self.context) self.collection_behavior = ICollection(context) self.b_size = self.collection_behavior.item_count
def get_filter_items(target_collection, group_by, filter_type=DEFAULT_FILTER_TYPE, narrow_down=False, show_count=False, view_name='', cache_enabled=True, request_params=None): request_params = request_params or {} custom_query = {} # Additional query to filter the collection collection = uuidToObject(target_collection) if not collection or not group_by: return None collection_url = collection.absolute_url() # Recursively transform all to unicode request_params = safe_decode(request_params) # Support for the Event Listing view from plone.app.event collection_layout = collection.getLayout() default_view = collection.restrictedTraverse(collection_layout) if isinstance(default_view, EventListing): mode = request_params.get('mode', 'future') date = request_params.get('date', None) date = guess_date_from(date) if date else None start, end = start_end_from_mode(mode, date, collection) start, end = _prepare_range(collection, start, end) custom_query.update(start_end_query(start, end)) # TODO: expand events. better yet, let collection.results # do that # Get index in question and the current filter value of this index, if set. groupby_criteria = getUtility(IGroupByCriteria).groupby idx = groupby_criteria[group_by]['index'] current_idx_value = safe_iterable(request_params.get(idx)) extra_ignores = [] if not narrow_down: # Additive filtering is about adding other filter values of the same # index. extra_ignores = [idx, idx + '_op'] urlquery = base_query(request_params, extra_ignores) # Get all collection results with additional filter defined by urlquery custom_query.update(urlquery) custom_query = make_query(custom_query) catalog_results = ICollection(collection).results( batch=False, brains=True, custom_query=custom_query) if narrow_down and show_count: # we need the extra_ignores to get a true count # even when narrow_down filters the display of indexed values # count_query allows us to do that true count count_query = {} count_urlquery = base_query(request_params, [idx, idx + '_op']) count_query.update(count_urlquery) catalog_results_fullcount = ICollection(collection).results( batch=False, brains=True, custom_query=count_query) if not catalog_results: return None # Attribute name for getting filter value from brain metadata_attr = groupby_criteria[group_by]['metadata'] # Optional modifier to set title from filter value display_modifier = groupby_criteria[group_by].get('display_modifier', None) # CSS modifier to set class on filter item css_modifier = groupby_criteria[group_by].get('css_modifier', None) # Value blacklist value_blacklist = groupby_criteria[group_by].get('value_blacklist', None) # Allow value_blacklist to be callables for runtime-evaluation value_blacklist = value_blacklist() if callable( value_blacklist) else value_blacklist # noqa # fallback to title sorted values sort_key_function = groupby_criteria[group_by].get( 'sort_key_function', lambda it: it['title'].lower()) grouped_results = {} for brain in catalog_results: # Get filter value val = getattr(brain, metadata_attr, None) if callable(val): val = val() # decode it to unicode val = safe_decode(val) # Make sure it's iterable, as it's the case for e.g. the subject index. val = safe_iterable(val) for filter_value in val: if filter_value is None or isinstance(filter_value, Missing): continue if value_blacklist and filter_value in value_blacklist: # Do not include blacklisted continue if filter_value in grouped_results: # Add counter, if filter value is already present grouped_results[filter_value]['count'] += 1 continue # Set title from filter value with modifications, # e.g. uuid to title title = filter_value if filter_value is not EMPTY_MARKER and callable(display_modifier): title = safe_decode(display_modifier(filter_value)) # Build filter url query _urlquery = urlquery.copy() # Allow deselection if filter_value in current_idx_value: _urlquery[idx] = [ it for it in current_idx_value if it != filter_value ] elif filter_type != 'single': # additive filter behavior _urlquery[idx] = current_idx_value + [filter_value] _urlquery[idx + '_op'] = filter_type # additive operator else: _urlquery[idx] = filter_value query_param = urlencode(safe_encode(_urlquery), doseq=True) url = '/'.join([ it for it in [ collection_url, view_name, '?' + query_param if query_param else None ] if it ]) # Set selected state selected = filter_value in current_idx_value css_class = 'filterItem {0}{1} {2}'.format( 'filter-' + idnormalizer.normalize(filter_value), ' selected' if selected else '', css_modifier(filter_value) if css_modifier else '', ) grouped_results[filter_value] = { 'title': title, 'url': url, 'value': filter_value, 'css_class': css_class, 'count': 1, 'selected': selected } # Entry to clear all filters urlquery_all = { k: v for k, v in list(urlquery.items()) if k not in (idx, idx + '_op') } if narrow_down and show_count: catalog_results = catalog_results_fullcount ret = [{ 'title': translate(_('subject_all', default=u'All'), context=getRequest()), 'url': u'{0}/?{1}'.format(collection_url, urlencode(safe_encode(urlquery_all), doseq=True)), 'value': 'all', 'css_class': 'filterItem filter-all', 'count': len(catalog_results), 'selected': idx not in request_params }] grouped_results = list(grouped_results.values()) if callable(sort_key_function): grouped_results = sorted(grouped_results, key=sort_key_function) ret += grouped_results return ret
def limit(self): limit = ICollection(self.context).limit return limit
def _brains(self): return ICollection(self.context).results(batch=False)[:self.limit]
def collection_behavior(self): return ICollection(aq_inner(self.context))