diff --git a/components/config/src/config/search.rs b/components/config/src/config/search.rs
index aa36c46e..c96a8748 100644
--- a/components/config/src/config/search.rs
+++ b/components/config/src/config/search.rs
@@ -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 {
@@ -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 {
@@ -25,6 +40,7 @@ impl Default for Search {
include_description: false,
include_path: false,
truncate_content_length: None,
+ index_format: Default::default(),
}
}
}
diff --git a/components/config/src/lib.rs b/components/config/src/lib.rs
index 59c6568b..05d62161 100644
--- a/components/config/src/lib.rs
+++ b/components/config/src/lib.rs
@@ -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;
diff --git a/components/site/src/lib.rs b/components/site/src/lib.rs
index 834e4d7f..079bc656 100644
--- a/components/site/src/lib.rs
+++ b/components/site/src/lib.rs
@@ -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;
@@ -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)?;
}
}
diff --git a/docs/config.toml b/docs/config.toml
index 87a0215e..1a462a72 100644
--- a/docs/config.toml
+++ b/docs/config.toml
@@ -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"
diff --git a/docs/content/documentation/content/search.md b/docs/content/documentation/content/search.md
index d0f8779c..c57c1fc1 100644
--- a/docs/content/documentation/content/search.md
+++ b/docs/content/documentation/content/search.md
@@ -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).
diff --git a/docs/content/documentation/getting-started/configuration.md b/docs/content/documentation/getting-started/configuration.md
index 92675197..0748b5ca 100644
--- a/docs/content/documentation/getting-started/configuration.md
+++ b/docs/content/documentation/getting-started/configuration.md
@@ -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"
diff --git a/docs/static/search.js b/docs/static/search.js
index 40815655..553b1de3 100644
--- a/docs/static/search.js
+++ b/docs/static/search.js
@@ -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";
@@ -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;
diff --git a/docs/templates/index.html b/docs/templates/index.html
index 2efb0373..de9134f3 100644
--- a/docs/templates/index.html
+++ b/docs/templates/index.html
@@ -103,7 +103,6 @@
-