From e6fbc2a227c77aa18f3a049bbd77c426f4be6b7b Mon Sep 17 00:00:00 2001 From: ffont Date: Tue, 5 Mar 2024 23:26:10 +0100 Subject: [PATCH] Use templatetag to help displaying search options in template --- DEVELOPERS.md | 3 +- .../static/bw-frontend/src/pages/search.js | 13 ++- .../bw-frontend/styles/pages/search.scss | 17 +++ search/templatetags/search.py | 16 +++ templates/search/search.html | 103 +++++------------- templates/search/search_option.html | 20 ++++ utils/search/search_query_processor.py | 2 +- 7 files changed, 90 insertions(+), 84 deletions(-) create mode 100644 templates/search/search_option.html diff --git a/DEVELOPERS.md b/DEVELOPERS.md index 07bde17a8..a3f001329 100644 --- a/DEVELOPERS.md +++ b/DEVELOPERS.md @@ -147,7 +147,8 @@ engine backend, this should be done in the `SearchQueryProcessor.as_query_params Adding a new search option to `SearchQueryProcessor` will make the option work with the search engine backend and with search URLs, but it will NOT automatically add the option to the form in the search page. This will need to be done manually by adding the -search option in the desired place in `templates/search/search.html` (see how other search options are implemented for inspiration). +search option in the desired place in `templates/search/search.html` (see how other search options are implemented for inspiration, +there is a `display_search_option` templatetag which will facilitate things in most cases). All this will add the search option to the user interface and send corresponding information to the search backend. For example, if the new search option should apply a filter in the search backend of some `new_property`, this will be handled by the `SearchQueryProcessor`. diff --git a/freesound/static/bw-frontend/src/pages/search.js b/freesound/static/bw-frontend/src/pages/search.js index 053e9e3be..8bc518333 100644 --- a/freesound/static/bw-frontend/src/pages/search.js +++ b/freesound/static/bw-frontend/src/pages/search.js @@ -7,7 +7,7 @@ const searchInputBrowse = document.getElementById('search-input-browse'); const searchInputBrowsePlaceholder = searchInputBrowse.getAttribute("placeholder"); const removeSearchInputValueBrowse = document.getElementById('remove-content-search'); const advancedSearchOptionsDiv = document.getElementById('advanced-search-options'); -const tagsMode = document.getElementsByName('tm')[0] !== undefined; +const tagsMode = location.pathname.indexOf('/browse/tags/') > -1; const updateRemoveSearchInputButtonVisibility = (searchInputElement) => { if (searchInputElement.value.length) { @@ -168,11 +168,12 @@ searchFormElement.getElementsByClassName('bw-checkbox').forEach(checkbox => { checkbox.parentNode.appendChild(hiddenCheckbox); }); - -var sortByElement = document.getElementById('sort-by'); -sortByElement.addEventListener('change', function() { - searchFormElement.submit(); -}) +var sortByElement = document.getElementById('id_sort_by'); +if (sortByElement !== null){ + sortByElement.addEventListener('change', function() { + searchFormElement.submit(); + }) +} document.body.addEventListener('keydown', evt => { const ENTER_KEY = 13 diff --git a/freesound/static/bw-frontend/styles/pages/search.scss b/freesound/static/bw-frontend/styles/pages/search.scss index 650279263..37ca81a75 100644 --- a/freesound/static/bw-frontend/styles/pages/search.scss +++ b/freesound/static/bw-frontend/styles/pages/search.scss @@ -163,6 +163,23 @@ } } +.bw-search_input { + border: 1px solid $border-input; + color: $black; + background-color: $background-input; + padding: 10px 20px; + border-radius: 5px; + + &::placeholder { + color: $navy-light-grey; + } + + &:focus { + background-color: $white; + border: 1px solid $black; + } +} + .browse__search-overview-sorter { display: flex; align-items: center; diff --git a/search/templatetags/search.py b/search/templatetags/search.py index 82e30593c..541851ea1 100644 --- a/search/templatetags/search.py +++ b/search/templatetags/search.py @@ -23,6 +23,7 @@ from django.conf import settings from sounds.models import License +from utils.search import search_query_processor_options from utils.tags import annotate_tags register = template.Library() @@ -114,3 +115,18 @@ def display_facet(context, facet_name): element['icon'] = 'fcw' return {'type': facet_type, 'title': facet_title, 'facet': facet} + + +@register.inclusion_tag('search/search_option.html', takes_context=True) +def display_search_option(context, option_name, widget=None): + sqp = context['sqp'] + option = sqp.options[option_name] + if widget is None: + # If a widget is not provided as a parameter, use a sensible default + widget = { + search_query_processor_options.SearchOptionBool: 'checkbox', + search_query_processor_options.SearchOptionStr: 'text', + search_query_processor_options.SearchOptionChoice: 'select', + }.get(type(option), 'text') + label = option.label if option.label else option_name.capitalize().replace('_', ' ') + return {'option': option, 'option_name': option_name, 'label': label, 'widget': widget} \ No newline at end of file diff --git a/templates/search/search.html b/templates/search/search.html index 40c8195f4..7137a3119 100644 --- a/templates/search/search.html +++ b/templates/search/search.html @@ -49,8 +49,8 @@

Choose a tag to start browsing{% bw_icon 'close' %} - {% if not sqp.options.field_weights.is_default_value %}{% endif %} - {% if not sqp.options.similar_to.is_default_value %}{% endif %} + {% if not sqp.options.field_weights.is_default_value %}{% display_search_option "field_weights" "hidden" %}{% endif %} + {% if not sqp.options.similar_to.is_default_value %}{% display_search_option "similar_to" "hidden" %}{% endif %} {% if sqp.tags_mode_active %} {% comment %}"sounds tagged as" label with follow/unfollow buttons{% endcomment %} @@ -86,16 +86,12 @@

{% comment %}sorting options{% endcomment %}
- {{ sqp.options.sort_by.label }}: - + {% if not sqp.similar_to_active %} + {% display_search_option "sort_by" %} + {% else %} + {{ sqp.options.sort_by.label }}: + Similarity to target + {% endif %}
@@ -138,66 +134,24 @@

Other
- {% with sqp.options.is_geotagged as option %} -
- +
+ {% display_search_option "is_geotagged" %}
- {% endwith %} - {% with sqp.options.is_remix as option %} -
- +
+ {% display_search_option "is_remix" %}
- {% endwith %} - {% with sqp.options.group_by_pack as option %} -
- +
+ {% display_search_option "group_by_pack" %}
- {% endwith %} - {% with sqp.options.display_as_packs as option %} -
- +
+ {% display_search_option "display_as_packs" %}
- {% endwith %} - {% with sqp.options.grid_mode as option %} -
- +
+ {% display_search_option "grid_mode" %}
- {% endwith %} - {% with sqp.options.map_mode as option %} -
- +
+ {% display_search_option "map_mode" %}
- {% endwith %}
@@ -209,17 +163,12 @@

-
- {% with sqp.options.compute_clusters as option %} -
- +
+
+
{% display_search_option "compute_clusters" %}
+
{% display_search_option "similar_to" %}
- {% endwith %} +
{% endif %}
@@ -234,6 +183,7 @@

{% if clusters_data %} {% include 'search/clustering_results.html' %} {% else %} + {% if get_clusters_url %}
@@ -243,6 +193,7 @@

{% endif %} + {% endif %} {% endif %}

diff --git a/templates/search/search_option.html b/templates/search/search_option.html new file mode 100644 index 000000000..d97d1fea0 --- /dev/null +++ b/templates/search/search_option.html @@ -0,0 +1,20 @@ +{% if widget == 'checkbox' %} + +{% elif widget == 'text' %} +: + +{% elif widget == 'select' %} +{{ label }}: + +{% elif widget == 'hidden' %} + +{% endif %} \ No newline at end of file diff --git a/utils/search/search_query_processor.py b/utils/search/search_query_processor.py index 52f6f9802..2758a0527 100644 --- a/utils/search/search_query_processor.py +++ b/utils/search/search_query_processor.py @@ -136,7 +136,7 @@ class SearchQueryProcessor(object): query_param_name='st') compute_clusters = SearchOptionBool( query_param_name='cc', - label='Cluster results by similarity') + label='Cluster results by sound similarity') cluster_id = SearchOptionInt( advanced=False, query_param_name='cid',