kopia lustrzana https://github.com/wagtail/wagtail
Update sphinx-wagtail-theme and search implementation (#12521)
rodzic
2271d86fc7
commit
538c5089e9
|
@ -1,39 +0,0 @@
|
|||
.search .algolia-docsearch-suggestion--highlight,
|
||||
.algolia-autocomplete .algolia-docsearch-suggestion--highlight {
|
||||
color: #2980b9;
|
||||
background: #f1c40f;
|
||||
}
|
||||
|
||||
.algolia-autocomplete {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#search-results a,
|
||||
a.algolia-docsearch-suggestion {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
#search-results h2 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* override algolia search input colors (set on element via JS) for dark mode alignment and radius for left icon */
|
||||
|
||||
#search-form .algolia-autocomplete > .form-control {
|
||||
background: #fff none repeat scroll 0% 0% padding-box !important;
|
||||
border-bottom-left-radius: 0 !important;
|
||||
border-top-left-radius: 0 !important;
|
||||
}
|
||||
|
||||
body.theme-dark #search-form .algolia-autocomplete > .form-control {
|
||||
background: #1b1238 none repeat scroll 0% 0% padding-box !important;
|
||||
}
|
||||
|
||||
/* override algolia search default styles to prevent overflow on mobile devices */
|
||||
|
||||
@media (max-width: 991px) {
|
||||
#algolia-autocomplete-listbox-0 {
|
||||
width: auto;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
.pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.pagination-list {
|
||||
display: flex;
|
||||
gap: 2rem;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.pagination-button,
|
||||
.pagination-previous,
|
||||
.pagination-next {
|
||||
border: none;
|
||||
background: none;
|
||||
text-decoration: 2px solid underline;
|
||||
text-decoration-color: #3beccd;
|
||||
text-underline-offset: 3px;
|
||||
}
|
||||
|
||||
.pagination-button[aria-current='page'] {
|
||||
background-color: #40efc5;
|
||||
}
|
||||
|
||||
body.theme-dark .pagination-button:not([aria-current]),
|
||||
body.theme-dark .pagination-next,
|
||||
body.theme-dark .pagination-previous {
|
||||
color: #fff;
|
||||
}
|
|
@ -1,95 +1,9 @@
|
|||
{% extends "!layout.html" %}
|
||||
|
||||
{% set docsearch_version = '2' %}
|
||||
{% set docsearch_base = 'https://cdn.jsdelivr.net/npm/docsearch.js@' ~ docsearch_version ~ '/dist/cdn/' %}
|
||||
|
||||
{% block extrahead %}
|
||||
<meta name="docsearch:version" content="{% if READTHEDOCS and current_version %}{{ current_version }}{% else %}unknown{% endif %}" />
|
||||
|
||||
<link rel="stylesheet" href="{{ docsearch_base ~ 'docsearch.min.css' }}"/>
|
||||
<link rel="stylesheet" href="{{ pathto('_static/css/docsearch.overrides.css', 1) }}" />
|
||||
<link rel="stylesheet" href="{{ pathto('_static/css/pagination.css', 1) }}" />
|
||||
<link rel="stylesheet" href="{{ pathto('_static/css/custom.css', 1) }}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block search %}
|
||||
<script async defer data-domain="docs.wagtail.org" 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 (for example "6753").
|
||||
* If the docs are built for a PR or local development, use the "latest" facet filter.
|
||||
* Otherwise, use the facet filter for the current version.
|
||||
*/
|
||||
function getReadTheDocsVersion() {
|
||||
const meta = document.querySelector('meta[name="docsearch:version"]');
|
||||
const rtd_version = meta ? meta.content : 'latest';
|
||||
const version = rtd_version.match(/^(\d+|unknown)$/) ? '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 dropdown.
|
||||
*/
|
||||
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() {
|
||||
/**
|
||||
* Configure Algolia DocSearch.
|
||||
* See https://github.com/wagtail/wagtail/wiki/Documentation-search for index configuration.
|
||||
*/
|
||||
const search = docsearch({
|
||||
appId: 'XSYGEO7KMJ',
|
||||
apiKey: 'd50a485660ed9280079aada4e09454b2',
|
||||
indexName: 'wagtail',
|
||||
inputSelector: '#searchbox [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(),
|
||||
})
|
||||
|
||||
// Change page styles when the dropdown is open, to lock scrolling.
|
||||
search.autocomplete.on('autocomplete:updated', function (event) {
|
||||
const isOpen = event.target.value.trim() !== '';
|
||||
document.body.classList.toggle('body--autocomplete-open', isOpen);
|
||||
});
|
||||
search.autocomplete.on('autocomplete:closed', function (event) {
|
||||
document.body.classList.toggle('body--autocomplete-open', false);
|
||||
});
|
||||
return search
|
||||
}
|
||||
|
||||
docSearchReady();
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}
|
||||
{{ super() }}
|
||||
<template data-promotion-banner data-clear-duration="90" data-date-until="2024-06-22">
|
||||
|
|
|
@ -1,187 +0,0 @@
|
|||
{% 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>
|
||||
|
||||
<nav id="pagination" class="pagination" aria-label="pagination" hidden="true" >
|
||||
<button class="pagination-previous" id="pagination-previous">
|
||||
← Previous
|
||||
</button>
|
||||
<ul class="pagination-list"></ul>
|
||||
<button class="pagination-next" id="pagination-next">
|
||||
Next →
|
||||
</button>
|
||||
</nav>
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}
|
||||
{{ super() }}
|
||||
<script>
|
||||
|
||||
function runSearchPageSearch(page) {
|
||||
const urlParams = new URLSearchParams(window.location.search)
|
||||
const query = urlParams.get('q')
|
||||
|
||||
const searchResultsContainer = document.getElementById('search-results')
|
||||
|
||||
// Erase previous results
|
||||
searchResultsContainer.innerHTML = ""
|
||||
document.querySelector('.pagination-list').innerHTML = ""
|
||||
addHeadingForQuery(query, searchResultsContainer)
|
||||
|
||||
const docSearch = docSearchReady()
|
||||
const index = docSearch.client.initIndex('wagtail')
|
||||
index.search(
|
||||
query,
|
||||
{
|
||||
hitsPerPage: 100,
|
||||
page: page,
|
||||
facetFilters: [getVersionFacetFilter()]
|
||||
}
|
||||
)
|
||||
.then(result => {
|
||||
// Display pagination if more than 1 page returned
|
||||
let nbPages = result["nbPages"]
|
||||
if (nbPages > 1) {
|
||||
document.querySelector("#pagination").hidden = false;
|
||||
displayPagination(page, nbPages)
|
||||
}
|
||||
|
||||
// Display hits
|
||||
let hits = result["hits"]
|
||||
addResultsList(hits, query, searchResultsContainer)
|
||||
})
|
||||
.catch((error) => console.log(error))
|
||||
}
|
||||
|
||||
function displayPagination(page, totalPages) {
|
||||
const pagination = document.querySelector("#pagination")
|
||||
const paginationList = pagination.querySelector(".pagination-list")
|
||||
|
||||
// Hide previous/next button if showing first/last page
|
||||
pagination.querySelector(".pagination-previous").hidden = false;
|
||||
pagination.querySelector(".pagination-previous").hidden = page === 0;
|
||||
pagination.querySelector(".pagination-next").hidden = page === totalPages -1;
|
||||
|
||||
// Display at most "toBeDisplayed" page links in the paginator
|
||||
const toBeDisplayed = 7
|
||||
let [start, end] = setStartEndForPaginator(page, totalPages, toBeDisplayed)
|
||||
|
||||
for (let i = start; i < end; i++) {
|
||||
let newPaginationItem = document.createElement("li")
|
||||
let newPaginationbutton = document.createElement("button")
|
||||
newPaginationbutton.classList.add("pagination-button")
|
||||
newPaginationbutton.innerHTML = i + 1
|
||||
if (i == page) {
|
||||
newPaginationbutton.setAttribute("aria-label", `page ${i+1}`)
|
||||
newPaginationbutton.setAttribute("aria-current", "page")
|
||||
} else {
|
||||
newPaginationbutton.setAttribute("aria-label", `Go to page ${i+1}`)
|
||||
}
|
||||
|
||||
// Register event handlers
|
||||
newPaginationbutton.onclick = function() {
|
||||
runSearchPageSearch(i)
|
||||
};
|
||||
pagination.querySelector(".pagination-previous").onclick = function() {
|
||||
runSearchPageSearch(page - 1)
|
||||
};
|
||||
pagination.querySelector(".pagination-next").onclick = function() {
|
||||
runSearchPageSearch(page + 1)
|
||||
};
|
||||
|
||||
newPaginationItem.append(newPaginationbutton)
|
||||
paginationList.append(newPaginationItem)
|
||||
}
|
||||
}
|
||||
|
||||
function setStartEndForPaginator(currentPage, totalPages, nbPagesLinkToDisplay) {
|
||||
let start = 0
|
||||
let end = totalPages
|
||||
|
||||
if (totalPages > nbPagesLinkToDisplay) {
|
||||
start = currentPage
|
||||
|
||||
if (totalPages - currentPage < nbPagesLinkToDisplay) {
|
||||
start = totalPages - nbPagesLinkToDisplay
|
||||
}
|
||||
|
||||
if (totalPages - start > nbPagesLinkToDisplay) {
|
||||
end = currentPage + nbPagesLinkToDisplay
|
||||
}
|
||||
}
|
||||
|
||||
return [start, end]
|
||||
}
|
||||
|
||||
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(0));
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -1,13 +0,0 @@
|
|||
{%- if builder != "singlehtml" %}
|
||||
<div id="searchbox" class="" role="search">
|
||||
<form id="search-form" action="{{ pathto('search') }}" autocomplete="off" method="get">
|
||||
<div class="input-group flex-nowrap">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text border-right-0 bg-white py-3 pl-3 pr-2"><span class="fas fa-search"></span></div>
|
||||
</div>
|
||||
<input class="form-control py-3 pr-3 pl-3 h-100 border-left-0" type="search" name="q" placeholder="Search" aria-label="Search" id="searchinput" />
|
||||
</div>
|
||||
<input type="submit" style="visibility:hidden;position:absolute;display:block;">
|
||||
</form>
|
||||
</div>
|
||||
{%- endif %}
|
3
setup.py
3
setup.py
|
@ -73,9 +73,8 @@ documentation_extras = [
|
|||
"sphinxcontrib-spelling>=7,<8",
|
||||
"Sphinx>=7.0",
|
||||
"sphinx-autobuild>=0.6.0",
|
||||
"sphinx-wagtail-theme==6.3.0",
|
||||
"sphinx-wagtail-theme==6.4.0",
|
||||
"myst_parser==2.0.0",
|
||||
"sphinx_copybutton>=0.5,<1.0",
|
||||
]
|
||||
|
||||
setup(
|
||||
|
|
Ładowanie…
Reference in New Issue