From e157bcd34f912432305f6faace366864ac18e61b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20I=C3=9Fbr=C3=BCcker?= Date: Sun, 30 Jun 2019 21:15:02 +0200 Subject: [PATCH] Filter tag cloud based on search query --- bookmarks/queries.py | 60 ++++++++++++++++---- bookmarks/styles/bookmarks.scss | 2 +- bookmarks/templates/bookmarks/tag_cloud.html | 17 ++++-- bookmarks/templatetags/shared.py | 10 ++++ bookmarks/views/bookmarks.py | 4 +- 5 files changed, 74 insertions(+), 19 deletions(-) diff --git a/bookmarks/queries.py b/bookmarks/queries.py index 5a29cce..7450b30 100644 --- a/bookmarks/queries.py +++ b/bookmarks/queries.py @@ -1,7 +1,7 @@ from django.contrib.auth.models import User from django.db.models import Q, Count, Aggregate, CharField -from bookmarks.models import Bookmark +from bookmarks.models import Bookmark, Tag class Concat(Aggregate): @@ -22,22 +22,14 @@ def query_bookmarks(user: User, query_string: str): .annotate(tag_count=Count('tags'), tag_string=Concat('tags__name')) - # Sanitize query params - if not query_string: - query_string = '' - # Filter for user query_set = query_set.filter(owner=user) # Split query into search terms and tags - keywords = query_string.strip().split(' ') - keywords = [word for word in keywords if word] - - search_terms = [word for word in keywords if word[0] != '#'] - tag_names = [word[1:] for word in keywords if word[0] == '#'] + query = _parse_query_string(query_string) # Filter for search terms and tags - for term in search_terms: + for term in query['search_terms']: query_set = query_set.filter( Q(title__contains=term) | Q(description__contains=term) @@ -45,7 +37,7 @@ def query_bookmarks(user: User, query_string: str): | Q(website_description__contains=term) ) - for tag_name in tag_names: + for tag_name in query['tag_names']: query_set = query_set.filter( tags__name=tag_name ) @@ -54,3 +46,47 @@ def query_bookmarks(user: User, query_string: str): query_set = query_set.order_by('-date_modified') return query_set + + +def query_tags(user: User, query_string: str): + query_set = Tag.objects; + + # Filter for user + query_set = query_set.filter(owner=user) + + # Split query into search terms and tags + query = _parse_query_string(query_string) + + # Filter for search terms and tags + for term in query['search_terms']: + query_set = query_set.filter( + Q(bookmark__title__contains=term) + | Q(bookmark__description__contains=term) + | Q(bookmark__website_title__contains=term) + | Q(bookmark__website_description__contains=term) + ) + + for tag_name in query['tag_names']: + query_set = query_set.filter( + bookmark__tags__name=tag_name + ) + + return query_set.distinct() + + +def _parse_query_string(query_string): + # Sanitize query params + if not query_string: + query_string = '' + + # Split query into search terms and tags + keywords = query_string.strip().split(' ') + keywords = [word for word in keywords if word] + + search_terms = [word for word in keywords if word[0] != '#'] + tag_names = [word[1:] for word in keywords if word[0] == '#'] + + return { + 'search_terms': search_terms, + 'tag_names': tag_names, + } diff --git a/bookmarks/styles/bookmarks.scss b/bookmarks/styles/bookmarks.scss index 7f3c456..1e02f17 100644 --- a/bookmarks/styles/bookmarks.scss +++ b/bookmarks/styles/bookmarks.scss @@ -43,7 +43,7 @@ ul.bookmark-list { margin-bottom: 0.4rem; } - .group-label { + .highlight-char { font-weight: bold; text-transform: uppercase; color: $alternative-color-dark; diff --git a/bookmarks/templates/bookmarks/tag_cloud.html b/bookmarks/templates/bookmarks/tag_cloud.html index bf0d5be..f15d8e2 100644 --- a/bookmarks/templates/bookmarks/tag_cloud.html +++ b/bookmarks/templates/bookmarks/tag_cloud.html @@ -3,11 +3,20 @@
{% for group in groups %}

- {{ group.char }} {% for tag in group.tags %} - - {{ tag.name }} - + {# Highlight first char of first tag in group #} + {% if forloop.counter == 1 %} + + {{ tag.name|first_char }}{{ tag.name|remaining_chars:1 }} + + {% else %} + {# Render remaining tags normally #} + + {{ tag.name }} + + {% endif %} {% endfor %}

{% endfor %} diff --git a/bookmarks/templatetags/shared.py b/bookmarks/templatetags/shared.py index c5bc562..566ca6b 100644 --- a/bookmarks/templatetags/shared.py +++ b/bookmarks/templatetags/shared.py @@ -33,3 +33,13 @@ def append_query_param(context, **kwargs): @register.filter(name='hash_tag') def hash_tag(tag_name): return '#' + tag_name + + +@register.filter(name='first_char') +def first_char(text): + return text[0] + + +@register.filter(name='remaining_chars') +def remaining_chars(text, index): + return text[index:] diff --git a/bookmarks/views/bookmarks.py b/bookmarks/views/bookmarks.py index a06d22c..4fb1694 100644 --- a/bookmarks/views/bookmarks.py +++ b/bookmarks/views/bookmarks.py @@ -4,7 +4,7 @@ from django.shortcuts import render from django.urls import reverse from bookmarks import queries -from bookmarks.models import Bookmark, BookmarkForm, Tag +from bookmarks.models import Bookmark, BookmarkForm from bookmarks.services.bookmarks import create_bookmark, update_bookmark _default_page_size = 30 @@ -16,7 +16,7 @@ def index(request): query_set = queries.query_bookmarks(request.user, query_string) paginator = Paginator(query_set, _default_page_size) bookmarks = paginator.get_page(page) - tags = Tag.objects.all() + tags = queries.query_tags(request.user, query_string) if request.GET.get('tag'): mod = request.GET.copy()