search: pagefind v1.1.0

Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
This commit is contained in:
David Karlsson 2024-05-23 09:35:24 +02:00
parent 0845436dbc
commit 97307d4c66
18 changed files with 91 additions and 85 deletions

1
.gitignore vendored
View File

@ -6,3 +6,4 @@ node_modules
resources
public
tmp
static/pagefind

View File

@ -83,5 +83,15 @@ WORKDIR /test
RUN --mount=type=bind,target=. \
./scripts/test_unused_media.sh
FROM base as pagefind
ARG PAGEFIND_VERSION=1.1.0
COPY --from=build /out ./public
RUN --mount=type=bind,src=pagefind.yml,target=pagefind.yml \
npx pagefind@v${PAGEFIND_VERSION} --output-path "/pagefind"
FROM scratch AS index
COPY --from=pagefind /pagefind .
FROM scratch AS release
COPY --from=build /out /
COPY --from=pagefind /pagefind .

View File

@ -14,6 +14,10 @@
scrollbar-color: theme(colors.gray.dark.800) theme(colors.white / 0.10);
}
}
mark {
@apply bg-amber-light-200 dark:bg-amber-dark-600/25 dark:text-white;
}
}
/* utility classes */

View File

@ -1,65 +0,0 @@
import Fuse from "fuse.js";
let indexed = false;
let handler = null;
const modalSearchInput = document.querySelector("#modal-search-input");
const modalSearchResults = document.querySelector("#modal-search-results");
async function initializeIndex() {
const index = await fetch("/metadata.json").then((response) =>
response.json(),
);
const options = {
keys: [
{ name: "title", weight: 2 },
{ name: "description", weight: 1 },
{
name: "keywords",
weight: 1,
getFn: (page) => {
return Array.isArray(page.keywords)
? page.keywords.join(" ")
: page.keywords;
},
},
{ name: "tags", weight: 1 },
],
minMatchCharLength: 1,
threshold: 0.2,
ignoreLocation: true,
useExtendedSearch: true,
ignoreFieldNorm: true,
};
handler = new Fuse(index, options);
indexed = true;
}
async function executeSearch(query) {
!indexed && (await initializeIndex());
const results = handler.search(query);
return results;
}
async function modalSearch(e) {
const query = e.target.value;
results = await executeSearch(query);
let resultsHTML = `<div>${results.length} results</div>`;
resultsHTML += results
.map(({ item }) => {
return `<div class="bg-gray-light-100 dark:bg-gray-dark-200 rounded p-4">
<div class="flex flex-col">
<a class="link" href="${item.url}">${item.title}</a>
<p>${item.description}</p>
</div>
</div>`;
})
.join("");
modalSearchResults.innerHTML = resultsHTML;
}
modalSearchInput.addEventListener("input", modalSearch);

View File

@ -17,6 +17,12 @@ group "default" {
targets = ["release"]
}
target "index" {
# generate a new local search index
target = "index"
output = ["type=local,dest=static/pagefind"]
}
target "release" {
args = {
HUGO_ENV = HUGO_ENV

View File

@ -39,6 +39,7 @@
"Docker-Engine",
"Docker-Hub",
"Download",
"Entra-ID",
"Entra-ID-SAML-2.0",
"Fedora",
"For-Mac-and-Linux",
@ -54,6 +55,7 @@
"HCL",
"HTTP",
"Heredocs",
"Hub",
"Hyper-V-backend-and-Windows-containers",
"Inline",
"Install-from-the-command-line",
@ -90,6 +92,7 @@
"Shell",
"Specific-version",
"Svelte",
"Travis-CI",
"Ubuntu",
"Unix-pipe",
"Use-Docker-Init",

View File

@ -1,4 +1,4 @@
<div class="scroll-mt-20" x-data x-ref="root">
<div data-pagefind-ignore class="scroll-mt-20" x-data x-ref="root">
{{ with .Attributes.title }}
<div class="text-sm -mb-3 text-gray-light dark:text-gray-dark">{{ . }}</div>
{{ end }}

View File

@ -30,7 +30,7 @@
{{ end }}
</div>
</div>
<div class="min-w-0 px-4 pb-32">
<div data-pagefind-body class="min-w-0 px-4 pb-32">
{{ block "main" . }}
{{ end }}
</div>

View File

@ -6,7 +6,7 @@
{{ partial "breadcrumbs.html" . }}
<article class="prose max-w-none dark:prose-invert">
{{ with .Title }}
<h1 class="scroll-mt-36">{{ . }}</h1>
<h1 data-pagefind-weight="10" class="scroll-mt-36">{{ . }}</h1>
{{ end }}
<div class="block lg:hidden">
{{ partial "pagemeta.html" . }}

View File

@ -6,7 +6,7 @@
{{ partial "breadcrumbs.html" . }}
<article class="prose max-w-none dark:prose-invert">
{{ with .Title }}
<h1 class="scroll-mt-36">{{ . }}</h1>
<h1 data-pagefind-weight="10" class="scroll-mt-36">{{ . }}</h1>
{{ end }}
<div class="block lg:hidden">
{{ partial "pagemeta.html" . }}

View File

@ -2,7 +2,7 @@
{{ $ctx := . }}
<nav id="breadcrumbs" class="py-4 gap-4 flex items-center text-gray-light dark:text-gray-dark max-w-full min-w-0">
<nav id="breadcrumbs" data-pagefind-ignore class="py-4 gap-4 flex items-center text-gray-light dark:text-gray-dark max-w-full min-w-0">
{{ with ($scratch.GetSortedMapValues "sections") }}
{{ range $i, $e := . }}
{{- if $i -}}

View File

@ -72,3 +72,8 @@
}}
<script defer src="{{ $js.Permalink }}"></script>
{{ partialCached "utils/resources.html" "-" }}
{{- /* Highlight text from search results */ -}}
<script type="module">
await import('/pagefind/pagefind-highlight.js');
new PagefindHighlight({ highlightParam: "highlight" });
</script>

