Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a module global COLLECTIONISH_TARGETS #154

Merged
merged 20 commits into from
Mar 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,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 @@ -157,6 +155,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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,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 @@ -151,7 +161,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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading