From dbbe33812bb49373c2daad4c81fb6a20a7455b81 Mon Sep 17 00:00:00 2001 From: razonyang Date: Sat, 13 May 2023 14:20:02 +0800 Subject: [PATCH] feat: add the taxonomies filter --- assets/search/js/engine.ts | 26 +++++++++-- assets/search/js/form.ts | 46 ++++++++++++++++++- assets/search/js/renderer.ts | 6 ++- assets/search/scss/_dropdown.scss | 2 + assets/search/scss/_result.scss | 2 +- assets/search/scss/form/index.scss | 3 ++ data/search/i18n/de.toml | 12 +++++ data/search/i18n/en.toml | 12 +++++ data/search/i18n/nl.toml | 12 +++++ data/search/i18n/zh-hans.toml | 12 +++++ data/search/i18n/zh-hant.toml | 12 +++++ exampleSite/config/_default/config.toml | 1 + go.mod | 2 +- go.sum | 4 +- hugo.toml | 1 + .../partials/search/assets/js-resource.html | 25 +++++++++- layouts/partials/search/index.json.html | 2 +- 17 files changed, 168 insertions(+), 12 deletions(-) diff --git a/assets/search/js/engine.ts b/assets/search/js/engine.ts index 5dedd8e54c2..3d2482c0775 100644 --- a/assets/search/js/engine.ts +++ b/assets/search/js/engine.ts @@ -73,6 +73,10 @@ class Engine { keys.push('content') } + for (const taxonomy in params.taxonomies) { + keys.push(taxonomy) + } + return keys } @@ -88,8 +92,8 @@ class Engine { * @param {string} sorting language. * @returns {Promise>} */ - search(query: string, sorting = '', lang = '', years: Array = []): Promise> { - const pattern = this.pattern(query, lang, years) + search(query: string, sorting = '', lang = '', years: Array = [], taxonomies: Record> = {}): Promise> { + const pattern = this.pattern(query, lang, years, taxonomies) const start = (new Date()).getTime() return new Promise((resolve) => { setTimeout(() => { @@ -121,7 +125,7 @@ class Engine { * @param {string} query * @param {string} lang */ - private pattern(query: string, lang: string, years: Array = []): string | Record { + private pattern(query: string, lang: string, years: Array = [], taxonomies: Record> = {}): string | Record { if (lang === '') { return query } @@ -158,6 +162,22 @@ class Engine { }) } + for (const taxonomy in taxonomies) { + if (taxonomies[taxonomy].length === 0) { + continue + } + + const taxonomyConditions: Array> = [] + for (const name of taxonomies[taxonomy]) { + taxonomyConditions.push({ + [taxonomy]: `="${name}"`, + }) + } + p.push({ + "$and": taxonomyConditions + }) + } + return { "$and": p } diff --git a/assets/search/js/form.ts b/assets/search/js/form.ts index 3d723d7ec43..e9b648da8d1 100644 --- a/assets/search/js/form.ts +++ b/assets/search/js/form.ts @@ -45,6 +45,7 @@ export default class Form { ${this.renderLanguage()} ${this.renderSorting()} ${this.renderYears()} + ${this.renderTaxonomies()} +
    ${v}
+ ` + } + private initialized = false // Initialize the form after rendering. @@ -165,6 +188,12 @@ export default class Form { this.submit() }) + this.ele.querySelectorAll('.search-taxonomies').forEach((el) => { + el.addEventListener('change', () => { + this.submit() + }) + }) + engine.init().then(() => { this.input.removeAttribute('disabled') }).catch((err) => { @@ -220,7 +249,8 @@ export default class Form { const sorting = this.getSorting() const lang = this.getLanguage() const years = this.getYears() - engine.search(query, sorting, lang, years).then(({ results, time }) => { + const taxonomies = this.getTaxonomies() + engine.search(query, sorting, lang, years, taxonomies).then(({ results, time }) => { this.renderer.render(query, results, time) }).finally(() => { this.spinner.hide() @@ -267,5 +297,19 @@ export default class Form { }) return v } + + getTaxonomies(): Record> { + const v = {} + + for (const taxonomy in params.taxonomies) { + const terms: Array = [] + document.querySelectorAll(`.search-taxonomies-${taxonomy} .search-dropdown-item.active`).forEach((item) => { + terms.push(item.getAttribute('data-value') ?? '') + }) + v[taxonomy] = terms + } + + return v + } } diff --git a/assets/search/js/renderer.ts b/assets/search/js/renderer.ts index 1a8bcfb31a4..46ce4b43638 100644 --- a/assets/search/js/renderer.ts +++ b/assets/search/js/renderer.ts @@ -64,8 +64,10 @@ export default class Renderer { taxonomies(page) { let v = '' - for (const i in page.taxonomies) { - v += `${page.taxonomies[i]} ` + for (const key of params.taxonomyKeys) { + for (const name of page[key]) { + v += `${name}` + } } return v diff --git a/assets/search/scss/_dropdown.scss b/assets/search/scss/_dropdown.scss index 13f3792f424..340c052718a 100644 --- a/assets/search/scss/_dropdown.scss +++ b/assets/search/scss/_dropdown.scss @@ -26,6 +26,8 @@ border: 1px solid var(--search-border-color); border-radius: 0.25rem; margin: 1.5rem 0 0; + max-height: 30vh; + overflow: auto; padding: 0.5rem 0; } diff --git a/assets/search/scss/_result.scss b/assets/search/scss/_result.scss index 9b649cfecdc..aaaafd55570 100644 --- a/assets/search/scss/_result.scss +++ b/assets/search/scss/_result.scss @@ -58,7 +58,7 @@ } span { - margin-right: 0.125rem; + margin-right: 0.25rem; &span:not(:last-child) { &::after { diff --git a/assets/search/scss/form/index.scss b/assets/search/scss/form/index.scss index d02098eeedb..cb7e184dcc5 100644 --- a/assets/search/scss/form/index.scss +++ b/assets/search/scss/form/index.scss @@ -74,11 +74,14 @@ display: flex; justify-content: space-between; align-items: center; + flex-wrap: wrap; margin-top: 0.25rem; } .search-panel { display: flex; + flex-wrap: wrap; + margin-bottom: 0.5rem; } .search-panel-action { diff --git a/data/search/i18n/de.toml b/data/search/i18n/de.toml index 7747ae50453..568c0df7a1c 100644 --- a/data/search/i18n/de.toml +++ b/data/search/i18n/de.toml @@ -26,6 +26,18 @@ other = "Älteste" [sort_by_date_desc] other = "Neueste" +[taxonomy_authors] +other = "Authors" + +[taxonomy_categories] +other = "Categories" + +[taxonomy_series] +other = "Series" + +[taxonomy_tags] +other = "Tags" + [to_close] other = "Schließen" diff --git a/data/search/i18n/en.toml b/data/search/i18n/en.toml index 7cb5f1c3f5c..bfb2978cd36 100644 --- a/data/search/i18n/en.toml +++ b/data/search/i18n/en.toml @@ -26,6 +26,18 @@ other = "Oldest" [sort_by_date_desc] other = "Newest" +[taxonomy_authors] +other = "Authors" + +[taxonomy_categories] +other = "Categories" + +[taxonomy_series] +other = "Series" + +[taxonomy_tags] +other = "Tags" + [to_close] other = "to close" diff --git a/data/search/i18n/nl.toml b/data/search/i18n/nl.toml index e07fd48b25e..5e74db16cc0 100644 --- a/data/search/i18n/nl.toml +++ b/data/search/i18n/nl.toml @@ -26,6 +26,18 @@ other = "Oudste" [sort_by_date_desc] other = "Nieuwste" +[taxonomy_authors] +other = "Authors" + +[taxonomy_categories] +other = "Categories" + +[taxonomy_series] +other = "Series" + +[taxonomy_tags] +other = "Tags" + [to_close] other = "sluiten" diff --git a/data/search/i18n/zh-hans.toml b/data/search/i18n/zh-hans.toml index ff76a394251..779b31514cb 100644 --- a/data/search/i18n/zh-hans.toml +++ b/data/search/i18n/zh-hans.toml @@ -26,6 +26,18 @@ other = "最旧的" [sort_by_date_desc] other = "最新的" +[taxonomy_authors] +other = "作者" + +[taxonomy_categories] +other = "分类" + +[taxonomy_series] +other = "专栏" + +[taxonomy_tags] +other = "标签" + [to_close] other = "关闭" diff --git a/data/search/i18n/zh-hant.toml b/data/search/i18n/zh-hant.toml index bf3352c97b9..7e3452ad1ae 100644 --- a/data/search/i18n/zh-hant.toml +++ b/data/search/i18n/zh-hant.toml @@ -26,6 +26,18 @@ other = "最舊的" [sort_by_date_desc] other = "最新的" +[taxonomy_authors] +other = "作者" + +[taxonomy_categories] +other = "分類" + +[taxonomy_series] +other = "專欄" + +[taxonomy_tags] +other = "標籤" + [to_close] other = "關閉" diff --git a/exampleSite/config/_default/config.toml b/exampleSite/config/_default/config.toml index bfd07be64c4..f313d565467 100644 --- a/exampleSite/config/_default/config.toml +++ b/exampleSite/config/_default/config.toml @@ -31,3 +31,4 @@ LanguageDirection = 'rtl' # distance = 10000 # min_match_char_length = 3 # lazy_loading = false +# filter_taxonomies = false \ No newline at end of file diff --git a/go.mod b/go.mod index 05b1c2e66a1..be34ddcfe38 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,6 @@ go 1.18 require ( github.com/hugomods/fuse-js v0.1.0 // indirect - github.com/hugomods/i18n-js v0.1.0 // indirect + github.com/hugomods/i18n-js v0.2.0 // indirect github.com/hugomods/icons/vendors/bootstrap v0.5.0 // indirect ) diff --git a/go.sum b/go.sum index 764f896dd8b..5304abad249 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/hugomods/fuse-js v0.1.0 h1:CmWHBZANvjOP44RDNQNLntqlLf9GLqeM29jekxTNcPE= github.com/hugomods/fuse-js v0.1.0/go.mod h1:srCqvtBQR02HS/abTraDU4oINv1D3PljNPdexdoHhpo= -github.com/hugomods/i18n-js v0.1.0 h1:gJmJVObN8rvtMEwBW/z9Wiitown5ZT91092UaAO+UIE= -github.com/hugomods/i18n-js v0.1.0/go.mod h1:eJfxjgI2CQsNA1/ReIVvr5127DftUKcbHd2A2SQmDvU= +github.com/hugomods/i18n-js v0.2.0 h1:pZKidtnEm5l8KqlVsL/7xAbSDM/aLLAvFeQwNjl+W00= +github.com/hugomods/i18n-js v0.2.0/go.mod h1:eJfxjgI2CQsNA1/ReIVvr5127DftUKcbHd2A2SQmDvU= github.com/hugomods/icons v0.6.0 h1:G6RU93okhPPRDh/jqcew9gwkcYpSpg0rCBv4S6yUAFw= github.com/hugomods/icons/vendors/bootstrap v0.5.0 h1:CHEGk677heq2kJZa7XsGHRc3Hwizl9NFkmNw146OVm0= github.com/hugomods/icons/vendors/bootstrap v0.5.0/go.mod h1:kfC17VWV+tNi6PGF4AY7CJBBa1/HEgWxCYq2kNOdcdI= diff --git a/hugo.toml b/hugo.toml index 708caf87bf4..e04335919ef 100644 --- a/hugo.toml +++ b/hugo.toml @@ -48,3 +48,4 @@ index_all_pages = true index_content = false expand_results_meta = false lazy_loading = true +filter_taxonomies = true diff --git a/layouts/partials/search/assets/js-resource.html b/layouts/partials/search/assets/js-resource.html index d7210ba25a5..0c5400a896a 100644 --- a/layouts/partials/search/assets/js-resource.html +++ b/layouts/partials/search/assets/js-resource.html @@ -14,6 +14,26 @@ {{- end }} {{- $years = sort $years }} {{- end }} +{{/* taxonomies. */}} +{{- $taxonomies := newScratch }} +{{- if default true site.Params.search.filter_taxonomies }} + {{- $allTaxonomies := newScratch }} + {{- range .Site.Sites }} + {{- range $name, $taxonomy := .Taxonomies }} + {{- range $taxonomy }} + {{- $allTaxonomies.Add $name (slice .Page.Title) }} + {{- end }} + {{- end }} + {{- end }} + {{/* remove duplicate taxonomies. */}} + {{- range $name, $v := $allTaxonomies.Values }} + {{- $taxonomies.Set $name ($v | uniq) }} + {{- end }} +{{- end }} +{{- $taxonomyKeys := slice }} +{{- range $name, $v := .Site.Taxonomies }} + {{- $taxonomyKeys = $taxonomyKeys | append $name }} +{{- end }} {{/* i18n messages. */}} {{- $i18n := newScratch }} {{- range $lang, $messages := .Site.Data.search.i18n }} @@ -34,6 +54,7 @@ "sort" (partial "icons/icon" (dict "vendor" "bootstrap" "name" "sort-down" "width" "1rem" "height" "1rem")) "expand" (partial "icons/icon" (dict "vendor" "bootstrap" "name" "chevron-expand" "width" "1rem" "height" "1rem")) "year" (partial "icons/icon" (dict "vendor" "bootstrap" "name" "calendar-check" "width" "1rem" "height" "1rem")) + "taxonomies" (partial "icons/icon" (dict "vendor" "bootstrap" "name" "tags" "width" "1rem" "height" "1rem")) }} {{/* Include the following icons when necessary. */}} {{- if default true .Site.Params.search.index_all_pages }} @@ -58,7 +79,9 @@ "i18n" $i18n.Values "defaultLang" $defaultLang "langs" $langs.Values - "years" $years) + "years" $years + "taxonomies" $taxonomies.Values + "taxonomyKeys" $taxonomyKeys) }} {{- $options := dict "targetPath" "js/search.js" diff --git a/layouts/partials/search/index.json.html b/layouts/partials/search/index.json.html index bfc60a2e7bf..0680ab941e2 100644 --- a/layouts/partials/search/index.json.html +++ b/layouts/partials/search/index.json.html @@ -23,7 +23,7 @@ {{/* Taxonomies */}} {{- range $name, $taxonomy := $.Site.Taxonomies -}} {{- range $page.GetTerms $name -}} - {{- $item.Add "taxonomies" (slice .Title) -}} + {{- $item.Add $name (slice .Title) }} {{- end -}} {{- end -}} {{- $items = $items | append $item.Values -}}