Skip to content

Commit

Permalink
Search json index (#1998)
Browse files Browse the repository at this point in the history
* search: Add support for a JSON index

* docs: Document JSON index for search

* docs: Use lazy-loaded JSON index

* Add elasticlunr prefix to search engine format configuration

This will be useful if support for more search libraries are added in the future
  • Loading branch information
sgued authored and Keats committed Feb 16, 2023
1 parent 291c93e commit 7000f78
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 26 deletions.
16 changes: 16 additions & 0 deletions components/config/src/config/search.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum IndexFormat {
ElasticlunrJson,
ElasticlunrJavascript,
}

impl Default for IndexFormat {
fn default() -> IndexFormat {
IndexFormat::ElasticlunrJavascript
}
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(default)]
pub struct Search {
Expand All @@ -15,6 +28,8 @@ pub struct Search {
pub include_description: bool,
/// Include the path of the page in the search index. `false` by default.
pub include_path: bool,
/// Foramt of the search index to be produced. Javascript by default
pub index_format: IndexFormat,
}

impl Default for Search {
Expand All @@ -25,6 +40,7 @@ impl Default for Search {
include_description: false,
include_path: false,
truncate_content_length: None,
index_format: Default::default(),
}
}
}
9 changes: 7 additions & 2 deletions components/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ mod theme;
use std::path::Path;

pub use crate::config::{
languages::LanguageOptions, link_checker::LinkChecker, link_checker::LinkCheckerLevel,
search::Search, slugify::Slugify, taxonomies::TaxonomyConfig, Config,
languages::LanguageOptions,
link_checker::LinkChecker,
link_checker::LinkCheckerLevel,
search::{IndexFormat, Search},
slugify::Slugify,
taxonomies::TaxonomyConfig,
Config,
};
use errors::Result;

Expand Down
42 changes: 23 additions & 19 deletions components/site/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use libs::rayon::prelude::*;
use libs::tera::{Context, Tera};
use libs::walkdir::{DirEntry, WalkDir};

use config::{get_config, Config};
use config::{get_config, Config, IndexFormat};
use content::{Library, Page, Paginator, Section, Taxonomy};
use errors::{anyhow, bail, Context as ErrorContext, Result};
use libs::relative_path::RelativePathBuf;
Expand Down Expand Up @@ -764,32 +764,36 @@ impl Site {
Ok(())
}

fn index_for_lang(&self, lang: &str) -> Result<()> {
let index_json = search::build_index(
&self.config.default_language,
&self.library.read().unwrap(),
&self.config,
)?;
let (path, content) = match &self.config.search.index_format {
IndexFormat::ElasticlunrJson => {
let path = self.output_path.join(&format!("search_index.{}.json", lang));
(path, index_json)
}
IndexFormat::ElasticlunrJavascript => {
let path = self.output_path.join(&format!("search_index.{}.js", lang));
let content = format!("window.searchIndex = {};", index_json);
(path, content)
}
};
create_file(&path, &content)
}

pub fn build_search_index(&self) -> Result<()> {
ensure_directory_exists(&self.output_path)?;
// TODO: add those to the SITE_CONTENT map

// index first
create_file(
&self.output_path.join(&format!("search_index.{}.js", self.config.default_language)),
&format!(
"window.searchIndex = {};",
search::build_index(
&self.config.default_language,
&self.library.read().unwrap(),
&self.config
)?
),
)?;
self.index_for_lang(&self.config.default_language)?;

for (code, language) in &self.config.other_languages() {
if code != &self.config.default_language && language.build_search_index {
create_file(
&self.output_path.join(&format!("search_index.{}.js", &code)),
&format!(
"window.searchIndex = {};",
search::build_index(code, &self.library.read().unwrap(), &self.config)?
),
)?;
self.index_for_lang(code)?;
}
}

Expand Down
3 changes: 3 additions & 0 deletions docs/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ description = "Everything you need to make a static site engine in one binary."
compile_sass = true
build_search_index = true

[search]
index_format = "elasticlunr_json"

[markdown]
highlight_code = true
highlight_theme = "kronuz"
Expand Down
3 changes: 3 additions & 0 deletions docs/content/documentation/content/search.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ After `zola build` or `zola serve`, you should see two files in your public dire
- `search_index.${default_language}.js`: so `search_index.en.js` for a default setup
- `elasticlunr.min.js`

If you set `index_format = "elasticlunr_json"` in your `config.toml`, a `search_index.${default_language}.json` is generated
instead of the default `search_index.${default_language}.js`.

As each site will be different, Zola makes no assumptions about your search function and doesn't provide
the JavaScript/CSS code to do an actual search and display results. You can look at how this site
implements it to get an idea: [search.js](https://github.com/getzola/zola/tree/master/docs/static/search.js).
Expand Down
4 changes: 4 additions & 0 deletions docs/content/documentation/getting-started/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ include_content = true
# 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_javascript"

# Optional translation object for the default language
# Example:
# default_language = "fr"
Expand Down
21 changes: 17 additions & 4 deletions docs/static/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,24 @@ function initSearch() {
}
};
var currentTerm = "";
var index = elasticlunr.Index.load(window.searchIndex);
var index;

var initIndex = async function () {
if (index === undefined) {
index = fetch("/search_index.en.json")
.then(
async function(response) {
return await elasticlunr.Index.load(await response.json());
}
);
}
let res = await index;
return res;
}

$searchInput.addEventListener("keyup", debounce(function() {
$searchInput.addEventListener("keyup", debounce(async function() {
var term = $searchInput.value.trim();
if (term === currentTerm || !index) {
if (term === currentTerm) {
return;
}
$searchResults.style.display = term === "" ? "none" : "block";
Expand All @@ -156,7 +169,7 @@ function initSearch() {
return;
}

var results = index.search(term, options);
var results = (await initIndex()).search(term, options);
if (results.length === 0) {
$searchResults.style.display = "none";
return;
Expand Down
1 change: 0 additions & 1 deletion docs/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ <h2>Augmented Markdown</h2>
</footer>

<script type="text/javascript" src="{{ get_url(path="elasticlunr.min.js") }}"></script>
<script type="text/javascript" src="{{ get_url(path="search_index.en.js") }}"></script>
<script type="text/javascript" src="{{ get_url(path="search.js") }}"></script>
</body>
</html>

0 comments on commit 7000f78

Please sign in to comment.