Skip to content

Commit

Permalink
hugo: Allow preselected tags on search
Browse files Browse the repository at this point in the history
Adds a feature to allow tags to added to the search widget. These
will be preselected tags, but can be manually removed after by the
user.

To test and compare, see:
https://cuelang.org/examples/shortcodes/search/

Fixes cue-lang/cue#3394
  • Loading branch information
Wies-UsMedia committed Nov 1, 2024
1 parent 567a376 commit 4d81a5f
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 15 deletions.
7 changes: 5 additions & 2 deletions content/examples/shortcodes/search/en.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ With this shortcode you can embed a search results widget on the page.
## Example

```
{{</* search contentType="How-to Guides" showContentTypes=false */>}}
{{</* search contentType="How-to Guides" showContentTypes=false tags="encodings,commented cue" */>}}
```

{{< search contentType="How-to Guides" showContentTypes=false >}}
{{< search contentType="How-to Guides" showContentTypes=false tags="encodings,commented cue" >}}


## Attributes
Expand All @@ -21,3 +21,6 @@ contentType

showContentTypes
: optional - If set to false the content type dropdown won't show

tags
: optional - Adds preselected tags
2 changes: 1 addition & 1 deletion hugo/assets/ts/helpers/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const parseQuery = (query: string): ParsedQuery => {

const regExp = new RegExp(`${ facetInput }:([^"]\\S+)`, 'g');
const regExpWithQuotes = new RegExp(`${ facetInput }:"([^"]+)"|(\\+)`, 'g');
const matches = [ ...query.matchAll(regExp), ...query.matchAll(regExpWithQuotes) ];
const matches = [...query.matchAll(regExp), ...query.matchAll(regExpWithQuotes)];

for (const match of matches) {
if (match) {
Expand Down
40 changes: 30 additions & 10 deletions hugo/assets/ts/widgets/search-filter.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// eslint-disable-next-line
import Fuse from 'fuse.js';
import { BaseWidget } from './base-widget';
import { FilterEvent, FilterItem, ParsedQuery, SearchEvents } from '../interfaces/search';
import { parseQuery, queryToUrlParams } from '../helpers/search';
import { FilterEvent, FilterItem, ParsedQuery, SearchEvents } from '../interfaces/search';
import { BaseWidget } from './base-widget';

export class SearchFilter extends BaseWidget {
public static readonly NAME = 'filter';
Expand All @@ -14,6 +14,7 @@ export class SearchFilter extends BaseWidget {
private readonly items: FilterItem[];
private filteredItems: FilterItem[];
private selectedItems: string[];
private preselectedItems: string[];
private parsedQuery: ParsedQuery;
private fuse: Fuse<FilterItem>;

Expand Down Expand Up @@ -51,7 +52,7 @@ export class SearchFilter extends BaseWidget {
};
this.fuse = new Fuse(this.items, options);

this.getParamsFromUrl();
this.getParams();
this.searchList();
this.initListeners();
this.element.classList.remove('is-loading');
Expand Down Expand Up @@ -139,21 +140,40 @@ export class SearchFilter extends BaseWidget {
this.updateUrl();
}

private updateUrl() {
window.location.href = `${ window.location.href.split('?')[0] }?${ queryToUrlParams(this.parsedQuery) }`;
private updateUrl(refresh = true) {
const url = `${ window.location.href.split('?')[0] }?${ queryToUrlParams(this.parsedQuery) }`;
if (!refresh) {
window.history.pushState(null, '', url);
} else {
window.location.href = url;
}
}

private getParamsFromUrl(): void {
private getParams(): void {
// Get url params
const url = new URL(window.location.href);
const searchParams = new URLSearchParams(url.search);
const query = searchParams.get('q');

this.parsedQuery = parseQuery(query);

if (!query) {
this.selectedItems = [];
} else {
this.selectedItems = this.parsedQuery.facets[this.filterName] ?? [];
let urlParamsChanged = false;
let selectedItems = this.parsedQuery.facets[this.filterName] ?? [];

// Get preselected items if no items set in url (if set in urL: url wins from preselected)
if (selectedItems.length === 0 && this.element.dataset.preselectedItems && this.element.dataset.preselectedItems !== '') {
this.preselectedItems = this.element.dataset.preselectedItems.split(',').map(val => val.trim());
// Update selected items
selectedItems = Array.from(new Set([...selectedItems, ...this.preselectedItems]));
urlParamsChanged = true;
}

// Update parsed query & save selected items
this.parsedQuery.facets[this.filterName] = selectedItems;
this.selectedItems = selectedItems;

if (urlParamsChanged) {
this.updateUrl(false);
}
}
}
Expand Down
7 changes: 5 additions & 2 deletions hugo/content/en/examples/shortcodes/search/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ With this shortcode you can embed a search results widget on the page.
## Example

```
{{</* search contentType="How-to Guides" showContentTypes=false */>}}
{{</* search contentType="How-to Guides" showContentTypes=false tags="encodings,commented cue" */>}}
```

{{< search contentType="How-to Guides" showContentTypes=false >}}
{{< search contentType="How-to Guides" showContentTypes=false tags="encodings,commented cue" >}}


## Attributes
Expand All @@ -21,3 +21,6 @@ contentType

showContentTypes
: optional - If set to false the content type dropdown won't show

tags
: optional - Adds preselected tags
2 changes: 2 additions & 0 deletions hugo/layouts/partials/filter.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
{{ $heading := printf "search_%s_heading" $translationKey }}
{{ $inputLabel := printf "search_%s_input" $translationKey }}
{{ $noResults := printf "search_%s_no-results" $translationKey }}
{{ $preselectedItems := .preselectedItems }}

<details class="filter{{ if $cssClass }} {{ $cssClass }}{{ end }} is-loading"
data-dropdown data-filter="{{ $name }}"
data-filter-items="{{ $filters | jsonify }}"
{{ if $preselectedItems }} data-preselected-items="{{ $preselectedItems }}"{{ end }}
{{ if $open }} open{{ end }}
>
<summary class="filter__title button button--small button--white">
Expand Down
2 changes: 2 additions & 0 deletions hugo/layouts/partials/search.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{{ $showContentTypes := .showContentTypes | default true }}
{{ $contentTypes := slice }}
{{ $contentType := .contentType | default "" }}
{{ $preselectedTags := .preselectedTags | default "" }}
{{ $type := .type | default "full" }}
{{ $placeholder := (T "search_placeholder" ) }}

Expand Down Expand Up @@ -46,6 +47,7 @@
"translationKey" "tags"
"name" "tags"
"filters" .Site.Params.tags
"preselectedItems" $preselectedTags
) -}}

{{ if $showContentTypes }}
Expand Down
2 changes: 2 additions & 0 deletions hugo/layouts/shortcodes/search.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
{{- $contentType := .Get "contentType" | default "" -}}
{{- $showContentTypes := .Get "showContentTypes" | default true -}}
{{- $preselectedTags := .Get "tags" | default "" -}}

{{- partial "search" (dict
"type" "widget"
"contentType" $contentType
"showContentTypes" $showContentTypes
"preselectedTags" $preselectedTags
"context" .
) -}}

0 comments on commit 4d81a5f

Please sign in to comment.