Skip to content

Commit

Permalink
feat: integrate pagefind search functionality
Browse files Browse the repository at this point in the history
- Add support for `pagefind` search type
- Update search configuration to include `pagefind` as an option
- Modify search logic to handle `pagefind` initialization and usage
- Update search result processing to integrate with `pagefind`
- Add logging for search results
- Refactor search type handling in templates
- Update documentation and configuration examples to reflect new search options
  • Loading branch information
Sped0n committed Jul 13, 2024
1 parent bac1d3d commit e54a82b
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 17 deletions.
81 changes: 70 additions & 11 deletions assets/js/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ function initSearch() {
const searchClear = document.getElementById(`search-clear-${suffix}`);
const autocompleteJs = window.config["autocomplete.min.js"];
const algoliaJs = window.config["algoliasearch.min.js"];
const pagefindJs = window.config["pagefind.js"];
const fuseJs = window.config["fuse.min.js"];
if (isMobile) {
window._searchMobileOnce = true;
Expand All @@ -195,8 +196,14 @@ function initSearch() {
});
if (window.config?.search?.type === "algolia") {
loadScript("algolia-script", algoliaJs, null);
} else {
} else if (window.config?.search?.type === "fuse") {
loadScript("fuse-script", fuseJs, null);
} else {
import(pagefindJs).then((p) => {
if (p === undefined) return;
pagefind = p;
pagefind.init();
});
}
document.body.classList.add("blur");
header.classList.add("open");
Expand Down Expand Up @@ -243,8 +250,13 @@ function initSearch() {
});
if (window.config?.search?.type === "algolia") {
loadScript("algolia-script", algoliaJs, null);
} else {
} else if (window.config?.search?.type === "fuse") {
loadScript("fuse-script", fuseJs, null);
} else {
import(pagefindJs).then((p) => {
window._pgfIndex = p;
window._pgfIndex.init();
});
}
document.body.classList.add("blur");
header.classList.add("open");
Expand Down Expand Up @@ -346,7 +358,7 @@ function initSearch() {
} else if (searchConfig.type === "fuse") {
const search = () => {
const results = {};
window._index
window._fuseIndex
.search(query)
.forEach(({ item, refIndex, matches }) => {
let title = item.title;
Expand Down Expand Up @@ -397,9 +409,10 @@ function initSearch() {
context: content,
};
});
console.log(results);
return Object.values(results).slice(0, maxResultLength);
};
if (!window._index) {
if (!window._fuseIndex) {
fetch(searchConfig.fuseIndexURL)
.then((response) => response.json())
.then((data) => {
Expand All @@ -418,14 +431,52 @@ function initSearch() {
includeMatches: true,
keys: ["content", "title"],
};
window._index = new Fuse(data, options);
window._fuseIndex = new Fuse(data, options);
finish(search());
})
.catch((err) => {
console.error(err);
finish([]);
});
} else finish(search());
} else {
if (window._pgfIndex === undefined) {
import(pagefindJs).then((p) => {
window._pgfIndex = p;
window._pgfIndex.init();
});
}
window._pgfIndex.debouncedSearch(query, 300).then((resp) => {
if (resp === null || !("results" in resp)) {
finish([]);
return;
}
Promise.all(
resp.results.slice(0, maxResultLength).map((r) => r.data()),
).then((res) => {
const results = {};
for (const r of res) {
for (const _r of r.sub_results) {
if (
_r.url === undefined ||
!("anchor" in _r) ||
_r.anchor.element != "h2"
)
continue;
results[_r.url] = {
uri: _r.url,
title: r.meta.title,
date: r.meta.date,
context: _r.excerpt.replace(
/<mark>(.*?)<\/mark>/gi,
"<em>$1</em>",
),
};
}
}
finish(Object.values(results));
});
});
}
},
templates: {
Expand All @@ -441,11 +492,17 @@ function initSearch() {
icon: '<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M229.3 182.6c-49.3 0-89.2 39.9-89.2 89.2 0 49.3 39.9 89.2 89.2 89.2s89.2-39.9 89.2-89.2c0-49.3-40-89.2-89.2-89.2zm62.7 56.6l-58.9 30.6c-1.8.9-3.8-.4-3.8-2.3V201c0-1.5 1.3-2.7 2.7-2.6 26.2 1 48.9 15.7 61.1 37.1.7 1.3.2 3-1.1 3.7zM389.1 32H58.9C26.4 32 0 58.4 0 90.9V421c0 32.6 26.4 59 58.9 59H389c32.6 0 58.9-26.4 58.9-58.9V90.9C448 58.4 421.6 32 389.1 32zm-202.6 84.7c0-10.8 8.7-19.5 19.5-19.5h45.3c10.8 0 19.5 8.7 19.5 19.5v15.4c0 1.8-1.7 3-3.3 2.5-12.3-3.4-25.1-5.1-38.1-5.1-13.5 0-26.7 1.8-39.4 5.5-1.7.5-3.4-.8-3.4-2.5v-15.8zm-84.4 37l9.2-9.2c7.6-7.6 19.9-7.6 27.5 0l7.7 7.7c1.1 1.1 1 3-.3 4-6.2 4.5-12.1 9.4-17.6 14.9-5.4 5.4-10.4 11.3-14.8 17.4-1 1.3-2.9 1.5-4 .3l-7.7-7.7c-7.6-7.5-7.6-19.8 0-27.4zm127.2 244.8c-70 0-126.6-56.7-126.6-126.6s56.7-126.6 126.6-126.6c70 0 126.6 56.6 126.6 126.6 0 69.8-56.7 126.6-126.6 126.6z"/></svg>',
href: "https://www.algolia.com/",
}
: {
searchType: "Fuse.js",
icon: "",
href: "https://fusejs.io/",
};
: searchConfig.type === "fuse"
? {
searchType: "Fuse.js",
icon: "",
href: "https://fusejs.io/",
}
: {
searchType: "pagefind",
icon: "",
href: "https://pagefind.app",
};
return `<div class="search-footer">Search by <a href="${href}" rel="noopener noreffer" target="_blank">${icon} ${searchType}</a></div>`;
},
},
Expand Down Expand Up @@ -540,7 +597,9 @@ function initToc() {
const toc = document.getElementById("toc-auto");
const tocLinkElements = tocCore.querySelectorAll("a:first-child");
const tocLiElements = tocCore.getElementsByTagName("li");
const headerLinkElements = document.getElementsByClassName("headerLink") as HTMLCollectionOf<HTMLHeadingElement>;
const headerLinkElements = document.getElementsByClassName(
"headerLink",
) as HTMLCollectionOf<HTMLHeadingElement>;
const headerIsFixed =
document.body.getAttribute("header-desktop") !== "normal";
const headerHeight = document.getElementById("header-desktop").offsetHeight;
Expand Down
6 changes: 3 additions & 3 deletions exampleSite/config/_default/params.en.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ keywords = ["Theme", "Hugo"]
# 搜索配置
[search]
enable = true
# type of search engine ("algolia", "fuse")
# 搜索引擎的类型 ("algolia", "fuse")
type = "algolia"
# type of search engine ("algolia", "fuse", "pagefind")
# 搜索引擎的类型 ("algolia", "fuse", "pagefind")
type = "pagefind"
# max index length of the chunked content
# 文章内容最长索引长度
contentLength = 4000
Expand Down
9 changes: 8 additions & 1 deletion layouts/partials/assets.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,21 @@
{{- $js := resources.Get $source -}}
{{- $config = dict "algoliasearch.min.js" $js.RelPermalink | merge $config}}
{{- $config = dict "type" "algolia" "algoliaIndex" $search.algolia.index "algoliaAppID" $search.algolia.appID "algoliaSearchKey" $search.algolia.searchKey | dict "search" | merge $config -}}
{{- else -}}
{{- else if eq $search.type "fuse" -}}
{{- with .Site.Home.OutputFormats.Get "json" -}}
{{- $config = dict "type" "fuse" "fuseIndexURL" .RelPermalink | dict "search" | merge $config -}}
{{- end -}}
{{- $source := $cdn.fuseJS | default "lib/fuse/fuse.min.js" -}}
{{- $js := resources.Get $source -}}
{{- $config = dict "fuse.min.js" $js.RelPermalink | merge $config}}
{{- $config = dict "isCaseSensitive" $search.fuse.isCaseSensitive "minMatchCharLength" $search.fuse.minMatchCharLength "findAllMatches" $search.fuse.findAllMatches "location" $search.fuse.location "threshold" $search.fuse.threshold "distance" $search.fuse.distance "ignoreLocation" $search.fuse.ignoreLocation "useExtendedSearch" $search.fuse.useExtendedSearch "ignoreFieldNorm" $search.fuse.ignoreFieldNorm | dict "search" | merge $config -}}
{{- else -}}
{{- with .Site.Home.OutputFormats.Get "json" -}}
{{- $config = dict "type" "pagefind" "fuseIndexURL" .RelPermalink | dict "search" | merge $config -}}
{{- end -}}
{{- $source := "/pagefind/pagefind.js" -}}
{{- $config = dict "pagefind.js" "/pagefind/pagefind.js" | merge $config}}
{{- $config = dict "isCaseSensitive" $search.fuse.isCaseSensitive "minMatchCharLength" $search.fuse.minMatchCharLength "findAllMatches" $search.fuse.findAllMatches "location" $search.fuse.location "threshold" $search.fuse.threshold "distance" $search.fuse.distance "ignoreLocation" $search.fuse.ignoreLocation "useExtendedSearch" $search.fuse.useExtendedSearch "ignoreFieldNorm" $search.fuse.ignoreFieldNorm | dict "search" | merge $config -}}
{{- end -}}
{{- end -}}

Expand Down
4 changes: 2 additions & 2 deletions layouts/posts/single.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ <h2 class="toc-title">{{ T "contents" }}</h2>

<article class="page single print:!tw-w-full print:!tw-max-w-none print:!tw-m-0 print:!tw-p-0">
{{- /* Title */ -}}
<h1 class="single-title">{{ .Title }}</h1>
<h1 class="single-title" data-pagefind-meta="date:{{- .Site.Params.dateformat | default "2006-01-02" | .PublishDate.Format -}}" data-pagefind-body>{{ .Title }}</h1>

{{- /* Subtitle */ -}}
{{- with $params.subtitle -}}
Expand Down Expand Up @@ -203,7 +203,7 @@ <h2 class="single-subtitle">{{ . }}</h2>
{{- end -}}

{{- /* Content */ -}}
<div class="content" id="content">
<div class="content" id="content" data-pagefind-body>
{{- /* Outdated Article Reminder */ -}}
{{- partial "single/outdatedArticleReminder.html" . -}}
{{- dict "Content" .Content "Ruby" $params.ruby "Fraction" $params.fraction "Fontawesome" $params.fontawesome | partial "function/content.html" | safeHTML -}}
Expand Down

0 comments on commit e54a82b

Please sign in to comment.