diff options
| -rw-r--r-- | CONTRIBUTING.md | 2 | ||||
| -rw-r--r-- | assets/js/.eslintrc.yml | 2 | ||||
| -rw-r--r-- | assets/js/ga.js | 2 | ||||
| -rw-r--r-- | assets/js/search.js | 52 | ||||
| -rw-r--r-- | exampleSite/config/_default/params.yaml | 6 | ||||
| -rw-r--r-- | layouts/index.json | 47 | ||||
| -rw-r--r-- | layouts/partials/data.html | 9 | ||||
| -rw-r--r-- | layouts/shortcodes/form-search.html | 56 |
8 files changed, 93 insertions, 83 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0b5df56..3cef891 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -84,7 +84,7 @@ time to complete. - Be minified to a single line with no formatting - Not contain any JS or CSS section inside it - Not contain any additional transformations (matrix, translate, scale) - - Сompatible with [MIT License](https://raw.githubusercontent.com/sergeyklay/gohugo-theme-ed/master/LICENSE) + - Compatible with [MIT License](https://raw.githubusercontent.com/sergeyklay/gohugo-theme-ed/master/LICENSE) - Maintain clean commit history and use meaningful commit messages. Pull Requests with messy commit history (with commit messages like "update", "another update", etc) are difficult to review and won't diff --git a/assets/js/.eslintrc.yml b/assets/js/.eslintrc.yml new file mode 100644 index 0000000..add5a78 --- /dev/null +++ b/assets/js/.eslintrc.yml @@ -0,0 +1,2 @@ +parserOptions: + sourceType: module diff --git a/assets/js/ga.js b/assets/js/ga.js index ae324bb..83d1b6e 100644 --- a/assets/js/ga.js +++ b/assets/js/ga.js @@ -1,5 +1,3 @@ -'use strict'; - function isDoNotTrackEnabled() { if (typeof window === 'undefined') { return false; diff --git a/assets/js/search.js b/assets/js/search.js index 484f3d9..bfb91c8 100644 --- a/assets/js/search.js +++ b/assets/js/search.js @@ -1,10 +1,6 @@ -'use strict'; +import {searchConfig, i18n} from '@params'; -let config, pagesIndex, searchIndex; - -// Maximum length (in words) of each text blurb. You can change this -// value if you find that 100 is too short or too long for your taste. -const MAX_SUMMARY_LENGTH = 100; +let pagesIndex, searchIndex; // Since the blurb is comprised of full sentences containing any search // term, we need a way to identify where each sentence begins/ends. This @@ -17,38 +13,9 @@ const SENTENCE_BOUNDARY_REGEX = /\b\.\s/gm; // in the blurb as it is being built. const WORD_REGEX = /\b(\w*)[\W|\s|\b]?/gm; -function buildPath(...args) { - return args.map((part, i) => { - if (i === 0) { - return part.trim().replace(/[/]*$/g, ''); - } - return part.trim().replace(/(^[/]*|[/]*$)/g, ''); - }).filter(x=>x.length).join('/'); -} - -function initConfig() { - const defaults = { - strings: { - searchEnterTerm: 'Please enter a search term.', - searchNoResults: 'No results found.' - }, - site: { - baseUrl: '/' - } - }; - - try { - const config = JSON.parse(document.querySelector('#ed-data').innerHTML); - return Object.assign({}, defaults, config); - } catch (e) { - return defaults; - } -} - async function initSearchIndex() { try { - const url = buildPath(config.site.baseUrl, 'index.json'); - const response = await fetch(url); + const response = await fetch(searchConfig.indexURI); if (response.status !== 200) return; @@ -58,6 +25,7 @@ async function initSearchIndex() { searchIndex = lunr(function () { // eslint-disable-line no-undef this.use(lunr.multiLanguage('de', 'en', 'es', 'fr', 'it', 'pt', 'ru')); // eslint-disable-line no-undef + this.field('objectID'); this.field('title'); this.field('categories'); this.field('tags'); @@ -76,14 +44,14 @@ function handleSearchQuery(event) { const query = document.getElementById('search').value.trim().toLowerCase(); if (!query) { - displayErrorMessage(config.strings.searchEnterTerm); + displayErrorMessage(i18n.enterTerm); hideSearchResults(); return; } const results = searchSite(query); if (!results.length) { - displayErrorMessage(config.strings.searchNoResults); + displayErrorMessage(i18n.noResults); hideSearchResults(); return; } @@ -220,9 +188,9 @@ function createSearchResultBlurb(query, pageContent) { if (pageBreakers.length > 0) { searchResultText = fixPageBreakers(searchResultText, pageBreakers); } - if (searchResultWords.length >= MAX_SUMMARY_LENGTH) break; + if (searchResultWords.length >= searchConfig.maxSummaryLength) break; } - return ellipsize(searchResultText, MAX_SUMMARY_LENGTH).replace( + return ellipsize(searchResultText, searchConfig.maxSummaryLength).replace( searchQueryRegex, '<span class="search-item">$&</span>' ); @@ -324,6 +292,7 @@ if (!String.prototype.matchAll) { }; } +initSearchIndex(); document.addEventListener('DOMContentLoaded', function () { const searchForm = document.getElementById('search-form'); const searchInput = document.getElementById('search'); @@ -332,9 +301,6 @@ document.addEventListener('DOMContentLoaded', function () { return; } - config = initConfig(); - initSearchIndex(); - searchForm.addEventListener('submit', (e) => { e.preventDefault(); }); diff --git a/exampleSite/config/_default/params.yaml b/exampleSite/config/_default/params.yaml index 9387248..42685e5 100644 --- a/exampleSite/config/_default/params.yaml +++ b/exampleSite/config/_default/params.yaml @@ -91,3 +91,9 @@ facebook_id: '' # Twitter username for the website twitter: john_doe + +# Configure search engine +search: + # Maximum length (in words) of each text blurb. You can change this + # value if you find that 100 is too short or too long for your taste. + maxSummaryLength: 100 diff --git a/layouts/index.json b/layouts/index.json index 05d731f..538cfcc 100644 --- a/layouts/index.json +++ b/layouts/index.json @@ -1,3 +1,4 @@ +{{- /* Generate the search index. */ -}} {{- $pages := slice -}} {{- $mainSections := site.Params.mainSections | default (slice "posts") }} @@ -7,19 +8,43 @@ {{- $.Scratch.Add "urlsAdded" slice -}} {{- range $index, $page := $pages -}} - {{- if gt (len $page.Content) 0 -}} - {{- if not (in ($.Scratch.Get "urlsAdded") $page.Permalink) -}} - {{- $pageData := (dict - "title" $page.Title - "href" $page.Permalink - "tags" (delimit ($page.Params.tags | default slice) " ; ") - "categories" (delimit ($page.Params.categories | default slice) " ; ") - "content" $page.Plain - ) -}} - {{- $.Scratch.Add "pagesIndex" $pageData -}} - {{- $.Scratch.Add "urlsAdded" $page.Permalink -}} + {{- /* Do not index drafts or private pages. */ -}} + {{- if and (not .Draft) (not .Params.private) | and (ne .Params.searchable false) -}} + + {{- /* Do not index pages w/o content. */ -}} + {{- if gt (len $page.Content) 0 -}} + + {{- /* Add page to index. */ -}} + {{- if not (in ($.Scratch.Get "urlsAdded") $page.Permalink) -}} + + {{/* Exclude virtual pages which aren't backed by a file */}} + {{ if .File }} + {{- $pageData := (dict + "objectID" $page.File.UniqueID + "date" $page.Date.UTC.Unix + "publishDate" $page.PublishDate + "lastmod" $page.Lastmod.UTC.Unix + "expiryDate" $page.ExpiryDate.UTC.Unix + "lang" $page.Lang + "title" $page.Title + "href" $page.Permalink + "kind" $page.Kind + "type" $page.Type + "section" $page.Section + "tags" (delimit ($page.Params.tags | default slice) " ; ") + "categories" (delimit ($page.Params.categories | default slice) " ; ") + "content" $page.Plain + ) -}} + {{- $.Scratch.Add "pagesIndex" $pageData -}} + {{- $.Scratch.Add "urlsAdded" $page.Permalink -}} + {{- end -}} + + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} {{- $.Scratch.Get "pagesIndex" | jsonify -}} diff --git a/layouts/partials/data.html b/layouts/partials/data.html index fa12238..afacc83 100644 --- a/layouts/partials/data.html +++ b/layouts/partials/data.html @@ -2,13 +2,6 @@ { "analytics_code": {{ site.GoogleAnalytics | default "" }}, "page_title": {{- partial "title.html" . -}}, - "language": {{ site.LanguageCode | default site.Language.Lang }}, - "strings": { - "searchEnterTerm": {{ i18n "search_enter_term" }}, - "searchNoResults": {{ i18n "search_no_results" }} - }, - "site": { - "baseUrl": {{ site.BaseURL }} - } + "language": {{ site.LanguageCode | default site.Language.Lang }} } </script> diff --git a/layouts/shortcodes/form-search.html b/layouts/shortcodes/form-search.html index f328f38..873c73a 100644 --- a/layouts/shortcodes/form-search.html +++ b/layouts/shortcodes/form-search.html @@ -22,32 +22,52 @@ <div id="search-results-body" class="post-list"></div> </section> -{{- $vendors := slice (resources.Get "js/vendor/lunr.js") -}} -{{- $vendors = $vendors | append (resources.Get "js/vendor/lunr.multi.js" ) -}} -{{- $vendors = $vendors | append (resources.Get "js/vendor/lunr.stemmer.support.js" ) -}} +{{- $isProduction := (or (eq (getenv "HUGO_ENV") "production") (eq site.Params.env "production")) -}} + +{{- /* Add lunr.js. */ -}} +{{- $lunrSearch := slice (resources.Get "js/vendor/lunr.js") -}} + +{{- /* Add lunr multilanguage support. */ -}} +{{- $lunrSearch = $lunrSearch | append (resources.Get "js/vendor/lunr.multi.js" ) -}} +{{- $lunrSearch = $lunrSearch | append (resources.Get "js/vendor/lunr.stemmer.support.js" ) -}} {{- $lunrLangs := slice "de" "es" "fr" "it" "pt" "ru" -}} {{- range $lunrLangs -}} - {{ $vendors = $vendors | append (resources.Get (printf "js/vendor/lunr.%s.js" .) ) }} + {{ $lunrSearch = $lunrSearch | append (resources.Get (printf "js/vendor/lunr.%s.js" .) ) -}} {{- end -}} -{{- $vendors = $vendors | resources.Concat "js/lunr-bundle.js" -}} -{{- if or (eq (getenv "HUGO_ENV") "production") (eq site.Params.env "production") }} - {{- $vendors = $vendors | minify -}} +{{- /* Build lunr. */ -}} +{{- $lunrSearch = $lunrSearch | resources.Concat "js/lunr-bundle.js" -}} + +{{- if $isProduction -}} + {{- $lunrSearch = $lunrSearch | minify -}} {{- end -}} -{{- if not site.Params.assets.disable_fingerprinting -}} - {{- $vendors = $vendors | fingerprint -}} - <script src="{{ $vendors.RelPermalink }}" integrity="{{ $vendors.Data.Integrity }}"></script> + +{{- if or (site.Params.assets.disable_fingerprinting) (not $isProduction) }} + <script src="{{ $lunrSearch.RelPermalink }}"></script> {{- else -}} - <script src="{{ $vendors.RelPermalink }}"></script> + {{- $lunrSearch = $lunrSearch | fingerprint }} + <script src="{{ $lunrSearch.RelPermalink }}" integrity="{{ $lunrSearch.Data.Integrity }}"></script> {{- end -}} -{{- $search := resources.Get "js/search.js" -}} -{{- if or (eq (getenv "HUGO_ENV") "production") (eq site.Params.env "production") }} - {{- $search = $search | minify -}} +{{- /* Configure search engine. */ -}} +{{- $maxSummaryLength := site.Params.search.maxSummaryLength | default 100 -}} +{{- $searchConfig := dict "indexURI" ("/index.json" | relLangURL) "maxSummaryLength" $maxSummaryLength -}} +{{- $searchI18n := dict "enterTerm" (i18n "search_enter_term") "noResults" (i18n "search_no_results") -}} +{{- $searchParams := dict "searchConfig" $searchConfig "i18n" $searchI18n -}} + +{{- $siteSearch := slice -}} +{{- $siteSearch = $siteSearch | append (resources.Get "js/search.js") -}} +{{- $siteSearch = $siteSearch | resources.Concat "js/search-bundle.js" -}} + +{{- if $isProduction -}} + {{- $siteSearch = $siteSearch | js.Build (dict "format" "iife" "params" $searchParams) | minify -}} +{{ else }} + {{- $siteSearch = $siteSearch | js.Build (dict "format" "iife" "sourceMap" "inline" "params" $searchParams) -}} {{- end -}} -{{- if not site.Params.assets.disable_fingerprinting -}} - {{- $search = $search | fingerprint -}} - <script src="{{ $search.RelPermalink }}" integrity="{{ $search.Data.Integrity }}"></script> + +{{- if or (site.Params.assets.disable_fingerprinting) (not $isProduction) }} + <script src="{{ $siteSearch.RelPermalink }}"></script> {{- else -}} - <script src="{{ $search.RelPermalink }}"></script> + {{- $siteSearch = $siteSearch | fingerprint }} + <script src="{{ $siteSearch.RelPermalink }}" integrity="{{ $siteSearch.Data.Integrity }}"></script> {{- end -}} |
