mirror of
https://github.com/gcushen/hugo-academic.git
synced 2025-07-26 03:00:50 +02:00
feat: upgrade Algolia integration from v2 to v4
This commit is contained in:
parent
1e48b12bf8
commit
ee434ab7ef
11 changed files with 156 additions and 92 deletions
|
@ -1,5 +1,6 @@
|
|||
_vendor/
|
||||
vendor/
|
||||
wowchemy/assets/css/libs/
|
||||
|
||||
public/
|
||||
resources/
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
[](https://discord.com/channels/722225264733716590/742892432458252370/742895548159492138)
|
||||
[](https://github.com/sponsors/gcushen)
|
||||
[](https://twitter.com/wowchemy)
|
||||
[](https://github.com/gcushen)
|
||||
[](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.
|
||||
|
||||
[](https://github.com/igrigorik/ga-beacon)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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. */}}
|
||||
|
|
|
@ -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" .)) }}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue