Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/WingLim/hugo-tania.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWingLim <643089849@qq.com>2021-06-13 11:47:02 +0300
committerGitHub <noreply@github.com>2021-06-13 11:47:02 +0300
commit00dd4c03613926c598b7d987285f25169ecd33e8 (patch)
tree6d8ded8e566d86315a4b43c906b69b06a8ae5ca9
parent44cb34cbb4d07e4d56a00629518eeafa2a166574 (diff)
feat(search): search in articles page (#13)
* feat: add search input * feat: use fuse to search * refactor: use div as results container * refactor: init fuse once * feat: set threshold 0.4 * feat: set fuse threshold to 0.3 0.3 search result looks better 0.4 * refactor: simplify result render * chore: make search input full width * docs: use yaml header * feat: add categories and tags filter * fix: searching in contents * fix: search input is empty * refactor: remove unused function * fix: add listener in articles page * refactor: rename articles to articlesList * docs: add comments * refactor: show categories only * feat: limit categories count
-rw-r--r--README.md7
-rw-r--r--assets/js/features.js250
-rw-r--r--assets/sass/components/_search.scss53
-rw-r--r--assets/sass/main.scss1
-rw-r--r--exampleSite/config.yaml5
-rw-r--r--exampleSite/content/post/emoji-support.md17
-rw-r--r--exampleSite/content/post/footnote.md2
-rw-r--r--exampleSite/content/post/markdown-syntax.md30
-rw-r--r--exampleSite/content/post/placeholder-text.md19
-rw-r--r--exampleSite/content/post/test-katex.md2
-rw-r--r--exampleSite/content/post/test-mathjax.md2
-rw-r--r--layouts/_default/archives.html15
-rw-r--r--layouts/index.json6
-rw-r--r--layouts/partials/footer.html1
14 files changed, 311 insertions, 99 deletions
diff --git a/README.md b/README.md
index e6907c2..d8cf056 100644
--- a/README.md
+++ b/README.md
@@ -66,6 +66,13 @@ If you want to disable the float footnotes, add below params.
enableFootnotes: false
```
+Limit how many categories filter show above search input.
+
+Default is `5`
+```yaml
+maxCategoryToShow: 10
+```
+
### Layout
`articles` layout is for showing all articles you write.
diff --git a/assets/js/features.js b/assets/js/features.js
index afc63b8..9d40716 100644
--- a/assets/js/features.js
+++ b/assets/js/features.js
@@ -1,65 +1,72 @@
-(function(d){
- let enableFootnotes = false
- if (d.currentScript) {
- enableFootnotes = d.currentScript.dataset['enableFootnotes'] == 'true'
- }
- renderFootnotes = function () {
- const removeEl = (el) => {
- if (!el) return;
- el.remove ? el.remove() : el.parentNode.removeChild(el);
- };
+let show = function (elem) {
+ elem.style.display = 'block';
+};
+let hide = function (elem) {
+ elem.style.display = 'none';
+};
- const insertAfter = (target, sib) => {
- target.after ? target.after(sib) : (
- target.parentNode.insertBefore(sib, target.nextSibling)
- );
- };
+(function (d) {
+ let enableFootnotes = false
+ if (d.currentScript) {
+ enableFootnotes = d.currentScript.dataset['enableFootnotes'] == 'true'
+ }
+ renderFootnotes = function () {
+ const removeEl = (el) => {
+ if (!el) return;
+ el.remove ? el.remove() : el.parentNode.removeChild(el);
+ };
- const insideOut = (el) => {
- var p = el.parentNode, x = el.innerHTML,
- c = document.createElement('div'); // a tmp container
- insertAfter(p, c);
- c.appendChild(el);
- el.innerHTML = '';
- el.appendChild(p);
- p.innerHTML = x; // let the original parent have the content of its child
- insertAfter(c, c.firstElementChild);
- removeEl(c);
- };
+ const insertAfter = (target, sib) => {
+ target.after ? target.after(sib) : (
+ target.parentNode.insertBefore(sib, target.nextSibling)
+ );
+ };
- document.querySelectorAll('.footnotes > ol > li[id^="fn"], #refs > div[id^="ref-"]').forEach(function (fn) {
- a = document.querySelectorAll('a[href="#' + fn.id + '"]');
- if (a.length === 0) return;
- a.forEach(function (el) { el.removeAttribute('href') });
- a = a[0];
- side = document.createElement('div');
- side.className = 'side side-right';
- if (/^fn/.test(fn.id)) {
- side.innerHTML = fn.innerHTML;
- var number = a.innerText; // footnote number
- side.firstElementChild.innerHTML = '<span class="bg-number">' + number +
- '</span> ' + side.firstElementChild.innerHTML;
- removeEl(side.querySelector('a[href^="#fnref"]')); // remove backreference
- a.parentNode.tagName === 'SUP' && insideOut(a);
- } else {
- side.innerHTML = fn.outerHTML;
- a = a.parentNode;
- }
- insertAfter(a, side);
- a.classList.add('note-ref');
- removeEl(fn);
- })
- document.querySelectorAll('.footnotes, #refs').forEach(function (fn) {
- var items = fn.children;
- if (fn.id === 'refs') return items.length === 0 && removeEl(fn);
- // there must be a <hr> and an <ol> left
- if (items.length !== 2 || items[0].tagName !== 'HR' || items[1].tagName !== 'OL') return;
- items[1].childElementCount === 0 && removeEl(fn);
- });
- };
- if (enableFootnotes) {
- renderFootnotes()
- }
+ const insideOut = (el) => {
+ var p = el.parentNode, x = el.innerHTML,
+ c = document.createElement('div'); // a tmp container
+ insertAfter(p, c);
+ c.appendChild(el);
+ el.innerHTML = '';
+ el.appendChild(p);
+ p.innerHTML = x; // let the original parent have the content of its child
+ insertAfter(c, c.firstElementChild);
+ removeEl(c);
+ };
+
+ document.querySelectorAll('.footnotes > ol > li[id^="fn"], #refs > div[id^="ref-"]').forEach(function (fn) {
+ a = document.querySelectorAll('a[href="#' + fn.id + '"]');
+ if (a.length === 0) return;
+ a.forEach(function (el) { el.removeAttribute('href') });
+ a = a[0];
+ side = document.createElement('div');
+ side.className = 'side side-right';
+ if (/^fn/.test(fn.id)) {
+ side.innerHTML = fn.innerHTML;
+ var number = a.innerText; // footnote number
+ side.firstElementChild.innerHTML = '<span class="bg-number">' + number +
+ '</span> ' + side.firstElementChild.innerHTML;
+ removeEl(side.querySelector('a[href^="#fnref"]')); // remove backreference
+ a.parentNode.tagName === 'SUP' && insideOut(a);
+ } else {
+ side.innerHTML = fn.outerHTML;
+ a = a.parentNode;
+ }
+ insertAfter(a, side);
+ a.classList.add('note-ref');
+ removeEl(fn);
+ })
+ document.querySelectorAll('.footnotes, #refs').forEach(function (fn) {
+ var items = fn.children;
+ if (fn.id === 'refs') return items.length === 0 && removeEl(fn);
+ // there must be a <hr> and an <ol> left
+ if (items.length !== 2 || items[0].tagName !== 'HR' || items[1].tagName !== 'OL') return;
+ items[1].childElementCount === 0 && removeEl(fn);
+ });
+ };
+ if (enableFootnotes) {
+ renderFootnotes()
+ }
})(document);
renderAnchor = function () {
@@ -177,4 +184,127 @@ switchDarkMode = function () {
// handle user click switch dark mode button
applyCustomDarkModeSettings(toggleCustomDarkMode());
})
-}(); \ No newline at end of file
+}();
+
+initFuse = function () {
+ const fuseOptions = {
+ shouldSort: true,
+ threshold: 0.3,
+ location: 0,
+ distance: 100,
+ maxPatternLength: 32,
+ minMatchCharLength: 1,
+ useExtendedSearch: true,
+ keys: [
+ { name: "title", weight: 0.8 },
+ { name: "contents", weight: 0.5 },
+ { name: "tags", weight: 0.3 },
+ { name: "categories", weight: 0.3 }
+ ]
+ };
+
+ fetch('/index.json')
+ .then(function (response) {
+ if (response.status !== 200) {
+ console.error('[' + response.status + ']Error:', response.statusText);
+ return;
+ }
+ response.json().then(function (pages) {
+ let fuse = new Fuse(pages, fuseOptions);
+ window.fuse = fuse;
+ })
+
+ })
+ .catch(function (err) {
+ console.error('[Fetch]Error:', err);
+ });
+}()
+
+const searchInput = document.getElementById('search-query');
+const searchResults = document.getElementById('search-results')
+const articlesList = document.getElementById('articles-list')
+if (searchInput != undefined) {
+ searchInput.addEventListener("input", function () {
+ let value = searchInput.value
+ executeSearch(buildSearchValue(value));
+ })
+}
+
+let searchFilter = new Map()
+buildSearchValue = function(value) {
+ let filter = []
+ if (searchFilter.size == 0 && value.length == 0) {
+ return ""
+ }
+ searchFilter.forEach((v, k) => {
+ let object = {}
+ if (v == "categories") {
+ object = {
+ categories: k
+ }
+ }
+ filter.push(object)
+ })
+ if (value != undefined && value.length != 0) {
+ let orObject = {
+ $or: [
+ {title: value},
+ // fuse extended search, 'value is include-match
+ // more details: https://fusejs.io/examples.html#extended-search
+ {contents: "'"+value}
+ ]
+ }
+ filter.push(orObject)
+ }
+ return {
+ $and: filter
+ }
+}
+
+filterSelect = function(element) {
+ let value = element.dataset.value
+ let type = element.dataset.type
+ if (element.classList.contains('active')) {
+ searchFilter.delete(value)
+ element.classList.remove('active')
+ } else {
+ searchFilter.set(value, type)
+ element.classList.add('active')
+ }
+ executeSearch(buildSearchValue(""))
+}
+
+executeSearch = function(value) {
+ if (value.length != 0) {
+ hide(articlesList)
+ show(searchResults)
+ } else {
+ hide(searchResults)
+ show(articlesList)
+ }
+
+ var result = fuse.search(value);
+ if (result.length > 0) {
+ populateResults(result);
+ } else {
+ searchResults.innerHTML = '<p>Sorry, nothing matched that search.</p>';
+ }
+
+ function populateResults(results) {
+ searchResults.innerHTML = ""
+
+ results.forEach(function (value) {
+ let item = value.item
+ let html = `
+ <div class="post">
+ <a href="${item.permalink}">
+ <div class="post-row">
+ <time>${item.date}</time>
+ <h3>${item.title}</h3>
+ </div>
+ </a>
+ </div>`
+ searchResults.innerHTML += html;
+ });
+ }
+}
diff --git a/assets/sass/components/_search.scss b/assets/sass/components/_search.scss
new file mode 100644
index 0000000..4f499b8
--- /dev/null
+++ b/assets/sass/components/_search.scss
@@ -0,0 +1,53 @@
+#search-query {
+ padding: .8rem 1rem;
+ background: var(--light-background);
+ border: 2px solid var(--border);
+ width: 100%;
+ border-radius: .35rem;
+ font-size: 1rem;
+ -webkit-appearance: none;
+ margin-left: auto;
+ margin-right: auto;
+ margin-bottom: 4rem;
+ outline-offset: 0;
+}
+#search-results {
+ display: none;
+}
+
+.filter-container {
+ display: flex;
+ justify-content: flex-start;
+ margin-bottom: 1.5rem;
+ flex-wrap: wrap;
+}
+
+.filter-item {
+ font-size: .85rem;
+ padding: .5rem .75rem;
+ background: #ebf1fe;
+ border-radius: 4px;
+ margin-right: .5rem;
+ margin-bottom: .5rem;
+ font-weight: 600;
+ cursor: pointer;
+
+ &:hover {
+ background: #d8e3fd;
+ color: #3972f4
+ }
+
+ &:last-of-type {
+ margin-right: 0;
+ }
+
+ &.active {
+ background: #5183f5;
+ color: #fff;
+
+ &:hover {
+ color: #fff;
+ background: #2161f2
+ }
+ }
+} \ No newline at end of file
diff --git a/assets/sass/main.scss b/assets/sass/main.scss
index 34b9aab..7195e76 100644
--- a/assets/sass/main.scss
+++ b/assets/sass/main.scss
@@ -15,6 +15,7 @@
@import "components/helpers";
@import "components/table";
@import "components/tags";
+@import "components/search";
@import "components/post";
@import "components/highlight";
diff --git a/exampleSite/config.yaml b/exampleSite/config.yaml
index e205454..71ffccf 100644
--- a/exampleSite/config.yaml
+++ b/exampleSite/config.yaml
@@ -25,4 +25,7 @@ markup:
lineNos: true
goldmark:
renderer:
- unsafe: true \ No newline at end of file
+ unsafe: true
+
+outputs:
+ home: ["HTML", "RSS", "JSON"] \ No newline at end of file
diff --git a/exampleSite/content/post/emoji-support.md b/exampleSite/content/post/emoji-support.md
index dc3589a..7c7ea76 100644
--- a/exampleSite/content/post/emoji-support.md
+++ b/exampleSite/content/post/emoji-support.md
@@ -1,12 +1,11 @@
-+++
-author = "Hugo Authors"
-title = "Emoji Support"
-date = "2019-03-05"
-description = "Guide to emoji usage in Hugo"
-tags = [
- "emoji",
-]
-+++
+---
+author: "Hugo Authors"
+title: "Emoji Support"
+date: "2019-03-05"
+description: "Guide to emoji usage in Hugo"
+tags:
+- emoji
+---
Emoji can be enabled in a Hugo project in a number of ways.
<!--more-->
diff --git a/exampleSite/content/post/footnote.md b/exampleSite/content/post/footnote.md
index e986eaa..48c3cac 100644
--- a/exampleSite/content/post/footnote.md
+++ b/exampleSite/content/post/footnote.md
@@ -1,6 +1,8 @@
---
author: Hugo Authors
title: Footnote test
+categories:
+- syntax
date: 2021-05-31
---
diff --git a/exampleSite/content/post/markdown-syntax.md b/exampleSite/content/post/markdown-syntax.md
index 06990d7..098f2cd 100644
--- a/exampleSite/content/post/markdown-syntax.md
+++ b/exampleSite/content/post/markdown-syntax.md
@@ -1,20 +1,16 @@
-+++
-author = "Hugo Authors"
-title = "Markdown Syntax Guide"
-date = "2019-03-11"
-description = "Sample article showcasing basic Markdown syntax and formatting for HTML elements."
-tags = [
- "markdown",
- "css",
- "html",
-]
-categories = [
- "themes",
- "syntax",
-]
-series = ["Themes Guide"]
-aliases = ["migrate-from-jekyl"]
-+++
+---
+author: "Hugo Authors"
+title: "Markdown Syntax Guide"
+date: "2019-03-11"
+description: "Sample article showcasing basic Markdown syntax and formatting for HTML elements."
+tags:
+- markdown
+- css
+- html
+categories:
+- themes
+- syntax
+---
This article offers a sample of basic Markdown syntax that can be used in Hugo content files, also it shows whether basic HTML elements are decorated with CSS in a Hugo theme.
<!--more-->
diff --git a/exampleSite/content/post/placeholder-text.md b/exampleSite/content/post/placeholder-text.md
index 9ed5f69..d619368 100644
--- a/exampleSite/content/post/placeholder-text.md
+++ b/exampleSite/content/post/placeholder-text.md
@@ -1,13 +1,12 @@
-+++
-author = "Hugo Authors"
-title = "Placeholder Text"
-date = "2019-03-09"
-description = "Lorem Ipsum Dolor Si Amet"
-tags = [
- "markdown",
- "text",
-]
-+++
+---
+author: "Hugo Authors"
+title: "Placeholder Text"
+date: "2019-03-09"
+description: "Lorem Ipsum Dolor Si Amet"
+tags:
+- markdown
+- text
+---
Lorem est tota propiore conpellat pectoribus de pectora summo. <!--more-->Redit teque digerit hominumque toris verebor lumina non cervice subde tollit usus habet Arctonque, furores quas nec ferunt. Quoque montibus nunc caluere tempus inhospita parcite confusaque translucet patri vestro qui optatis lumine cognoscere flos nubis! Fronde ipsamque patulos Dryopen deorum.
diff --git a/exampleSite/content/post/test-katex.md b/exampleSite/content/post/test-katex.md
index 6e15fc9..164a175 100644
--- a/exampleSite/content/post/test-katex.md
+++ b/exampleSite/content/post/test-katex.md
@@ -3,6 +3,8 @@ author: Hugo Authors
title: Katex support
date: 2021-05-22
description: "KaTeX is a fast, easy-to-use JavaScript library for TeX math rendering on the web."
+categories:
+- math
katex: true
---
diff --git a/exampleSite/content/post/test-mathjax.md b/exampleSite/content/post/test-mathjax.md
index d9116dc..02b9374 100644
--- a/exampleSite/content/post/test-mathjax.md
+++ b/exampleSite/content/post/test-mathjax.md
@@ -3,6 +3,8 @@ author: Hugo Authors
title: MathJax support
date: 2021-05-22
description: A brief guide to setup MathJax
+categories:
+- math
mathjax: true
---
diff --git a/layouts/_default/archives.html b/layouts/_default/archives.html
index 32f4937..06b2840 100644
--- a/layouts/_default/archives.html
+++ b/layouts/_default/archives.html
@@ -11,7 +11,19 @@
<section>
<div class="container">
- <section>
+ <div class="filter-container">
+ {{ $maxCategoryToShow := $.Site.Params.maxCategoryToShow | default 5 }}
+ {{ range .Site.Taxonomies.categories.TaxonomyArray | first $maxCategoryToShow }}
+ <div class="filter-item" data-value="{{ .Page.Title }}" data-type="categories" onclick="filterSelect(this)">
+ {{ .Page.Title }}<sup>{{ .Count }}</sup>
+ </div>
+ {{ end }}
+ </div>
+ <input id="search-query" type="search" placeholder="Search for anything...">
+
+ <div id="search-results">
+ </div>
+ <section id="articles-list">
{{ range $pages.GroupByDate "2006" }}
<section>
<h2>{{ .Key }}</h2>
@@ -23,7 +35,6 @@
<time>{{ .Date.Format "Jan 02" }}</time>
<h3>{{ .Title }}</h3>
</div>
- <!--<div class="new-post">New!</div>-->
</a>
</div>
{{ end }}
diff --git a/layouts/index.json b/layouts/index.json
new file mode 100644
index 0000000..d86ec6f
--- /dev/null
+++ b/layouts/index.json
@@ -0,0 +1,6 @@
+{{- $.Scratch.Add "index" slice -}}
+{{- range .Site.RegularPages -}}
+ {{- $date := .Date.Format "Jan 02"}}
+ {{- $.Scratch.Add "index" (dict "title" .Title "tags" .Params.tags "categories" .Params.categories "contents" .Plain "permalink" .Permalink "date" $date) -}}
+{{- end -}}
+{{- $.Scratch.Get "index" | jsonify -}} \ No newline at end of file
diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html
index c57d22f..eb44ed3 100644
--- a/layouts/partials/footer.html
+++ b/layouts/partials/footer.html
@@ -22,6 +22,7 @@
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/contrib/auto-render.min.js" integrity="sha384-vZTG03m+2yp6N6BNi5iM4rW4oIwk5DfcNdFfxkk9ZWpDriOkXX8voJBFrAO7MpVl" crossorigin="anonymous"
onload="renderMathInElement(document.querySelector('.article-post'));"></script>
{{- end }}
+ <script defer src="https://cdn.jsdelivr.net/npm/fuse.js@6.4.6/dist/fuse.min.js"></script>
{{ $features := resources.Get "js/features.js" | minify | fingerprint }}
<script async src="{{ $features.RelPermalink }}" data-enable-footnotes="{{ .Site.Params.enableFootnotes | default true }}"></script>
</footer> \ No newline at end of file