From 08f52c05fda0d7bf7cc26223e6178d862d013cae Mon Sep 17 00:00:00 2001 From: StephenHoover Date: Sat, 2 Mar 2024 20:56:47 -0500 Subject: [PATCH] Added search based off of the Zola docs page and based off of HugoPaperModX --- config.toml | 19 ++++++- content/search.md | 6 +++ static/js/search.js | 96 ++++++++++++++++++++++++++++++++++ templates/partials/footer.html | 5 ++ templates/partials/search.html | 33 ++++++++++++ templates/search.html | 23 ++++++++ 6 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 content/search.md create mode 100644 static/js/search.js create mode 100644 templates/partials/search.html create mode 100644 templates/search.html diff --git a/config.toml b/config.toml index abf7195..8cbd501 100644 --- a/config.toml +++ b/config.toml @@ -11,6 +11,22 @@ taxonomies = [ { name = "tags", feed = true } ] +[search] +# Whether to include the title of the page/section in the index +include_title = true +# Whether to include the description of the page/section in the index +include_description = false +# Whether to include the path of the page/section in the index +include_path = false +# Whether to include the rendered content of the page/section in the index +include_content = true +# At which character to truncate the content to. Useful if you have a lot of pages and the index would +# become too big to load on the site. Defaults to not being set. +# truncate_content_length = 100 +# Wether to produce the search index as a javascript file or as a JSON file +# Accepted value "elasticlunr_javascript" or "elasticlunr_json" +index_format = "elasticlunr_json" + [markdown] # Whether to do syntax highlighting # Theme can be customised by setting the `highlight_theme` variable to a theme supported by Zola @@ -39,7 +55,8 @@ date_format = "%Y-%m-%d" navigation = [ { url = "$BASE_URL/archive", title = "Archive" }, { url = "$BASE_URL/tags", title = "Tags" }, - { url = "https://getzola.com/", title = "Zola", is_external = true } + { url = "$BASE_URL/search", title = "Search" }, + { url = "https://getzola.org/", title = "Zola", is_external = true } ] home_title = "PaperMod" diff --git a/content/search.md b/content/search.md new file mode 100644 index 0000000..897f956 --- /dev/null +++ b/content/search.md @@ -0,0 +1,6 @@ ++++ +title = "Search" +date = "2024-02-27" +template = "search.html" +extra = { is_search_page = true } ++++ diff --git a/static/js/search.js b/static/js/search.js new file mode 100644 index 0000000..65b8ac1 --- /dev/null +++ b/static/js/search.js @@ -0,0 +1,96 @@ + +// Zola Paper Mod javascript search code by Stephen Hoover +// Used: +// - https://github.com/getzola/zola/blob/master/docs/static/search.js +// - https://github.com/reorx/hugo-PaperModX/blob/master/assets/js/fastsearch.js + +// Debounce function definition +function debounce(func, wait, immediate) { + var timeout; + return function() { + var context = this, args = arguments; + var later = function() { + timeout = null; + if (!immediate) func.apply(context, args); + }; + var callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) func.apply(context, args); + }; +} + +function formatSearchResultItem(item, terms) { + // Adjust this to match your desired result item structure + return `
  • +
    ${item.doc.title} »
    ` + + ` +
  • `; +} + +function initSearch() { + var $searchInput = document.getElementById("searchInput"); // Make sure ID matches HTML + var $searchResults = document.getElementById("searchResults"); // Ensure this matches your HTML + var MAX_ITEMS = 10; + + var options = { + bool: "AND", + fields: { + title: {boost: 2}, + body: {boost: 1}, + } + }; + var currentTerm = ""; + var index; + + var initIndex = async function () { + if (index === undefined) { + index = fetch("/search_index.en.json") // Make sure the path to your search index is correct + .then( + async function(response) { + return await elasticlunr.Index.load(await response.json()); + } + ); + } + let res = await index; + return res; + } + + $searchInput.addEventListener("keyup", debounce(async function() { + var term = $searchInput.value.trim(); + if (term === currentTerm) { + return; + } + $searchResults.style.display = term === "" ? "none" : "block"; + $searchResults.innerHTML = ""; // Clear previous results + currentTerm = term; + if (term === "") { + return; + } + + var results = (await initIndex()).search(term, options); + if (results.length === 0) { + $searchResults.style.display = "none"; + return; + } + + // Directly inserting formatted search result items without additional
  • creation + for (var i = 0; i < Math.min(results.length, MAX_ITEMS); i++) { + $searchResults.innerHTML += formatSearchResultItem(results[i], term.split(" ")); + } +}, 150)); + window.addEventListener('click', function(e) { + if ($searchResults.style.display == "block" && !$searchResults.contains(e.target)) { + $searchResults.style.display = "none"; + } + }); +} + + +if (document.readyState === "complete" || + (document.readyState !== "loading" && !document.documentElement.doScroll) +) { + initSearch(); +} else { + document.addEventListener("DOMContentLoaded", initSearch); +} \ No newline at end of file diff --git a/templates/partials/footer.html b/templates/partials/footer.html index 9123cf1..a4ea156 100644 --- a/templates/partials/footer.html +++ b/templates/partials/footer.html @@ -133,3 +133,8 @@ }); {% endif %} + +{% if page.extra.is_search_page %} + + +{% endif %} \ No newline at end of file diff --git a/templates/partials/search.html b/templates/partials/search.html new file mode 100644 index 0000000..0ee60a2 --- /dev/null +++ b/templates/partials/search.html @@ -0,0 +1,33 @@ + \ No newline at end of file diff --git a/templates/search.html b/templates/search.html new file mode 100644 index 0000000..5094d81 --- /dev/null +++ b/templates/search.html @@ -0,0 +1,23 @@ +{% import "macros/social_icon.svg.html" as macro_social -%} + + + + {% block head %} + {% include "partials/head.html" %} + {% endblock %} + + + {% block header %} + {% include "partials/header.html" %} + {% endblock %} +
    + {% block main %} + {% include "partials/search.html" %} + {% endblock %} +
    + {% block footer %} + {% include "partials/footer.html" %} + {% endblock %} + + +