feat: upgrade Algolia integration from v2 to v4

This commit is contained in:
George Cushen 2021-12-15 23:34:45 +00:00
commit ee434ab7ef
11 changed files with 156 additions and 92 deletions

View file

@ -1,5 +1,6 @@
_vendor/
vendor/
wowchemy/assets/css/libs/
public/
resources/

View file

@ -6,7 +6,7 @@
[![Discord](https://img.shields.io/discord/722225264733716590?style=for-the-badge)](https://discord.com/channels/722225264733716590/742892432458252370/742895548159492138)
[![GitHub Sponsors](https://img.shields.io/github/sponsors/gcushen?label=%E2%9D%A4%EF%B8%8F%20sponsor&style=for-the-badge)](https://github.com/sponsors/gcushen)
[![Twitter Follow](https://img.shields.io/twitter/follow/wowchemy?label=Follow%20on%20Twitter&style=for-the-badge)](https://twitter.com/wowchemy)
[![GitHub followers](https://img.shields.io/github/followers/gcushen?label=Follow%20on%20GH&style=for-the-badge)](https://github.com/gcushen)
[![GitHub followers](https://img.shields.io/github/followers/gcushen?label=Follow%20on%20GH&style=for-the-badge)](https://github.com/gcushen)
# [Wowchemy](https://wowchemy.com): the website builder for [Hugo](https://gohugo.io)
@ -83,5 +83,3 @@ Feel free to [_star_ the project on Github](https://github.com/wowchemy/wowchemy
Copyright 2016-present [George Cushen](https://georgecushen.com).
The [Wowchemy Hugo Themes](https://github.com/wowchemy/wowchemy-hugo-themes/) repository is released under the [MIT](https://github.com/wowchemy/wowchemy-hugo-themes/blob/main/LICENSE.md) license.
[![Analytics](https://ga-beacon.appspot.com/UA-78646709-2/wowchemy-hugo-themes/readme?pixel)](https://github.com/igrigorik/ga-beacon)

View file

@ -6,72 +6,108 @@
**************************************************/
import {algoliaConfig, i18n, content_type} from '@params';
import algoliasearch from 'https://cdn.jsdelivr.net/npm/algoliasearch@4/dist/algoliasearch.esm.browser.js';
// import instantsearch from 'https://cdn.jsdelivr.net/npm/instantsearch.js@4/es/index.js'
// import {searchBox, infiniteHits} from 'https://cdn.jsdelivr.net/npm/instantsearch.js@4/es/widgets/index.js';
function getTemplate(templateName) {
return document.querySelector(`#${templateName}-template`).innerHTML;
}
if (typeof instantsearch === 'function' && $('#search-box').length) {
const options = {
appId: algoliaConfig.appId,
apiKey: algoliaConfig.apiKey,
indexName: algoliaConfig.indexName,
routing: true,
searchParameters: {
hitsPerPage: 10,
},
searchFunction: function (helper) {
let searchResults = document.querySelector('#search-hits');
let commonQueries = document.querySelector('#search-common-queries');
if (helper.state.query === '') {
searchResults.style.display = 'none';
commonQueries.style.display = 'block';
return;
}
helper.search();
commonQueries.style.display = 'none';
searchResults.style.display = 'block';
},
};
const search = instantsearch(options);
// Initialize search box.
search.addWidget(
instantsearch.widgets.searchBox({
container: '#search-box',
autofocus: true,
reset: true,
poweredBy: algoliaConfig.poweredBy,
placeholder: i18n.placeholder,
}),
);
// Initialize search results.
search.addWidget(
instantsearch.widgets.infiniteHits({
container: '#search-hits',
escapeHits: true,
templates: {
empty: '<div class="search-no-results">' + i18n.no_results + '</div>',
item: getTemplate('search-hit-algolia'),
},
cssClasses: {
showmoreButton: 'btn btn-outline-primary',
},
}),
);
// On render search results, localize the content type metadata.
search.on('render', function () {
$('.search-hit-type').each(function () {
let content_key = $(this).text();
if (content_key in content_type) {
$(this).text(content_type[content_key]);
}
});
});
// Start search.
search.start();
// Get query from URI.
function getSearchQuery(name) {
return decodeURIComponent((location.search.split(name + '=')[1] || '').split('&')[0]).replace(/\+/g, ' ');
}
// On page load, check for search query in URL.
document.addEventListener('DOMContentLoaded', () => {
let queryURL = getSearchQuery('q');
if (queryURL) {
$('body').addClass('searching');
$('.search-results').css({opacity: 0, visibility: 'visible'}).animate({opacity: 1}, 200);
let commonQueries = document.querySelector('#search-common-queries');
commonQueries.style.display = 'none';
}
if (typeof instantsearch === 'function' && $('#search-box').length) {
const search = instantsearch({
indexName: algoliaConfig.indexName,
searchClient: algoliasearch(algoliaConfig.appId, algoliaConfig.apiKey), //'appId', 'apiKey'),
routing: {
router: instantsearch.routers.history({
parseURL() {
return {
q: getSearchQuery('q'),
};
},
}),
stateMapping: {
stateToRoute(uiState) {
const indexUiState = uiState[algoliaConfig.indexName];
return {
q: indexUiState.query,
};
},
routeToState(routeState) {
return {
[algoliaConfig.indexName]: {
query: routeState.q,
},
};
},
},
},
});
// Initialize search box.
search.addWidget(
instantsearch.widgets.searchBox({
container: '#search-box',
autofocus: true,
showReset: true,
//poweredBy: algoliaConfig.poweredBy,
placeholder: i18n.placeholder,
queryHook(query, search) {
let searchResults = document.querySelector('#search-hits');
let commonQueries = document.querySelector('#search-common-queries');
if (query === '') {
searchResults.style.display = 'none';
commonQueries.style.display = 'block';
return;
}
search(query);
commonQueries.style.display = 'none';
searchResults.style.display = 'block';
},
}),
);
// Initialize search results.
search.addWidget(
instantsearch.widgets.infiniteHits({
container: '#search-hits',
escapeHTML: true,
templates: {
empty: '<div class="search-no-results">' + i18n.no_results + '</div>',
item: getTemplate('search-hit-algolia'),
},
cssClasses: {
loadMore: 'btn btn-outline-primary',
},
}),
);
// On render search results, localize the content type metadata.
search.on('render', function () {
$('.search-hit-type').each(function () {
let content_key = $(this).text();
if (content_key in content_type) {
$(this).text(content_type[content_key]);
}
});
});
// Start search.
search.start();
}
});

View file

@ -24,7 +24,7 @@ console.debug(`Environment: ${hugoEnvironment}`);
// Dynamically get responsive navigation bar height for offsetting Scrollspy.
function getNavBarHeight() {
let navbar = document.getElementById('navbar-main');
let navbarHeight = (navbar) ? navbar.getBoundingClientRect().height : 0;
let navbarHeight = navbar ? navbar.getBoundingClientRect().height : 0;
console.debug('Navbar height: ' + navbarHeight);
return navbarHeight;
}
@ -364,7 +364,12 @@ function toggleSearchDialog() {
// Show search modal.
$('body').addClass('searching');
$('.search-results').css({opacity: 0, visibility: 'visible'}).animate({opacity: 1}, 200);
$('#search-query').focus();
let algoliaSearchBox = document.querySelector('.ais-SearchBox-input');
if (algoliaSearchBox) {
algoliaSearchBox.focus();
} else {
$('#search-query').focus();
}
}
}

View file

@ -238,16 +238,16 @@ ul.toc-top {
#TableOfContents li {
display: block;
margin-bottom: 8px; // Lighthouse: tap targets must be at least 8px apart
margin-bottom: 8px; // Lighthouse: tap targets must be at least 8px apart
}
#TableOfContents li a,
.toc-top li a {
display: block;
padding: 0 1.5rem; // Override default padding
padding: 0 1.5rem; // Override default padding
color: rgba(0, 0, 0, 0.65);
line-height: 1.75; // Lighthouse: min tap target size
font-size: 16px; // Lighthouse: min tap target size
line-height: 1.75; // Lighthouse: min tap target size
font-size: 16px; // Lighthouse: min tap target size
}
.dark #TableOfContents li a,

View file

@ -86,6 +86,31 @@
overflow-x: hidden;
}
// Override Algolia results style
.ais-Hits-item,
.ais-InfiniteHits-item {
background: unset;
box-shadow: unset;
padding: unset;
}
// Override Algolia search box icon style
.ais-SearchBox-form::before {
all: unset; // clear Algolia style
height: 1rem;
left: 1rem;
margin-top: -0.5rem;
position: absolute;
top: 50%;
width: 1rem;
font-family: 'Font Awesome 5 Free';
font-weight: 900;
content: '\f002';
font-size: 100%;
opacity: 0.7;
line-height: 1;
}
.dark #search-query {
background-color: $sta-dark-background;
}

View file

@ -104,7 +104,7 @@ ul.ul-edu li .description p.institution {
// For about.avatar widget
.avatar-wrapper {
position: relative;
width: 150px; // Match image size in about.avatar widget
width: 150px; // Match image size in about.avatar widget
height: 150px;
margin-left: auto;
margin-right: auto;
@ -120,7 +120,7 @@ ul.ul-edu li .description p.institution {
text-align: center;
font-size: 20px;
background-color: #fff;
color: #000; // override parent alpha
color: #000; // override parent alpha
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.04), 0 2px 6px rgba(0, 0, 0, 0.04), 0 0 1px rgba(0, 0, 0, 0.04);
}
}

View file

@ -49,9 +49,8 @@
sri = "sha512-mhbv5DqBMgrWL+32MmsDOt/OAvqr/cHimk6B8y/bx/xS88MVkYGPiVv2ixKVrkywF2qHplNRUvFsAHUdxZ3Krg=="
url = "https://cdn.jsdelivr.net/gh/julmot/mark.js@%s/dist/jquery.mark.min.js"
[js.instantsearch]
version = "2.10.5"
sri = "sha512-fsaJ0SdBVinKOpq2u2o1kMKexDBGkEepm+4RmSEW4E2kKxkMw+3VFpWOIhFaXwxb+x9HJ2nLpKFGajju5esK1w=="
url = "https://cdn.jsdelivr.net/npm/instantsearch.js@%s/dist/instantsearch.min.js"
version = "4" # no SRI as we use latest major version
url = "https://cdn.jsdelivr.net/npm/instantsearch.js@%s/dist/instantsearch.production.min.js"
[js.anchor]
version = "4.2.2"
sri = "sha512-I7w3ZdSFzw5j3jU3ZkNikBNeIrl3i+hEuEdwNmqUJvwNcaBUNcijnP2gd9DtGlgVYDplfjGoD8vTNsID+lCjqg=="
@ -84,13 +83,9 @@
sri = "sha512-H9jrZiiopUdsLpg94A333EfumgUBpO9MdbxStdeITo+KEIMaNfHNvwyjjDJb+ERPaRS6DpyRlKbvPUasNItRyw=="
url = "https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@%s/dist/jquery.fancybox.min.css"
[css.instantsearch]
version = "2.9.0"
sri = "sha512-r0ZHmgMRCi4mGWwva52RW2IXabjPr7sFVpcy4QIjDVTcgwadvP33dFG6gmZDe8lS2c96dPly57jDVZ4r6t8QCg=="
url = "https://cdn.jsdelivr.net/npm/instantsearch.js@%s/dist/instantsearch.min.css"
[css.instantsearchTheme]
version = "2.10.5"
sri = "sha512-AjQHx1UkDult/5TlKWqKapSLLMmNTJk7WINfp0F08inVEjpjeVPGiXOgTT9YCUyQE31xNBsajMRA7T8MQqK3cA=="
url = "https://cdn.jsdelivr.net/npm/instantsearch.js@%s/dist/instantsearch-theme-algolia.min.css"
version = "7.4.5"
sri = "sha256-TehzF/2QvNKhGQrrNpoOb2Ck4iGZ1J/DI4pkd2oUsBc="
url = "https://cdn.jsdelivr.net/npm/instantsearch.css@%s/themes/satellite-min.css"
[css.highlight]
version = "10.2.1"
sri = "" # No SRI as highlight style is determined at run time.

View file

@ -14,7 +14,7 @@
</div>
</button>
{{ if eq (lower site.Params.search.provider) "wowchemy" }}
{{ if in (slice "wowchemy" "algolia") (lower site.Params.search.provider) }}
<button class="form-control sidebar-search js-search d-none d-md-flex">
<i class="fas fa-search pr-2"></i>
<span class="sidebar-search-text">{{ i18n "search_placeholder" }}</span>

View file

@ -172,7 +172,6 @@
{{ if eq (lower site.Params.search.provider) "algolia" }}
{{ printf "<link rel=\"stylesheet\" href=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\">" (printf $css.instantsearch.url $css.instantsearch.version) $css.instantsearch.sri | safeHTML }}
{{ printf "<link rel=\"stylesheet\" href=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\">" (printf $css.instantsearchTheme.url $css.instantsearchTheme.version) $css.instantsearchTheme.sri | safeHTML }}
{{ end }}
{{/* Load async scripts. */}}

View file

@ -87,15 +87,15 @@
<div class="search-hit">
<div class="search-hit-content">
<div class="search-hit-name">
{{ printf "<a href=\"%s\">{{{_highlightResult.title.value}}}</a>" "{{relpermalink}}" | safeHTML }}
{{ printf "<a href=\"%s\">{{#helpers.highlight}}{ \"attribute\": \"title\" }{{/helpers.highlight}}</a>" "{{relpermalink}}" | safeHTML }}
</div>
<div class="article-metadata search-hit-type">{{"{{type}}"}}</div>
<p class="search-hit-description">{{ safeHTML "{{{_highlightResult.summary.value}}}" }}</p>
<p class="search-hit-description">{{ safeHTML "{{#helpers.highlight}}{ \"attribute\": \"summary\" }{{/helpers.highlight}}" }}</p>
</div>
</div>
</script>
{{ if ($scr.Get "use_cdn") }}
{{ printf "<script src=\"%s\" integrity=\"%s\" crossorigin=\"anonymous\"></script>" (printf $js.instantsearch.url $js.instantsearch.version) $js.instantsearch.sri | safeHTML }}
{{ printf "<script src=\"%s\" crossorigin=\"anonymous\"></script>" (printf $js.instantsearch.url $js.instantsearch.version) | safeHTML }}
{{ end }}
{{ $algoliaConfig = dict "appId" (site.Params.search.algolia.app_id | default "") "apiKey" (site.Params.search.algolia.api_key | default "") "indexName" (site.Params.search.algolia.index_name | default "") "poweredBy" (site.Params.search.algolia.show_logo | default false) }}
{{ end }}
@ -123,6 +123,14 @@
{{ $js_search_params = dict "search_config" $search_config "algoliaConfig" $algoliaConfig "i18n" $search_i18n "content_type" $content_types }}
{{ end }}
{{ if eq $search_provider "algolia" }}
{{ $js_algolia_search := resources.Get "js/algolia-search.js" | js.Build (dict "format" "esm" "targetPath" (printf "%s/js/algolia-search-built.js" .Lang) "params" $js_search_params) }}
{{- if hugo.IsProduction -}}
{{- $js_algolia_search = $js_algolia_search | minify | fingerprint "md5" -}}
{{- end -}}
<script src="{{ $js_algolia_search.RelPermalink }}" type="module"></script>
{{ end }}
{{ $js_license := printf "/*! Wowchemy v%s | https://wowchemy.com/ */\n" site.Data.wowchemy.version }}
{{ $js_license := $js_license | printf "%s/*! Copyright 2016-present George Cushen (https://georgecushen.com/) */\n" }}
{{ $js_license := $js_license | printf "%s/*! License: https://github.com/wowchemy/wowchemy-hugo-themes/blob/main/LICENSE.md */\n" }}
@ -133,9 +141,6 @@
{{ if eq $search_provider "wowchemy" }}
{{ $js_academic_search := resources.Get "js/wowchemy-search.js" | js.Build (dict "targetPath" (printf "%s/js/wow-search-built.js" .Lang) "params" $js_search_params) }}
{{ $js_bundle = $js_bundle | append $js_academic_search }}
{{ else if eq $search_provider "algolia" }}
{{ $js_algolia_search := resources.Get "js/algolia-search.js" | js.Build (dict "targetPath" (printf "%s/js/algolia-search-built.js" .Lang) "params" $js_search_params) }}
{{ $js_bundle = $js_bundle | append $js_algolia_search }}
{{ end }}
{{ range site.Params.plugins_js }}
{{ $js_bundle = $js_bundle | append (resources.Get (printf "js/%s.js" .)) }}