Skip to content

Commit

Permalink
Merge pull request #154 from collective/collectionish-tile-targets
Browse files Browse the repository at this point in the history
Add a module global COLLECTIONISH_TARGETS
  • Loading branch information
jensens committed Mar 25, 2022
2 parents 1bd5c14 + 97eae45 commit 6cad72f
Show file tree
Hide file tree
Showing 13 changed files with 121 additions and 57 deletions.
19 changes: 19 additions & 0 deletions CHANGES.rst
Expand Up @@ -14,8 +14,26 @@ Breaking Change:
needs to expect this parameter too!
[MrTango]

Features:

- Add checkbox to reverse output the filters.
[jensens]

- Support and Test Plone 6.
[jensens]

- Add a module global COLLECTIONISH_TARGETS to c.c.tiles to register other tiles with collections than plone.app.standardtiles.contentlisting.
[jensens]

Bug Fixes:

- Not every metadata entry has an index with same name.
Ignore if not a pair.
[jensens]

- Fix/Workaround for #59 (Int fields in indexes are not working).
[jensens]

- Hide uninstall profiles from install view.
[jensens]

Expand All @@ -28,6 +46,7 @@ Bug Fixes:
- Fixed searches for only non-alphanumeric characters causing an exception to be displayed.
[JeffersonBledsoe]


Other:

- Code-Style Black and Isort
Expand Down
12 changes: 0 additions & 12 deletions base.cfg
Expand Up @@ -17,18 +17,6 @@ plone.batching = >=1.1.7
# plone.app.standardtiles = 2.3.1 # fix https://github.com/plone/plone.app.standardtiles/issues/111
pycodestyle =

# Robot Testing (see buildout.coredev[5.2]/versions.cfg)
plone.app.robotframework = 1.5.4
robotframework = 3.1.2
robotframework-python3 = 2.9
robotframework-debuglibrary = 1.2.1
robotframework-ride = 1.7.4.1
robotframework-seleniumlibrary = 3.3.1
robotframework-selenium2library = 3.0.0
robotframework-selenium2screenshots = 0.8.1
robotsuite = 2.2.1
selenium = 3.141.0

[versions:python27]
# to get codeanalysis working
build = 0.1
Expand Down
2 changes: 1 addition & 1 deletion requirements-5.2.x.txt
@@ -1 +1 @@
-r https://dist.plone.org/release/5.2-latest/requirements.txt
-r https://dist.plone.org/release/5.2-latest/requirements.txt
2 changes: 1 addition & 1 deletion requirements-6.0.x.txt
@@ -1 +1 @@
-r https://dist.plone.org/release/6.0-latest/requirements.txt
-r https://dist.plone.org/release/6.0-latest/requirements.txt
9 changes: 4 additions & 5 deletions src/collective/collectionfilter/baseviews.py
Expand Up @@ -130,13 +130,11 @@ class BaseFilterView(BaseView):
def input_type(self):
if self.settings.input_type == "links":
return "link"
elif self.settings.filter_type == "single":
if self.settings.filter_type == "single":
if self.settings.input_type == "checkboxes_radiobuttons":
return "radio"
else:
return "dropdown"
else:
return "checkbox"
return "dropdown"
return "checkbox"

# results is called twice inside the template in view/available and view/results. But its expensive so we cache it
# but just the the lifetime of the view
Expand All @@ -152,6 +150,7 @@ def results(self):
cache_enabled=self.settings.cache_enabled,
request_params=self.top_request.form or {},
content_selector=self.settings.content_selector,
reverse=self.settings.reverse,
)
return results