View File

@ -4,7 +4,7 @@
{{- end }}
{{- $tags := .GetTerms "tags" }}
{{- if or $toc $tags }}
<div class="not-prose">
<div data-pagefind-ignore class="not-prose">
{{- with $tags }}
<div class="flex flex-col gap-2 my-2">
<span class="text-lg">Tags</span>

View File

@ -21,7 +21,8 @@ case 'k':
<!-- search modal -->
<div class="fixed left-0 top-0 z-20 flex w-lvw justify-center py-12 text-gray-light-800 dark:text-gray-dark-800"
role="dialog" tabindex="-1" x-show="open" x-trap="open" x-cloak x-transition>
<div class="max-h-[80vh] overflow-hidden lg:w-[600px] xl:w-[800px] rounded-lg bg-white p-2 mx-8 dark:bg-background-dark w-full flex flex-col"
<div
class="mx-8 flex max-h-[80vh] w-full flex-col overflow-hidden rounded-lg bg-white p-2 dark:bg-background-dark lg:w-[600px] xl:w-[800px]"
@click.away="open = false; document.body.classList.remove('overflow-hidden');">
<div class="m-2 text-xl">Search Docker documentation</div>
<header class="flex items-center py-2">
@ -42,4 +43,52 @@ case 'k':
<!-- search modal backdrop -->
<div class="fixed left-0 top-0 h-full w-full bg-background-dark/70 dark:bg-gray-dark-100/70" x-show="open" x-cloak>
</div>
<script type="module">
window.addEventListener("load", async function () {
const pagefind = await import("/pagefind/pagefind.js");
await pagefind.options({
ranking: {
termFrequency: 0.2,
pageLength: 0.75,
termSaturation: 1.4,
termSimilarity: 6.0,
},
highlightParam: "highlight",
});
pagefind.init();
const modalSearchInput = document.querySelector("#modal-search-input");
const modalSearchResults = document.querySelector(
"#modal-search-results",
);
async function modalSearch(e) {
const query = e.target.value;
const search = await pagefind.debouncedSearch(query);
if (search === null) {
return;
} else {
const results = await Promise.all(
search.results.map((r) => r.data()),
);
let resultsHTML = `<div>${results.length} results</div>`;
resultsHTML += results
.map((item) => {
return `<div class="bg-gray-light-100 dark:bg-gray-dark-200 rounded p-4">
<div class="flex flex-col">
<a class="link" href="${item.url}">${item.meta.title}</a>
<p class="text-gray-light dark:text-gray-dark">…${item.excerpt}…</p>
</div>
</div>`;
})
.join("");
modalSearchResults.innerHTML = resultsHTML;
}
}
modalSearchInput.addEventListener("input", modalSearch);
});
</script>
</div>

View File

@ -9,5 +9,4 @@ HUGO_ENABLEGITINFO = "true"
HUGO_ENVIRONMENT = "preview"
[context.deploy-preview]
command = "hugo --gc --minify -b $DEPLOY_PRIME_URL"
command = "hugo --gc --minify -b $DEPLOY_PRIME_URL && npx pagefind@v1.1.0"

9
package-lock.json generated
View File

@ -18,7 +18,6 @@
"@tailwindcss/typography": "^0.5.10",
"alpinejs": "^3.13.5",
"autoprefixer": "^10.4.17",
"fuse.js": "^7.0.0",
"postcss": "^8.4.33",
"postcss-cli": "^11.0.0",
"postcss-import": "^16.0.0",
@ -722,14 +721,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/fuse.js": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.0.0.tgz",
"integrity": "sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==",
"engines": {
"node": ">=10"
}
},
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",

View File

@ -15,15 +15,14 @@
"homepage": "https://docs.docker.com/",
"dependencies": {
"@alpinejs/collapse": "^3.13.5",
"@alpinejs/persist": "^3.13.5",
"@alpinejs/focus": "^3.13.7",
"@alpinejs/persist": "^3.13.5",
"@floating-ui/dom": "^1.6.3",
"@material-symbols/svg-400": "^0.14.6",
"@tailwindcss/nesting": "^0.0.0-insiders.565cd3e",
"@tailwindcss/typography": "^0.5.10",
"alpinejs": "^3.13.5",
"autoprefixer": "^10.4.17",
"fuse.js": "^7.0.0",
"postcss": "^8.4.33",
"postcss-cli": "^11.0.0",
"postcss-import": "^16.0.0",

4
pagefind.yml Normal file
View File

@ -0,0 +1,4 @@
output_subdir: pagefind
site: public
exclude_selectors:
- "table"