From e45ab77eef6c60265e1ecf1ad0d4e7f3c2b0a067 Mon Sep 17 00:00:00 2001 From: Kasper Birch Date: Wed, 4 Sep 2024 08:05:11 +0200 Subject: [PATCH 1/7] Add full-text search to `Events` view This allows the user to search for words in the `title` and `description` of an event. To achieve this, I have added an exposed filter in the view and updated the search API to index titles and descriptions. I have also unenabled case sensitivity. To get the right design, I have added some template suggestions in the `norvel.theme` file and changed the order of filters in the view template. --- config/sync/search_api.index.events.yml | 24 ++++++++ config/sync/views.view.events.yml | 56 ++++++++++++++++++- web/themes/custom/novel/novel.theme | 33 +++++++++++ .../views/form--views-exposed-form.html.twig | 7 +++ ...orm-element--search-api-fulltext.html.twig | 7 +++ .../input--search-api-fulltext.html.twig | 3 + .../views-view--content-list-page.html.twig | 4 +- 7 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 web/themes/custom/novel/templates/views/form--views-exposed-form.html.twig create mode 100644 web/themes/custom/novel/templates/views/form-element--search-api-fulltext.html.twig create mode 100644 web/themes/custom/novel/templates/views/input--search-api-fulltext.html.twig diff --git a/config/sync/search_api.index.events.yml b/config/sync/search_api.index.events.yml index 69280621e..db2e641e8 100644 --- a/config/sync/search_api.index.events.yml +++ b/config/sync/search_api.index.events.yml @@ -45,6 +45,14 @@ field_settings: dependencies: module: - field_inheritance + event_description: + label: 'Event description' + datasource_id: 'entity:eventinstance' + property_path: event_description + type: text + dependencies: + module: + - field_inheritance event_tags: label: 'Event tags' datasource_id: 'entity:eventinstance' @@ -61,6 +69,14 @@ field_settings: dependencies: module: - recurring_events + title: + label: 'Event title' + datasource_id: 'entity:eventinstance' + property_path: title + type: text + dependencies: + module: + - field_inheritance datasource_settings: 'entity:eventinstance': bundles: @@ -74,6 +90,14 @@ processor_settings: aggregated_field: { } custom_value: { } entity_type: { } + ignorecase: + weights: + preprocess_index: -20 + preprocess_query: -20 + all_fields: true + fields: + - event_description + - title language_with_fallback: { } rendered_item: { } tracker_settings: diff --git a/config/sync/views.view.events.yml b/config/sync/views.view.events.yml index 0ae91853e..405256ce1 100644 --- a/config/sync/views.view.events.yml +++ b/config/sync/views.view.events.yml @@ -261,6 +261,58 @@ display: default_group: All default_group_multiple: { } group_items: { } + search_api_fulltext: + id: search_api_fulltext + table: search_api_index_events + field: search_api_fulltext + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api_fulltext + operator: and + value: '' + group: 1 + exposed: true + expose: + operator_id: search_api_fulltext_op + label: Search + description: '' + use_operator: false + operator: search_api_fulltext_op + operator_limit_selection: false + operator_list: { } + identifier: search_api_fulltext + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + local_administrator: '0' + editor: '0' + mediator: '0' + patron: '0' + external_system: '0' + expose_fields: false + placeholder: 'Søg' + searched_fields_id: search_api_fulltext_searched_fields + value_maxlength: 128 + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + parse_mode: terms + min_length: null + fields: { } style: type: default row: @@ -277,7 +329,7 @@ display: preserve_facet_query_args: false query_tags: { } relationships: { } - use_ajax: true + use_ajax: false header: { } footer: { } display_extenders: { } @@ -285,6 +337,7 @@ display: max-age: -1 contexts: - 'languages:language_interface' + - url - url.query_args - user.permissions tags: @@ -305,6 +358,7 @@ display: max-age: -1 contexts: - 'languages:language_interface' + - url - url.query_args - user.permissions tags: diff --git a/web/themes/custom/novel/novel.theme b/web/themes/custom/novel/novel.theme index 93ca0ebb4..86dd4f04c 100644 --- a/web/themes/custom/novel/novel.theme +++ b/web/themes/custom/novel/novel.theme @@ -293,6 +293,39 @@ function novel_theme_suggestions_select_alter(array &$suggestions, array $variab } } +/** + * Implements hook_theme_suggestions_form_alter(). + */ +function novel_theme_suggestions_form_alter(array &$suggestions, array $variables): void { + $form_id = $variables['element']['#form_id'] ?? NULL; + + if ($form_id) { + $suggestions[] = "form__$form_id"; + } +} + +/** + * Implements hook_theme_suggestions_form_element_alter(). + */ +function novel_theme_suggestions_form_element_alter(array &$suggestions, array $variables): void { + $name = $variables['element']['#name'] ?? NULL; + + if ($name) { + $suggestions[] = "form_element__$name"; + } +} + +/** + * Implements hook_theme_suggestions_input_alter(). + */ +function novel_theme_suggestions_input_alter(array &$suggestions, array $variables): void { + $name = $variables['element']['#name'] ?? NULL; + + if ($name) { + $suggestions[] = "input__$name"; + } +} + /** * Preprocesses rows in a Drupal view to handle the display of event instances. * diff --git a/web/themes/custom/novel/templates/views/form--views-exposed-form.html.twig b/web/themes/custom/novel/templates/views/form--views-exposed-form.html.twig new file mode 100644 index 000000000..1e7f1ba18 --- /dev/null +++ b/web/themes/custom/novel/templates/views/form--views-exposed-form.html.twig @@ -0,0 +1,7 @@ +{# web/core/themes/stable9/templates/form/form.html.twig #} +
  • + + + {{ children }} + +
  • diff --git a/web/themes/custom/novel/templates/views/form-element--search-api-fulltext.html.twig b/web/themes/custom/novel/templates/views/form-element--search-api-fulltext.html.twig new file mode 100644 index 000000000..521bc9784 --- /dev/null +++ b/web/themes/custom/novel/templates/views/form-element--search-api-fulltext.html.twig @@ -0,0 +1,7 @@ +{# web/core/themes/stable9/templates/form/form-element.html.twig #} +{{ children }} +{% if errors %} +
    + {{ errors }} +
    +{% endif %} diff --git a/web/themes/custom/novel/templates/views/input--search-api-fulltext.html.twig b/web/themes/custom/novel/templates/views/input--search-api-fulltext.html.twig new file mode 100644 index 000000000..0caea4e38 --- /dev/null +++ b/web/themes/custom/novel/templates/views/input--search-api-fulltext.html.twig @@ -0,0 +1,3 @@ +{# web/core/themes/stable9/templates/form/input.html.twig #} + + diff --git a/web/themes/custom/novel/templates/views/views-view--content-list-page.html.twig b/web/themes/custom/novel/templates/views/views-view--content-list-page.html.twig index 6c350fc12..e1c14cba1 100644 --- a/web/themes/custom/novel/templates/views/views-view--content-list-page.html.twig +++ b/web/themes/custom/novel/templates/views/views-view--content-list-page.html.twig @@ -14,10 +14,10 @@ {{ header }} {{ attachment_before }} From 0414d7ab04f29e5b0fec30e1fdd3099f91bd10ff Mon Sep 17 00:00:00 2001 From: Kasper Birch Date: Wed, 4 Sep 2024 08:32:41 +0200 Subject: [PATCH 2/7] Add full-text search to `Articles` view This allows the user to search for words in the `title` and `description` and `teaser` of an articles. To achieve this, I have added an exposed filter in the view and updated the search API to index titles and descriptions and teaser text. I have also unenabled case sensitivity. And aligned the advance settinges for the view to user better expose fileters with the settings from events view --- config/sync/search_api.index.content.yml | 29 +++++++- config/sync/views.view.articles.yml | 85 +++++++++++++++++++++++- config/sync/views.view.events.yml | 2 +- 3 files changed, 113 insertions(+), 3 deletions(-) diff --git a/config/sync/search_api.index.content.yml b/config/sync/search_api.index.content.yml index 5d8bcc5bb..cb0360234 100644 --- a/config/sync/search_api.index.content.yml +++ b/config/sync/search_api.index.content.yml @@ -6,6 +6,8 @@ dependencies: - field.storage.node.field_branch - field.storage.node.field_categories - field.storage.node.field_publication_date + - field.storage.node.field_subtitle + - field.storage.node.field_teaser_text - search_api.server.db_search module: - node @@ -47,6 +49,22 @@ field_settings: dependencies: config: - field.storage.node.field_publication_date + field_subtitle: + label: Subtitle + datasource_id: 'entity:node' + property_path: field_subtitle + type: text + dependencies: + config: + - field.storage.node.field_subtitle + field_teaser_text: + label: 'Teaser text' + datasource_id: 'entity:node' + property_path: field_teaser_text + type: text + dependencies: + config: + - field.storage.node.field_teaser_text status: label: Published datasource_id: 'entity:node' @@ -59,7 +77,7 @@ field_settings: label: Title datasource_id: 'entity:node' property_path: title - type: string + type: text dependencies: module: - node @@ -84,6 +102,15 @@ processor_settings: aggregated_field: { } custom_value: { } entity_type: { } + ignorecase: + weights: + preprocess_index: -20 + preprocess_query: -20 + all_fields: false + fields: + - field_subtitle + - title + - type language_with_fallback: { } rendered_item: { } tracker_settings: diff --git a/config/sync/views.view.articles.yml b/config/sync/views.view.articles.yml index 4e5a48cfc..e40a7473a 100644 --- a/config/sync/views.view.articles.yml +++ b/config/sync/views.view.articles.yml @@ -6,6 +6,7 @@ dependencies: - field.storage.node.field_branch - search_api.index.content module: + - better_exposed_filters - search_api - user - views_infinite_scroll @@ -120,7 +121,7 @@ display: automatically_load_content: false initially_load_all_pages: true exposed_form: - type: basic + type: bef options: submit_button: Apply reset_button: false @@ -129,6 +130,34 @@ display: expose_sort_order: true sort_asc_label: Asc sort_desc_label: Desc + text_input_required: 'Select any filter and click on Apply to see results' + text_input_required_format: basic + bef: + general: + autosubmit: true + autosubmit_exclude_textfield: false + autosubmit_textfield_delay: 500 + autosubmit_hide: true + input_required: false + allow_secondary: false + secondary_label: 'Advanced options' + secondary_open: false + reset_button_always_show: false + filter: + search_api_fulltext: + plugin_id: default + advanced: + placeholder_text: '' + rewrite: + filter_rewrite_values: '' + filter_rewrite_values_key: false + collapsible: false + collapsible_disable_automatic_open: false + is_secondary: false + options_show_only_used: false + options_show_only_used_filtered: false + options_hide_when_empty: false + options_show_items_count: false access: type: perm options: @@ -232,6 +261,58 @@ display: default_group_multiple: { } group_items: { } reduce_duplicates: false + search_api_fulltext: + id: search_api_fulltext + table: search_api_index_content + field: search_api_fulltext + relationship: none + group_type: group + admin_label: '' + plugin_id: search_api_fulltext + operator: and + value: '' + group: 1 + exposed: true + expose: + operator_id: search_api_fulltext_op + label: Search + description: '' + use_operator: false + operator: search_api_fulltext_op + operator_limit_selection: false + operator_list: { } + identifier: search_api_fulltext + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + local_administrator: '0' + editor: '0' + mediator: '0' + patron: '0' + external_system: '0' + expose_fields: false + placeholder: Søg + searched_fields_id: search_api_fulltext_searched_fields + value_maxlength: 128 + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + parse_mode: terms + min_length: null + fields: { } style: type: default row: @@ -259,6 +340,7 @@ display: contexts: - 'languages:language_content' - 'languages:language_interface' + - url - url.query_args - 'user.node_grants:view' - user.permissions @@ -279,6 +361,7 @@ display: contexts: - 'languages:language_content' - 'languages:language_interface' + - url - url.query_args - 'user.node_grants:view' - user.permissions diff --git a/config/sync/views.view.events.yml b/config/sync/views.view.events.yml index 405256ce1..40f5dc93d 100644 --- a/config/sync/views.view.events.yml +++ b/config/sync/views.view.events.yml @@ -295,7 +295,7 @@ display: patron: '0' external_system: '0' expose_fields: false - placeholder: 'Søg' + placeholder: Søg searched_fields_id: search_api_fulltext_searched_fields value_maxlength: 128 is_grouped: false From 67af013a3bd0af035a151c0649db7fcd6e3dea63 Mon Sep 17 00:00:00 2001 From: Kasper Birch Date: Wed, 4 Sep 2024 09:17:17 +0200 Subject: [PATCH 3/7] Align dropdown filter classes with design system Updated the dropdown filter in views to include the missing classes as per the design specifications: https://www.figma.com/design/Zx9GrkFA3l4ISvyZD2q0Qi/Designsystem?node-id=7567-51261&t=RjElCVOLGPz7JEeF-4 --- .../templates/views/facets-item-list--dropdown.html.twig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/themes/custom/novel/templates/views/facets-item-list--dropdown.html.twig b/web/themes/custom/novel/templates/views/facets-item-list--dropdown.html.twig index 91ed0df50..9d89877b8 100644 --- a/web/themes/custom/novel/templates/views/facets-item-list--dropdown.html.twig +++ b/web/themes/custom/novel/templates/views/facets-item-list--dropdown.html.twig @@ -16,10 +16,10 @@ {%- endif %} -