Expand Down
12 changes: 11 additions & 1 deletion src/collective/collectionfilter/filteritems.py
Expand Up @@ -42,6 +42,7 @@ def _build_url(
):
# 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]
Expand Down Expand Up @@ -105,6 +106,7 @@ def _results_cachekey(
cache_enabled=True,
request_params=None,
content_selector="",
reverse=False,
):
if not cache_enabled:
raise DontCache
Expand All @@ -117,6 +119,7 @@ def _results_cachekey(
view_name,
request_params,
content_selector,
reverse,
" ".join(plone.api.user.get_roles()),
plone.api.portal.get_current_language(),
str(plone.api.portal.get_tool("portal_catalog").getCounter()),
Expand All @@ -135,6 +138,7 @@ def get_filter_items(
cache_enabled=True,
request_params=None,
content_selector="",
reverse=False,
):
request_params = request_params or {}
custom_query = {} # Additional query to filter the collection
Expand Down Expand Up @@ -189,7 +193,7 @@ def get_filter_items(
# 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()
Expand All @@ -213,6 +217,9 @@ def get_filter_items(
or filter_value in value_blacklist
):
continue
if type(filter_value) == int:
# if indexed value is an integer, convert to string
filter_value = str(filter_value)
if filter_value in grouped_results:
# Add counter, if filter value is already present
grouped_results[filter_value]["count"] += 1
Expand Down Expand Up @@ -262,6 +269,9 @@ def get_filter_items(
if callable(sort_key_function):
grouped_results = sorted(grouped_results, key=sort_key_function)

if reverse:
grouped_results = reversed(grouped_results)

ret += grouped_results

return ret
Expand Down
14 changes: 12 additions & 2 deletions src/collective/collectionfilter/interfaces.py
Expand Up @@ -132,8 +132,18 @@ class ICollectionFilterSchema(ICollectionFilterBaseSchema):
vocabulary="collective.collectionfilter.InputType",
)

reverse = schema.Bool(
title=_(u"label_reverse", default=u"Reverse sort filter"),
description=_(
u"help_reverse",
default=u"Reverse the sorting of th list of filter options.",
),
default=False,
required=False,
)

narrow_down = schema.Bool(
title=_(u"label_narrow_down", default=u"Narrow down filter options"), # noqa
title=_(u"label_narrow_down", default=u"Narrow down filter options"),
description=_(
u"help_narrow_down",
default=u"Narrow down the filter options when a filter of this group is applied." # noqa
Expand All @@ -145,7 +155,7 @@ class ICollectionFilterSchema(ICollectionFilterBaseSchema):
)

hide_if_empty = schema.Bool(
title=_(u"label_hide_if_empty", default=u"Hide if empty"), # noqa
title=_(u"label_hide_if_empty", default=u"Hide if empty"),
description=_(
u"help_hide_if_empty",
default=u"Don't display if there is 1 or no options without selecting a filter yet.",
Expand Down
3 changes: 3 additions & 0 deletions src/collective/collectionfilter/portlets/collectionfilter.py
Expand Up @@ -28,6 +28,7 @@ class Assignment(base.Assignment):
view_name = None
content_selector = "#content-core"
hide_if_empty = False
reverse = False
# list_scaling = None

def __init__(
Expand All @@ -43,6 +44,7 @@ def __init__(
view_name=None,
content_selector="#content-core",
hide_if_empty=False,
reverse=False,
# list_scaling=None
):
self.header = header
Expand All @@ -56,6 +58,7 @@ def __init__(
self.view_name = view_name
self.content_selector = content_selector
self.hide_if_empty = hide_if_empty
self.reverse = reverse
# self.list_scaling = list_scaling

@property
Expand Down
11 changes: 9 additions & 2 deletions src/collective/collectionfilter/testing.py
Expand Up @@ -14,6 +14,8 @@

import json
import os
import pytz
import six


try:
Expand Down Expand Up @@ -77,12 +79,17 @@ def setUpPloneSite(self, portal):
}
],
)
if six.PY2:
now = datetime.now()
else:
now = datetime.now(pytz.UTC)

portal.invokeFactory(
"Event",
id="testevent",
title=u"Test Event",
start=datetime.now() + timedelta(days=1),
end=datetime.now() + timedelta(days=2),
start=now + timedelta(days=1),
end=now + timedelta(days=2),
subject=[u"Süper", u"Evänt"],
exclude_from_nav=False,
)
Expand Down
Expand Up @@ -45,7 +45,7 @@ Scenario: Test Batching
Scenario: Hide when no options

Given I've got a site with a collection
and my collection has a collection filter author_name or checkboxes_dropdowns Hide if empty
and my collection has a collection filter Creator or checkboxes_dropdowns Hide if empty
When I'm viewing the collection
then Should be 3 collection results
then Should be 0 filter options
Expand Down
31 changes: 19 additions & 12 deletions src/collective/collectionfilter/tiles/__init__.py
Expand Up @@ -15,6 +15,12 @@
import re


# tile names actijg collectionish
COLLECTIONISH_TARGETS = [
"plone.app.standardtiles.contentlisting",
]


class DictDataWrapper(object):
def __init__(self, data):
self.data = data
Expand Down Expand Up @@ -51,6 +57,8 @@ def reload_url(self):


def findall_tiles(context, spec):
if not isinstance(spec, list):
spec = [spec]
request = context.REQUEST
la = ILayoutAware(context)
layout = (
Expand All @@ -62,8 +70,10 @@ def findall_tiles(context, spec):
)
if layout is None:
return []
urls = re.findall(r"(@@[\w\.]+/\w+)", layout)
urls = [url for url in urls if url.startswith("@@{}".format(spec))]
possible_urls = re.findall(r"(@@[\w\.]+/\w+)", layout)
urls = []
for name in spec:
urls += [url for url in possible_urls if url.startswith("@@{}".format(name))]
# TODO: maybe better to get tile data? using ITileDataManager(id)?
our_tile = request.response.headers.get("x-tile-url")
tiles = [context.unrestrictedTraverse(str(url)) for url in urls]
Expand Down Expand Up @@ -107,10 +117,10 @@ def selectContent(self, selector=None):
if selector is None:
selector = ""
self.tile = None
tiles = findall_tiles(self.context, "plone.app.standardtiles.contentlisting")
tiles = findall_tiles(self.context, COLLECTIONISH_TARGETS)
for tile in tiles:
tile.update()
tile_classes = tile.tile_class.split() + [""]
tile_classes = getattr(tile, "tile_class", "").split() + [""]
# First tile that matches all the selector classes
if all([_class in tile_classes for _class in selector.split(".")]):
self.tile = tile
Expand All @@ -121,25 +131,22 @@ def selectContent(self, selector=None):
self.tile = tile
if self.tile is not None or self.collection is not None:
return self
else:
return None

@property
def sort_reversed(self):
if self.tile is not None:
return self.sort_order == "reverse"
else:
return self.collection.sort_reversed
return self.collection.sort_reversed

@property
def content_selector(self):
"""will return None if no tile or colleciton found"""
"""will return None if no tile or collection found"""
if self.collection is None:
return None
elif self.tile is None:
return
if self.tile is None:
return super(CollectionishLayout, self).content_selector
classes = ["contentlisting-tile"]
if self.tile.tile_class:
if getattr(self.tile, "tile_class", ""):
classes += self.tile.tile_class.split()
return "." + ".".join(classes)

Expand Down

0 comments on commit 6cad72f

Please sign in to comment.