diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 9f34d97569..ef8d8d4467 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -17,6 +17,7 @@ Changelog * Cleaned up Django docs URLs in documentation (Pete Andrew) * Add StreamFieldPanel to available panel types in documentation (Dan Swain) * Add {{ block.super }} example to ModelAdmin customisation in documentation (Dan Swain) + * Add ability to filter image index by a tag (Benedikt Willi) * Fix: Rename documents listing column 'uploaded' to 'created' (LB (Ben Johnston)) * Fix: Submenu items longer then the page height are no longer broken by the submenu footer (Igor van Spengen) * Fix: Unbundle the l18n library as it was bundled to avoid installation errors which have been resolved (Matt Westcott) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index 87d6323ba3..8041a69324 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -425,6 +425,7 @@ Contributors * Tim Gates * Timothy Bautista * Pete Andrew +* Benedikt Willi Translators =========== diff --git a/client/scss/components/_button.scss b/client/scss/components/_button.scss index 66a9f6978e..2b65475dad 100644 --- a/client/scss/components/_button.scss +++ b/client/scss/components/_button.scss @@ -106,7 +106,7 @@ } &.bicolor { - border: 0; + border: 1px solid transparent; padding-left: 3.5em; &:before { @@ -123,6 +123,10 @@ border-top-left-radius: inherit; border-bottom-left-radius: inherit; } + + &.button-secondary { + border: 1px solid rgba(0, 0, 0, 0.2); + } } &.button-small.bicolor { diff --git a/client/scss/components/_tag.scss b/client/scss/components/_tag.scss index 8b561282cc..d054d9888c 100644 --- a/client/scss/components/_tag.scss +++ b/client/scss/components/_tag.scss @@ -29,9 +29,33 @@ a.tag:hover { .taglist { font-size: 0.9em; line-height: 2.4em; +} - h3 { - display: inline; - margin-right: 1em; +.tagfilter { + legend { + @include visuallyvisible; + + @include media-breakpoint-up(sm) { + @include column(2); + padding-left: 0; + } + + font-weight: 700; + color: #333; + font-size: 1.1em; + display: block; + padding: 0 0 0.8em; + } + + a { + font-size: 0.9em; + } + + .button.bicolor.icon-cross { + padding-left: 2em; + + &:before { + background-color: transparent; + } } } diff --git a/client/scss/tools/_mixins.general.scss b/client/scss/tools/_mixins.general.scss index 1b826f489d..38cb7da8b1 100644 --- a/client/scss/tools/_mixins.general.scss +++ b/client/scss/tools/_mixins.general.scss @@ -81,10 +81,10 @@ @mixin visuallyvisible { - clip: none; + clip: auto; height: auto; width: auto; - margin: auto; + margin: initial; overflow: visible; position: initial; } diff --git a/docs/releases/2.8.rst b/docs/releases/2.8.rst index 1966a52afa..00db4f51cb 100644 --- a/docs/releases/2.8.rst +++ b/docs/releases/2.8.rst @@ -26,6 +26,7 @@ Other features * Cleaned up Django docs URLs in documentation (Pete Andrew) * Add StreamFieldPanel to available panel types in documentation (Dan Swain) * Add {{ block.super }} example to ModelAdmin customisation in documentation (Dan Swain) + * Add ability to filter image index by a tag (Benedikt Willi) Bug fixes diff --git a/wagtail/images/templates/wagtailimages/images/index.html b/wagtail/images/templates/wagtailimages/images/index.html index be13692fff..b53e5983fe 100644 --- a/wagtail/images/templates/wagtailimages/images/index.html +++ b/wagtail/images/templates/wagtailimages/images/index.html @@ -1,4 +1,5 @@ {% extends "wagtailadmin/base.html" %} +{% load wagtailadmin_tags %} {% load wagtailimages_tags %} {% load i18n %} @@ -31,13 +32,33 @@ {% endif %}
- {% if collections %} - +
{% include "wagtailimages/images/results.html" %} diff --git a/wagtail/images/tests/test_admin_views.py b/wagtail/images/tests/test_admin_views.py index e7d088a230..56a93d114a 100644 --- a/wagtail/images/tests/test_admin_views.py +++ b/wagtail/images/tests/test_admin_views.py @@ -50,7 +50,7 @@ class TestImageIndexView(TestCase, WagtailTestUtils): for i in range(1, 50): self.image = Image.objects.create( title="Test image %i" % i, - file=get_test_image_file(), + file=get_test_image_file(size=(1, 1)), collection=evil_plans_collection ) @@ -87,6 +87,85 @@ class TestImageIndexView(TestCase, WagtailTestUtils): ['Root', 'Evil plans', 'Good plans']) + def test_tags(self): + image_two_tags = Image.objects.create( + title="Test image with two tags", + file=get_test_image_file(), + ) + image_two_tags.tags.add("one", "two") + + response = self.get() + self.assertEqual(response.status_code, 200) + + current_tag = response.context['current_tag'] + self.assertIsNone(current_tag) + + tags = response.context['popular_tags'] + self.assertTrue( + [tag.name for tag in tags] == ["one", "two"] + or [tag.name for tag in tags] == ["two", "one"] + ) + + + def test_tag_filtering(self): + Image.objects.create( + title="Test image with no tags", + file=get_test_image_file(), + ) + + image_one_tag = Image.objects.create( + title="Test image with one tag", + file=get_test_image_file(), + ) + image_one_tag.tags.add("one") + + image_two_tags = Image.objects.create( + title="Test image with two tags", + file=get_test_image_file(), + ) + image_two_tags.tags.add("one", "two") + + # no filtering + response = self.get() + self.assertEqual(response.context['images'].paginator.count, 3) + + # filter all images with tag 'one' + response = self.get({'tag': 'one'}) + self.assertEqual(response.context['images'].paginator.count, 2) + + # filter all images with tag 'two' + response = self.get({'tag': 'two'}) + self.assertEqual(response.context['images'].paginator.count, 1) + + + def test_tag_filtering_preserves_other_params(self): + for i in range(1, 100): + image = Image.objects.create( + title="Test image %i" % i, + file=get_test_image_file(size=(1, 1)), + ) + if (i % 2 != 0): + image.tags.add('even') + image.save() + + + response = self.get({'tag': 'even', 'p': 2}) + self.assertEqual(response.status_code, 200) + + response_body = response.content.decode('utf8') + + # prev link should exist and include tag + self.assertTrue( + "?p=2&tag=even" in response_body + or "?tag=even&p=1" in response_body + ) + # next link should exist and include tag + self.assertTrue( + "?p=3&tag=even" in response_body + or "?tag=even&p=3" in response_body + ) + + class TestImageAddView(TestCase, WagtailTestUtils): def setUp(self): self.login() diff --git a/wagtail/images/views/images.py b/wagtail/images/views/images.py index 3246ccb213..2c8bcb2cd2 100644 --- a/wagtail/images/views/images.py +++ b/wagtail/images/views/images.py @@ -59,6 +59,14 @@ def index(request): except (ValueError, Collection.DoesNotExist): pass + # Filter by tag + current_tag = request.GET.get('tag') + if current_tag: + try: + images = images.filter(tags__name=current_tag) + except (AttributeError): + current_tag = None + paginator = Paginator(images, per_page=INDEX_PAGE_SIZE) images = paginator.get_page(request.GET.get('p')) @@ -85,6 +93,7 @@ def index(request): 'search_form': form, 'popular_tags': popular_tags_for_model(Image), + 'current_tag': current_tag, 'collections': collections, 'current_collection': current_collection, 'user_can_add': permission_policy.user_has_permission(request.user, 'add'),