kopia lustrzana https://github.com/wagtail/wagtail
Switch documentation search to Algolia DocSearch (#6833)
Co-authored-by: Scott Cranfill <scott@scottcranfill.com> Co-authored-by: Thibaud Colas <thibaudcolas@gmail.com> Co-authored-by: Andy Chosak <andy@chosak.org>pull/6883/head
rodzic
fd563b6adf
commit
328e7012fc
|
@ -5,8 +5,14 @@ body.wy-body-for-nav {
|
|||
background-color: #e6e6e6; /*$color-grey-4*/
|
||||
}
|
||||
|
||||
div.wy-nav-side {
|
||||
nav.wy-nav-side {
|
||||
background-color: #333; /*color-grey-1*/
|
||||
position: absolute;
|
||||
overflow: inherit;
|
||||
}
|
||||
|
||||
div.wy-side-scroll {
|
||||
overflow: inherit;
|
||||
}
|
||||
|
||||
div.wy-side-nav-search {
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
.search .algolia-docsearch-suggestion--highlight,
|
||||
.algolia-autocomplete .algolia-docsearch-suggestion--highlight {
|
||||
color: #2980B9;
|
||||
background: #F1C40F;
|
||||
}
|
|
@ -1,6 +1,78 @@
|
|||
{% extends "!layout.html" %}
|
||||
|
||||
{% set docsearch_version = '2' %}
|
||||
{% set docsearch_base = 'https://cdn.jsdelivr.net/npm/docsearch.js@' ~ docsearch_version ~ '/dist/cdn/' %}
|
||||
|
||||
{% block extrahead %}
|
||||
<link rel="stylesheet" href="{{ docsearch_base ~ 'docsearch.min.css' }}"/>
|
||||
<link rel="stylesheet" href="{{ pathto('_static/css/docsearch.overrides.css', 1) }}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}
|
||||
{{ super() }}
|
||||
<script async defer data-domain="docs.wagtail.io" src="https://plausible.io/js/plausible.js"></script>
|
||||
<script src="{{ docsearch_base }}docsearch.min.js"></script>
|
||||
<script>
|
||||
/**
|
||||
* Get version of the currently served docs.
|
||||
*
|
||||
* PR builds have their version set to the PR ID (e.g. "6753").
|
||||
* If the docs are built for a PR, use the "latest" search index.
|
||||
* Otherwise, use the search index for the current version.
|
||||
*/
|
||||
function getReadTheDocsVersion() {
|
||||
const rtd_version = (window.READTHEDOCS_DATA || {}).version || 'latest'
|
||||
const version = rtd_version.match(/^\d+$/) ? 'latest' : rtd_version
|
||||
return version
|
||||
}
|
||||
|
||||
function getVersionFacetFilter() {
|
||||
return `version:${getReadTheDocsVersion()}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true (debug: on) for local builds or Read the Docs PR previews.
|
||||
*
|
||||
* The debug mode allows inspection of the dropodown.
|
||||
*/
|
||||
function getSearchDebugMode() {
|
||||
let debug = false
|
||||
if (window.READTHEDOCS_DATA === undefined) {
|
||||
// When developing locally, the `window.READTHEDOCS_DATA` object does not exist.
|
||||
debug = true
|
||||
} else {
|
||||
// When PR preview on Readthedocs, then the version can be converted into
|
||||
// a number. This does not work for the production version identifiers
|
||||
// like 'stable', 'latest', 'v2.12', etc. In that case `Number()` is `NaN`.
|
||||
const versionNumber = Number(window.READTHEDOCS_DATA.version)
|
||||
debug = !isNaN(versionNumber)
|
||||
}
|
||||
return debug
|
||||
}
|
||||
|
||||
function docSearchReady(script) {
|
||||
/**
|
||||
* Configure Algolia DocSearch.
|
||||
* See https://github.com/algolia/docsearch-configs/blob/master/configs/wagtail.json for index configuration.
|
||||
*/
|
||||
const search = docsearch({
|
||||
apiKey: '8325c57d16798633e29d211c26c7b6f9',
|
||||
indexName: 'wagtail',
|
||||
inputSelector: '#rtd-search-form [name="q"]',
|
||||
algoliaOptions: {
|
||||
facetFilters: [getVersionFacetFilter()],
|
||||
},
|
||||
autocompleteOptions: {
|
||||
// Do NOT automatically select the first suggestion in the dropdown.
|
||||
// https://github.com/algolia/autocomplete/blob/45fa32d008620cf52bf4a90530be338543dfba7f/README.md#global-options
|
||||
autoSelect: false
|
||||
},
|
||||
debug: getSearchDebugMode(),
|
||||
})
|
||||
|
||||
return search
|
||||
}
|
||||
|
||||
window.onload(docSearchReady())
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
{% extends "layout.html" %}
|
||||
{% set title = _('Search') %}
|
||||
|
||||
{% block body %}
|
||||
<noscript>
|
||||
<div id="fallback" class="admonition warning">
|
||||
<p class="last">
|
||||
{% trans trimmed %}Please activate JavaScript to enable the search
|
||||
functionality.{% endtrans %}
|
||||
</p>
|
||||
</div>
|
||||
</noscript>
|
||||
|
||||
<div id="search-results">
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}
|
||||
{{ super() }}
|
||||
<script>
|
||||
|
||||
function runSearchPageSearch(event) {
|
||||
const urlParams = new URLSearchParams(window.location.search)
|
||||
const query = urlParams.get('q')
|
||||
|
||||
const searchResultsContainer = document.getElementById('search-results')
|
||||
addHeadingForQuery(query, searchResultsContainer)
|
||||
|
||||
const docSearch = docSearchReady()
|
||||
const index = docSearch.client.initIndex('wagtail')
|
||||
index.search(
|
||||
query,
|
||||
{
|
||||
hitsPerPage: 50,
|
||||
facetFilters: [getVersionFacetFilter()]
|
||||
}
|
||||
)
|
||||
.then(({ hits }) => addResultsList(hits, query, searchResultsContainer))
|
||||
.catch((error) => console.log(error))
|
||||
}
|
||||
|
||||
function addHeadingForQuery(query, parentElement) {
|
||||
const searchHeading = document.createElement('h1')
|
||||
searchHeading.textContent = `Search results for “${query}”`
|
||||
parentElement.appendChild(searchHeading)
|
||||
}
|
||||
|
||||
function addResultsList(hits, query, parentElement) {
|
||||
const searchResultsList = document.createElement('ul')
|
||||
searchResultsList.className = "search"
|
||||
for (hit of hits) {
|
||||
const hitElement = createHitElement(hit, query)
|
||||
searchResultsList.appendChild(hitElement)
|
||||
}
|
||||
parentElement.appendChild(searchResultsList)
|
||||
}
|
||||
|
||||
function createHitElement(hitData, query) {
|
||||
const pageURL = new URL(hitData.url)
|
||||
pageURL.hash = '';
|
||||
pageURL.searchParams.set('highlight', query);
|
||||
const anchorURL = new URL(hitData.url);
|
||||
anchorURL.searchParams.set('highlight', query);
|
||||
const result = hitData._highlightResult
|
||||
|
||||
const hitListElement = document.createElement('li')
|
||||
|
||||
const hierarchies = Object.values(result.hierarchy);
|
||||
const firstHierarchyLevel = hierarchies[0];
|
||||
const lastHierarchyLevel = hierarchies[hierarchies.length - 1];
|
||||
|
||||
const pageLink = document.createElement('a')
|
||||
hitListElement.appendChild(pageLink)
|
||||
pageLink.innerHTML = firstHierarchyLevel.value
|
||||
pageLink.href = pageURL
|
||||
|
||||
const contextElement = document.createElement('div')
|
||||
hitListElement.appendChild(contextElement)
|
||||
contextElement.className = 'context'
|
||||
|
||||
if (lastHierarchyLevel && lastHierarchyLevel !== firstHierarchyLevel ) {
|
||||
const contextLinkContainer = document.createElement('div')
|
||||
contextElement.appendChild(contextLinkContainer)
|
||||
const contextLink = document.createElement('a')
|
||||
contextLinkContainer.appendChild(contextLink)
|
||||
contextLink.innerHTML = lastHierarchyLevel.value
|
||||
contextLink.href = anchorURL
|
||||
}
|
||||
|
||||
if (result.content) {
|
||||
const contentElement = document.createElement('div')
|
||||
contentElement.innerHTML = result.content.value
|
||||
contextElement.appendChild(contentElement)
|
||||
}
|
||||
|
||||
return hitListElement
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', runSearchPageSearch)
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -0,0 +1,4 @@
|
|||
<form id="rtd-search-form" class="wy-form" action="{{ pathto('search') }}" method="get" role="search">
|
||||
<input type="text" name="q" placeholder="{{ _('Search docs') }}" />
|
||||
<input type="submit" style="visibility:hidden;position:absolute">
|
||||
</form>
|
|
@ -187,7 +187,10 @@ html_extra_path = ['robots.txt']
|
|||
# html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
# html_use_index = True
|
||||
# Since we are implementing search with Algolia DocSearch, we do not need Sphinx to
|
||||
# generate its own index. It might not hurt to keep the Sphinx index, but it
|
||||
# could potentially speed up the build process.
|
||||
html_use_index = False
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
# html_split_index = False
|
||||
|
|
Ładowanie…
Reference in New Issue