diff --git a/assets/js/third-party/search/algolia-search.js b/assets/js/third-party/search/algolia-search.js deleted file mode 100644 index 12a554c..0000000 --- a/assets/js/third-party/search/algolia-search.js +++ /dev/null @@ -1,130 +0,0 @@ -/* global instantsearch, algoliasearch, CONFIG, pjax */ - -document.addEventListener('DOMContentLoaded', () => { - const { indexName, appID, apiKey, hits } = CONFIG.algolia; - - const search = instantsearch({ - indexName, - searchClient : algoliasearch(appID, apiKey), - searchFunction: helper => { - if (document.querySelector('.search-input').value) { - helper.search(); - } - } - }); - - if (typeof pjax === 'object') { - search.on('render', () => { - pjax.refresh(document.querySelector('.algolia-hits')); - }); - } - - // Registering Widgets - search.addWidgets([ - instantsearch.widgets.configure({ - hitsPerPage: hits.per_page || 10 - }), - - instantsearch.widgets.searchBox({ - container : '.search-input-container', - placeholder : CONFIG.i18n.placeholder, - // Hide default icons of algolia search - showReset : false, - showSubmit : false, - showLoadingIndicator: false, - cssClasses : { - input: 'search-input' - } - }), - - instantsearch.widgets.stats({ - container: '.algolia-stats', - templates: { - text: data => { - const stats = CONFIG.i18n.hits_time - .replace('${hits}', data.nbHits) - .replace('${time}', data.processingTimeMS); - return `${stats} - Algolia`; - } - }, - cssClasses: { - text: 'search-stats' - } - }), - - instantsearch.widgets.hits({ - container : '.algolia-hits', - escapeHTML: false, - templates : { - item: data => { - const { title, excerpt, excerptStrip, contentStripTruncate } = data._highlightResult; - let result = `${title.value}`; - const content = excerpt || excerptStrip || contentStripTruncate; - if (content && content.value) { - const div = document.createElement('div'); - div.innerHTML = content.value; - result += `

${div.textContent.substring(0, 100)}...

`; - } - return result; - }, - empty: data => { - return `
- ${CONFIG.i18n.empty.replace('${query}', data.query)} -
`; - } - }, - cssClasses: { - list: 'search-result-list' - } - }), - - instantsearch.widgets.pagination({ - container: '.algolia-pagination', - scrollTo : false, - showFirst: false, - showLast : false, - templates: { - first : '', - last : '', - previous: '', - next : '' - }, - cssClasses: { - list : ['pagination', 'algolia-pagination'], - item : 'pagination-item', - link : 'page-number', - selectedItem: 'current', - disabledItem: 'disabled-item' - } - }) - ]); - - search.start(); - - // Handle and trigger popup window - document.querySelectorAll('.popup-trigger').forEach(element => { - element.addEventListener('click', () => { - document.body.classList.add('search-active'); - setTimeout(() => document.querySelector('.search-input').focus(), 500); - }); - }); - - // Monitor main search box - const onPopupClose = () => { - document.body.classList.remove('search-active'); - }; - - document.querySelector('.search-pop-overlay').addEventListener('click', event => { - if (event.target === document.querySelector('.search-pop-overlay')) { - onPopupClose(); - } - }); - document.querySelector('.popup-btn-close').addEventListener('click', onPopupClose); - document.addEventListener('pjax:success', onPopupClose); - window.addEventListener('keyup', event => { - if (event.key === 'Escape') { - onPopupClose(); - } - }); -}); diff --git a/assets/js/third-party/search/algolia.js b/assets/js/third-party/search/algolia.js new file mode 100644 index 0000000..1ffb1a0 --- /dev/null +++ b/assets/js/third-party/search/algolia.js @@ -0,0 +1,141 @@ +/* global instantsearch, algoliasearch, CONFIG, pjax */ + +document.addEventListener('DOMContentLoaded', () => { + + const algoiajs = NexT.utils.getCDNResource(NexT.CONFIG.algolia.js); + const instantschjs = NexT.utils.getCDNResource(NexT.CONFIG.algolia.instantjs); + + NexT.utils.getScript(algoiajs, {}); + NexT.utils.getScript(instantschjs, {}).then(() => { + + const { indexname, appid, apikey, hits } = NexT.CONFIG.algolia.cfg; + const indexName = indexname; + + const search = instantsearch({ + indexName, + searchClient: algoliasearch(appid, apikey), + searchFunction: helper => { + if (document.querySelector('.search-input').value) { + helper.search(); + } + } + }); + + if (typeof pjax === 'object') { + search.on('render', () => { + pjax.refresh(document.querySelector('.algolia-hits')); + }); + } + + // Registering Widgets + search.addWidgets([ + instantsearch.widgets.configure({ + hitsPerPage: hits.perpage || 10 + }), + + instantsearch.widgets.searchBox({ + container: '.search-input-container', + placeholder: NexT.CONFIG.i18n.placeholder, + // Hide default icons of algolia search + showReset: false, + showSubmit: false, + showLoadingIndicator: false, + cssClasses: { + input: 'search-input' + } + }), + + instantsearch.widgets.stats({ + container: '.algolia-stats', + templates: { + text: data => { + const stats = NexT.CONFIG.i18n.hits_time + .replace('${hits}', data.nbHits) + .replace('${time}', data.processingTimeMS); + return `${stats}`; + //Algolia`; + } + }, + cssClasses: { + text: 'search-stats' + } + }), + + instantsearch.widgets.hits({ + container: '.algolia-hits', + escapeHTML: false, + templates: { + item: data => { + const { title, excerpt, excerptStrip, contentStripTruncate } = data._highlightResult; + let result = `${title.value}`; + const content = excerpt || excerptStrip || contentStripTruncate; + if (content && content.value) { + const div = document.createElement('div'); + div.innerHTML = content.value; + result += `

${div.textContent.substring(0, 100)}...

`; + } + return result; + }, + empty: data => { + return `
+ ${NexT.CONFIG.i18n.empty.replace('${query}', data.query)} +
`; + } + }, + cssClasses: { + list: 'search-result-list' + } + }), + + instantsearch.widgets.pagination({ + container: '.algolia-pagination', + scrollTo: false, + showFirst: false, + showLast: false, + templates: { + first: '', + last: '', + previous: '', + next: '' + }, + cssClasses: { + list: ['pagination', 'algolia-pagination'], + item: 'pagination-item', + link: 'page-number', + selectedItem: 'current', + disabledItem: 'disabled-item' + } + }) + ]); + + search.start(); + + // Handle and trigger popup window + document.querySelectorAll('.popup-trigger').forEach(element => { + element.addEventListener('click', () => { + document.body.classList.add('search-active'); + setTimeout(() => document.querySelector('.search-input').focus(), 500); + }); + }); + + // Monitor main search box + const onPopupClose = () => { + document.body.classList.remove('search-active'); + }; + + document.querySelector('.search-pop-overlay').addEventListener('click', event => { + if (event.target === document.querySelector('.search-pop-overlay')) { + onPopupClose(); + } + }); + document.querySelector('.popup-btn-close').addEventListener('click', onPopupClose); + document.addEventListener('pjax:success', onPopupClose); + window.addEventListener('keyup', event => { + if (event.key === 'Escape') { + onPopupClose(); + } + }); + });; + + +}); \ No newline at end of file diff --git a/assets/js/third-party/search/local-search.js b/assets/js/third-party/search/local.js similarity index 100% rename from assets/js/third-party/search/local-search.js rename to assets/js/third-party/search/local.js diff --git a/data/resources.yaml b/data/resources.yaml index e95a2f7..f039b4c 100644 --- a/data/resources.yaml +++ b/data/resources.yaml @@ -39,8 +39,8 @@ analytics: addthis: js: https://s7.addthis.com/js/300/addthis_widget.js -# 评论组件资源 -# Comment component Resources +# 评论组件 +# Comment component waline: js: name: '@waline/client' @@ -70,4 +70,15 @@ utterances: js: https://utteranc.es/client.js livere: - js: https://cdn-city.livere.com/js/embed.dist.js \ No newline at end of file + js: https://cdn-city.livere.com/js/embed.dist.js + +# 全文搜索 +# Full text search +algolia: + name: algoliasearch + version: 4.13.0 + file: dist/algoliasearch-lite.umd.js +instant: + name: instantsearch.js + version: 4.40.5 + file: dist/instantsearch.production.min.js \ No newline at end of file diff --git a/exampleSite/config.yaml b/exampleSite/config.yaml index 4a3f898..f0d52ce 100644 --- a/exampleSite/config.yaml +++ b/exampleSite/config.yaml @@ -898,15 +898,17 @@ params: # --------------------------------------------------------------- - # TODO - # 内容搜索服务(暂时未实现) + # 内容搜索服务 # Search Services # --------------------------------------------------------------- # Algolia Search # For more information: https://www.algolia.com algoliaSearch: - enable: false + enable: true + appId: # + apiKey: # + indexName: # hits: perPage: 10 diff --git a/layouts/partials/init.html b/layouts/partials/init.html index 34aef75..22f8872 100644 --- a/layouts/partials/init.html +++ b/layouts/partials/init.html @@ -35,7 +35,6 @@ "bookmark" .Site.Params.bookmark "lazyload" .Site.Params.lazyload "motion" .Site.Params.motion - "localSearch" .Site.Params.localSearch "i18n" (dict "placeholder" (T "SearchPh") "empty" (T "SearchEmpty") @@ -44,6 +43,20 @@ ) }} +{{ if .Site.Params.localSearch.enable }} + {{ $localSearch := dict "localSearch" .Site.Params.localSearch }} + {{ $config = merge $config $localSearch }} +{{ end }} + +{{ if .Site.Params.algoliaSearch.enable }} + {{ $algoliaSearch := dict + "js" .Site.Data.resources.algolia + "instantjs" .Site.Data.resources.instant + "cfg" .Site.Params.algoliaSearch + }} + {{ $config = merge $config (dict "algolia" $algoliaSearch) }} +{{ end }} + {{ with .Site.Params.waline }} {{ $waline := dict "js" $.Site.Data.resources.waline.js diff --git a/layouts/partials/scripts.html b/layouts/partials/scripts.html index f7ac6dd..4015bd1 100644 --- a/layouts/partials/scripts.html +++ b/layouts/partials/scripts.html @@ -64,11 +64,17 @@ {{- $utterancesjs := resources.Get "js/third-party/comments/utterances.js" }} {{- $nextjs = $nextjs | append $utterancesjs }} {{- end }} +{{- if .Site.Params.localSearch.enable }} +{{- $search := resources.Get "js/third-party/search/local.js" }} +{{- $nextjs = $nextjs | append $search }} +{{ end }} +{{- if .Site.Params.algoliaSearch.enable }} +{{- $search := resources.Get "js/third-party/search/algolia.js" }} +{{- $nextjs = $nextjs | append $search }} +{{ end }} {{- $nextjs = $nextjs | resources.Concat "js/main.js"}} {{ if hugo.IsProduction }} {{- $nextjs = $nextjs | minify | fingerprint }} {{ end }} -{{- $search := resources.Get "js/third-party/search/local-search.js" }} -